diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 935e3c57c..956207fcf 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -439,8 +439,6 @@ add_library(core STATIC
     hle/service/am/omm.h
     hle/service/am/process.cpp
     hle/service/am/process.h
-    hle/service/am/self_controller.cpp
-    hle/service/am/self_controller.h
     hle/service/am/service/all_system_applet_proxies_service.cpp
     hle/service/am/service/all_system_applet_proxies_service.h
     hle/service/am/service/applet_common_functions.cpp
@@ -475,6 +473,8 @@ add_library(core STATIC
     hle/service/am/service/library_applet_self_accessor.h
     hle/service/am/service/process_winding_controller.cpp
     hle/service/am/service/process_winding_controller.h
+    hle/service/am/service/self_controller.cpp
+    hle/service/am/service/self_controller.h
     hle/service/am/service/system_applet_proxy.cpp
     hle/service/am/service/system_applet_proxy.h
     hle/service/am/system_buffer_manager.cpp
diff --git a/src/core/hle/service/am/am_types.h b/src/core/hle/service/am/am_types.h
index 093adcdea..46afb3996 100644
--- a/src/core/hle/service/am/am_types.h
+++ b/src/core/hle/service/am/am_types.h
@@ -67,10 +67,9 @@ enum class ScreenshotPermission : u32 {
 };
 
 struct FocusHandlingMode {
-    bool unknown0;
-    bool unknown1;
-    bool unknown2;
-    bool unknown3;
+    bool notify;
+    bool background;
+    bool suspend;
 };
 
 enum class IdleTimeDetectionExtension : u32 {
diff --git a/src/core/hle/service/am/self_controller.cpp b/src/core/hle/service/am/self_controller.cpp
deleted file mode 100644
index 65e249c0c..000000000
--- a/src/core/hle/service/am/self_controller.cpp
+++ /dev/null
@@ -1,470 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#include "common/logging/log.h"
-#include "core/hle/result.h"
-#include "core/hle/service/am/am_results.h"
-#include "core/hle/service/am/frontend/applets.h"
-#include "core/hle/service/am/self_controller.h"
-#include "core/hle/service/caps/caps_su.h"
-#include "core/hle/service/hle_ipc.h"
-#include "core/hle/service/ipc_helpers.h"
-#include "core/hle/service/nvnflinger/fb_share_buffer_manager.h"
-#include "core/hle/service/nvnflinger/nvnflinger.h"
-#include "core/hle/service/sm/sm.h"
-#include "core/hle/service/vi/vi_results.h"
-
-namespace Service::AM {
-
-ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_,
-                                 Nvnflinger::Nvnflinger& nvnflinger_)
-    : ServiceFramework{system_, "ISelfController"}, nvnflinger{nvnflinger_}, applet{std::move(
-                                                                                 applet_)} {
-    // clang-format off
-    static const FunctionInfo functions[] = {
-        {0, &ISelfController::Exit, "Exit"},
-        {1, &ISelfController::LockExit, "LockExit"},
-        {2, &ISelfController::UnlockExit, "UnlockExit"},
-        {3, &ISelfController::EnterFatalSection, "EnterFatalSection"},
-        {4, &ISelfController::LeaveFatalSection, "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, &ISelfController::SetScreenShotAppletIdentityInfo, "SetScreenShotAppletIdentityInfo"},
-        {16, &ISelfController::SetOutOfFocusSuspendingEnabled, "SetOutOfFocusSuspendingEnabled"},
-        {17, nullptr, "SetControllerFirmwareUpdateSection"},
-        {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
-        {19, &ISelfController::SetAlbumImageOrientation, "SetAlbumImageOrientation"},
-        {20, nullptr, "SetDesirableKeyboardLayout"},
-        {21, nullptr, "GetScreenShotProgramId"},
-        {40, &ISelfController::CreateManagedDisplayLayer, "CreateManagedDisplayLayer"},
-        {41, &ISelfController::IsSystemBufferSharingEnabled, "IsSystemBufferSharingEnabled"},
-        {42, &ISelfController::GetSystemSharedLayerHandle, "GetSystemSharedLayerHandle"},
-        {43, &ISelfController::GetSystemSharedBufferHandle, "GetSystemSharedBufferHandle"},
-        {44, &ISelfController::CreateManagedDisplaySeparableLayer, "CreateManagedDisplaySeparableLayer"},
-        {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
-        {46, nullptr, "SetRecordingLayerCompositionEnabled"},
-        {50, &ISelfController::SetHandlesRequestToDisplay, "SetHandlesRequestToDisplay"},
-        {51, &ISelfController::ApproveToDisplay, "ApproveToDisplay"},
-        {60, nullptr, "OverrideAutoSleepTimeAndDimmingTime"},
-        {61, &ISelfController::SetMediaPlaybackState, "SetMediaPlaybackState"},
-        {62, &ISelfController::SetIdleTimeDetectionExtension, "SetIdleTimeDetectionExtension"},
-        {63, &ISelfController::GetIdleTimeDetectionExtension, "GetIdleTimeDetectionExtension"},
-        {64, nullptr, "SetInputDetectionSourceSet"},
-        {65, &ISelfController::ReportUserIsActive, "ReportUserIsActive"},
-        {66, nullptr, "GetCurrentIlluminance"},
-        {67, nullptr, "IsIlluminanceAvailable"},
-        {68, &ISelfController::SetAutoSleepDisabled, "SetAutoSleepDisabled"},
-        {69, &ISelfController::IsAutoSleepDisabled, "IsAutoSleepDisabled"},
-        {70, nullptr, "ReportMultimediaError"},
-        {71, nullptr, "GetCurrentIlluminanceEx"},
-        {72, nullptr, "SetInputDetectionPolicy"},
-        {80, nullptr, "SetWirelessPriorityMode"},
-        {90, &ISelfController::GetAccumulatedSuspendedTickValue, "GetAccumulatedSuspendedTickValue"},
-        {91, &ISelfController::GetAccumulatedSuspendedTickChangedEvent, "GetAccumulatedSuspendedTickChangedEvent"},
-        {100, &ISelfController::SetAlbumImageTakenNotificationEnabled, "SetAlbumImageTakenNotificationEnabled"},
-        {110, nullptr, "SetApplicationAlbumUserData"},
-        {120, &ISelfController::SaveCurrentScreenshot, "SaveCurrentScreenshot"},
-        {130, &ISelfController::SetRecordVolumeMuted, "SetRecordVolumeMuted"},
-        {1000, nullptr, "GetDebugStorageChannel"},
-    };
-    // clang-format on
-
-    RegisterHandlers(functions);
-}
-
-ISelfController::~ISelfController() = default;
-
-void ISelfController::Exit(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-
-    // TODO
-    system.Exit();
-}
-
-void ISelfController::LockExit(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    system.SetExitLocked(true);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::UnlockExit(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called");
-
-    system.SetExitLocked(false);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-
-    if (system.GetExitRequested()) {
-        system.Exit();
-    }
-}
-
-void ISelfController::EnterFatalSection(HLERequestContext& ctx) {
-
-    std::scoped_lock lk{applet->lock};
-    applet->fatal_section_count++;
-    LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", applet->fatal_section_count);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::LeaveFatalSection(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called.");
-
-    // Entry and exit of fatal sections must be balanced.
-    std::scoped_lock lk{applet->lock};
-    if (applet->fatal_section_count == 0) {
-        IPC::ResponseBuilder rb{ctx, 2};
-        rb.Push(AM::ResultFatalSectionCountImbalance);
-        return;
-    }
-
-    applet->fatal_section_count--;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::GetLibraryAppletLaunchableEvent(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    applet->library_applet_launchable_event.Signal();
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->library_applet_launchable_event.GetHandle());
-}
-
-void ISelfController::SetScreenShotPermission(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const auto permission = rp.PopEnum<ScreenshotPermission>();
-    LOG_DEBUG(Service_AM, "called, permission={}", permission);
-
-    std::scoped_lock lk{applet->lock};
-    applet->screenshot_permission = permission;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetOperationModeChangedNotification(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const bool notification_enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled);
-
-    std::scoped_lock lk{applet->lock};
-    applet->operation_mode_changed_notification_enabled = notification_enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetPerformanceModeChangedNotification(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const bool notification_enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called notification_enabled={}", notification_enabled);
-
-    std::scoped_lock lk{applet->lock};
-    applet->performance_mode_changed_notification_enabled = notification_enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetFocusHandlingMode(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto flags = rp.PopRaw<FocusHandlingMode>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called. unknown0={}, unknown1={}, unknown2={}",
-                flags.unknown0, flags.unknown1, flags.unknown2);
-
-    std::scoped_lock lk{applet->lock};
-    applet->focus_handling_mode = flags;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetRestartMessageEnabled(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-    applet->restart_message_enabled = true;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetScreenShotAppletIdentityInfo(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::RequestParser rp{ctx};
-    std::scoped_lock lk{applet->lock};
-    applet->screen_shot_identity = rp.PopRaw<AppletIdentityInfo>();
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const bool enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
-
-    std::scoped_lock lk{applet->lock};
-    ASSERT(applet->type == AppletType::Application);
-    applet->out_of_focus_suspension_enabled = enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetAlbumImageOrientation(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto orientation = rp.PopRaw<Capture::AlbumImageOrientation>();
-    LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", static_cast<s32>(orientation));
-
-    std::scoped_lock lk{applet->lock};
-    applet->album_image_orientation = orientation;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::CreateManagedDisplayLayer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 layer_id{};
-    applet->managed_layer_holder.Initialize(&nvnflinger);
-    applet->managed_layer_holder.CreateManagedDisplayLayer(&layer_id);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push(layer_id);
-}
-
-void ISelfController::IsSystemBufferSharingEnabled(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
-}
-
-void ISelfController::GetSystemSharedLayerHandle(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 buffer_id, layer_id;
-    applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id);
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
-    rb.Push<s64>(buffer_id);
-    rb.Push<s64>(layer_id);
-}
-
-void ISelfController::GetSystemSharedBufferHandle(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 buffer_id, layer_id;
-    applet->system_buffer_manager.GetSystemSharedLayerHandle(&buffer_id, &layer_id);
-
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(this->EnsureBufferSharingEnabled(ctx.GetThread().GetOwnerProcess()));
-    rb.Push<s64>(buffer_id);
-}
-
-Result ISelfController::EnsureBufferSharingEnabled(Kernel::KProcess* process) {
-    if (applet->system_buffer_manager.Initialize(&nvnflinger, process, applet->applet_id,
-                                                 applet->library_applet_mode)) {
-        return ResultSuccess;
-    }
-
-    return VI::ResultOperationFailed;
-}
-
-void ISelfController::CreateManagedDisplaySeparableLayer(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    u64 layer_id{};
-    u64 recording_layer_id{};
-    applet->managed_layer_holder.Initialize(&nvnflinger);
-    applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(&layer_id, &recording_layer_id);
-
-    IPC::ResponseBuilder rb{ctx, 6};
-    rb.Push(ResultSuccess);
-    rb.Push(layer_id);
-    rb.Push(recording_layer_id);
-}
-
-void ISelfController::SetHandlesRequestToDisplay(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::ApproveToDisplay(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetMediaPlaybackState(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-    const u8 state = rp.Pop<u8>();
-
-    LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetIdleTimeDetectionExtension(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto extension = rp.PopRaw<IdleTimeDetectionExtension>();
-    LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", extension);
-
-    std::scoped_lock lk{applet->lock};
-    applet->idle_time_detection_extension = extension;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::GetIdleTimeDetectionExtension(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    std::scoped_lock lk{applet->lock};
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.PushRaw<IdleTimeDetectionExtension>(applet->idle_time_detection_extension);
-}
-
-void ISelfController::ReportUserIsActive(HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetAutoSleepDisabled(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    std::scoped_lock lk{applet->lock};
-    applet->auto_sleep_disabled = rp.Pop<bool>();
-
-    // On the system itself, if the previous state of is_auto_sleep_disabled
-    // differed from the current value passed in, it'd signify the internal
-    // window manager to update (and also increment some statistics like update counts)
-    //
-    // It'd also indicate this change to an idle handling context.
-    //
-    // However, given we're emulating this behavior, most of this can be ignored
-    // and it's sufficient to simply set the member variable for querying via
-    // IsAutoSleepDisabled().
-
-    LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", applet->auto_sleep_disabled);
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::IsAutoSleepDisabled(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called.");
-
-    std::scoped_lock lk{applet->lock};
-
-    IPC::ResponseBuilder rb{ctx, 3};
-    rb.Push(ResultSuccess);
-    rb.Push(applet->auto_sleep_disabled);
-}
-
-void ISelfController::GetAccumulatedSuspendedTickValue(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called.");
-
-    std::scoped_lock lk{applet->lock};
-    // This command returns the total number of system ticks since ISelfController creation
-    // where the game was suspended. Since Yuzu doesn't implement game suspension, this command
-    // can just always return 0 ticks.
-    IPC::ResponseBuilder rb{ctx, 4};
-    rb.Push(ResultSuccess);
-    rb.Push<u64>(applet->suspended_ticks);
-}
-
-void ISelfController::GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx) {
-    LOG_DEBUG(Service_AM, "called.");
-
-    IPC::ResponseBuilder rb{ctx, 2, 1};
-    rb.Push(ResultSuccess);
-    rb.PushCopyObjects(applet->accumulated_suspended_tick_changed_event.GetHandle());
-}
-
-void ISelfController::SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    // This service call sets an internal flag whether a notification is shown when an image is
-    // captured. Currently we do not support capturing images via the capture button, so this can be
-    // stubbed for now.
-    const bool enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled);
-
-    std::scoped_lock lk{applet->lock};
-    applet->album_image_taken_notification_enabled = enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SaveCurrentScreenshot(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto report_option = rp.PopEnum<Capture::AlbumReportOption>();
-
-    LOG_INFO(Service_AM, "called, report_option={}", report_option);
-
-    const auto screenshot_service =
-        system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>(
-            "caps:su");
-
-    if (screenshot_service) {
-        screenshot_service->CaptureAndSaveScreenshot(report_option);
-    }
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-void ISelfController::SetRecordVolumeMuted(HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
-
-    const auto enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled);
-
-    std::scoped_lock lk{applet->lock};
-    applet->record_volume_muted = enabled;
-
-    IPC::ResponseBuilder rb{ctx, 2};
-    rb.Push(ResultSuccess);
-}
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/self_controller.h b/src/core/hle/service/am/self_controller.h
deleted file mode 100644
index ab21a1881..000000000
--- a/src/core/hle/service/am/self_controller.h
+++ /dev/null
@@ -1,60 +0,0 @@
-// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
-// SPDX-License-Identifier: GPL-2.0-or-later
-
-#pragma once
-
-#include "core/hle/service/hle_ipc.h"
-#include "core/hle/service/kernel_helpers.h"
-#include "core/hle/service/service.h"
-
-namespace Service::AM {
-
-struct Applet;
-
-class ISelfController final : public ServiceFramework<ISelfController> {
-public:
-    explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet_,
-                             Nvnflinger::Nvnflinger& nvnflinger_);
-    ~ISelfController() override;
-
-private:
-    void Exit(HLERequestContext& ctx);
-    void LockExit(HLERequestContext& ctx);
-    void UnlockExit(HLERequestContext& ctx);
-    void EnterFatalSection(HLERequestContext& ctx);
-    void LeaveFatalSection(HLERequestContext& ctx);
-    void GetLibraryAppletLaunchableEvent(HLERequestContext& ctx);
-    void SetScreenShotPermission(HLERequestContext& ctx);
-    void SetOperationModeChangedNotification(HLERequestContext& ctx);
-    void SetPerformanceModeChangedNotification(HLERequestContext& ctx);
-    void SetFocusHandlingMode(HLERequestContext& ctx);
-    void SetRestartMessageEnabled(HLERequestContext& ctx);
-    void SetScreenShotAppletIdentityInfo(HLERequestContext& ctx);
-    void SetOutOfFocusSuspendingEnabled(HLERequestContext& ctx);
-    void SetAlbumImageOrientation(HLERequestContext& ctx);
-    void IsSystemBufferSharingEnabled(HLERequestContext& ctx);
-    void GetSystemSharedBufferHandle(HLERequestContext& ctx);
-    void GetSystemSharedLayerHandle(HLERequestContext& ctx);
-    void CreateManagedDisplayLayer(HLERequestContext& ctx);
-    void CreateManagedDisplaySeparableLayer(HLERequestContext& ctx);
-    void SetHandlesRequestToDisplay(HLERequestContext& ctx);
-    void ApproveToDisplay(HLERequestContext& ctx);
-    void SetMediaPlaybackState(HLERequestContext& ctx);
-    void SetIdleTimeDetectionExtension(HLERequestContext& ctx);
-    void GetIdleTimeDetectionExtension(HLERequestContext& ctx);
-    void ReportUserIsActive(HLERequestContext& ctx);
-    void SetAutoSleepDisabled(HLERequestContext& ctx);
-    void IsAutoSleepDisabled(HLERequestContext& ctx);
-    void GetAccumulatedSuspendedTickValue(HLERequestContext& ctx);
-    void GetAccumulatedSuspendedTickChangedEvent(HLERequestContext& ctx);
-    void SetAlbumImageTakenNotificationEnabled(HLERequestContext& ctx);
-    void SaveCurrentScreenshot(HLERequestContext& ctx);
-    void SetRecordVolumeMuted(HLERequestContext& ctx);
-
-    Result EnsureBufferSharingEnabled(Kernel::KProcess* process);
-
-    Nvnflinger::Nvnflinger& nvnflinger;
-    const std::shared_ptr<Applet> applet;
-};
-
-} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/application_proxy.cpp b/src/core/hle/service/am/service/application_proxy.cpp
index 5f5a8f06c..9bba985be 100644
--- a/src/core/hle/service/am/service/application_proxy.cpp
+++ b/src/core/hle/service/am/service/application_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/application_functions.h"
 #include "core/hle/service/am/service/application_proxy.h"
@@ -11,6 +10,7 @@
 #include "core/hle/service/am/service/display_controller.h"
 #include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/process_winding_controller.h"
+#include "core/hle/service/am/service/self_controller.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
@@ -77,7 +77,8 @@ Result IApplicationProxy::GetWindowController(
 Result IApplicationProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    *out_self_controller =
+        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/am/service/library_applet_proxy.cpp b/src/core/hle/service/am/service/library_applet_proxy.cpp
index 91aa9f4db..bac3e0168 100644
--- a/src/core/hle/service/am/service/library_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/library_applet_proxy.cpp
@@ -1,7 +1,6 @@
 // SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
 // SPDX-License-Identifier: GPL-2.0-or-later
 
-#include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
@@ -13,6 +12,7 @@
 #include "core/hle/service/am/service/library_applet_proxy.h"
 #include "core/hle/service/am/service/library_applet_self_accessor.h"
 #include "core/hle/service/am/service/process_winding_controller.h"
+#include "core/hle/service/am/service/self_controller.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
 
@@ -83,7 +83,8 @@ Result ILibraryAppletProxy::GetWindowController(
 Result ILibraryAppletProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    *out_self_controller =
+        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
     R_SUCCEED();
 }
 
diff --git a/src/core/hle/service/am/service/self_controller.cpp b/src/core/hle/service/am/service/self_controller.cpp
new file mode 100644
index 000000000..5c4c13de1
--- /dev/null
+++ b/src/core/hle/service/am/service/self_controller.cpp
@@ -0,0 +1,393 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#include "common/logging/log.h"
+#include "core/hle/result.h"
+#include "core/hle/service/am/am_results.h"
+#include "core/hle/service/am/frontend/applets.h"
+#include "core/hle/service/am/service/self_controller.h"
+#include "core/hle/service/caps/caps_su.h"
+#include "core/hle/service/cmif_serialization.h"
+#include "core/hle/service/nvnflinger/nvnflinger.h"
+#include "core/hle/service/sm/sm.h"
+#include "core/hle/service/vi/vi_results.h"
+
+namespace Service::AM {
+
+ISelfController::ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
+                                 Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger)
+    : ServiceFramework{system_, "ISelfController"},
+      m_nvnflinger{nvnflinger}, m_process{process}, m_applet{std::move(applet)} {
+    // clang-format off
+    static const FunctionInfo functions[] = {
+        {0, D<&ISelfController::Exit>, "Exit"},
+        {1, D<&ISelfController::LockExit>, "LockExit"},
+        {2, D<&ISelfController::UnlockExit>, "UnlockExit"},
+        {3, D<&ISelfController::EnterFatalSection>, "EnterFatalSection"},
+        {4, D<&ISelfController::LeaveFatalSection>, "LeaveFatalSection"},
+        {9, D<&ISelfController::GetLibraryAppletLaunchableEvent>, "GetLibraryAppletLaunchableEvent"},
+        {10, D<&ISelfController::SetScreenShotPermission>, "SetScreenShotPermission"},
+        {11, D<&ISelfController::SetOperationModeChangedNotification>, "SetOperationModeChangedNotification"},
+        {12, D<&ISelfController::SetPerformanceModeChangedNotification>, "SetPerformanceModeChangedNotification"},
+        {13, D<&ISelfController::SetFocusHandlingMode>, "SetFocusHandlingMode"},
+        {14, D<&ISelfController::SetRestartMessageEnabled>, "SetRestartMessageEnabled"},
+        {15, D<&ISelfController::SetScreenShotAppletIdentityInfo>, "SetScreenShotAppletIdentityInfo"},
+        {16, D<&ISelfController::SetOutOfFocusSuspendingEnabled>, "SetOutOfFocusSuspendingEnabled"},
+        {17, nullptr, "SetControllerFirmwareUpdateSection"},
+        {18, nullptr, "SetRequiresCaptureButtonShortPressedMessage"},
+        {19, D<&ISelfController::SetAlbumImageOrientation>, "SetAlbumImageOrientation"},
+        {20, nullptr, "SetDesirableKeyboardLayout"},
+        {21, nullptr, "GetScreenShotProgramId"},
+        {40, D<&ISelfController::CreateManagedDisplayLayer>, "CreateManagedDisplayLayer"},
+        {41, D<&ISelfController::IsSystemBufferSharingEnabled>, "IsSystemBufferSharingEnabled"},
+        {42, D<&ISelfController::GetSystemSharedLayerHandle>, "GetSystemSharedLayerHandle"},
+        {43, D<&ISelfController::GetSystemSharedBufferHandle>, "GetSystemSharedBufferHandle"},
+        {44, D<&ISelfController::CreateManagedDisplaySeparableLayer>, "CreateManagedDisplaySeparableLayer"},
+        {45, nullptr, "SetManagedDisplayLayerSeparationMode"},
+        {46, nullptr, "SetRecordingLayerCompositionEnabled"},
+        {50, D<&ISelfController::SetHandlesRequestToDisplay>, "SetHandlesRequestToDisplay"},
+        {51, D<&ISelfController::ApproveToDisplay>, "ApproveToDisplay"},
+        {60, D<&ISelfController::OverrideAutoSleepTimeAndDimmingTime>, "OverrideAutoSleepTimeAndDimmingTime"},
+        {61, D<&ISelfController::SetMediaPlaybackState>, "SetMediaPlaybackState"},
+        {62, D<&ISelfController::SetIdleTimeDetectionExtension>, "SetIdleTimeDetectionExtension"},
+        {63, D<&ISelfController::GetIdleTimeDetectionExtension>, "GetIdleTimeDetectionExtension"},
+        {64, nullptr, "SetInputDetectionSourceSet"},
+        {65, D<&ISelfController::ReportUserIsActive>, "ReportUserIsActive"},
+        {66, nullptr, "GetCurrentIlluminance"},
+        {67, nullptr, "IsIlluminanceAvailable"},
+        {68, D<&ISelfController::SetAutoSleepDisabled>, "SetAutoSleepDisabled"},
+        {69, D<&ISelfController::IsAutoSleepDisabled>, "IsAutoSleepDisabled"},
+        {70, nullptr, "ReportMultimediaError"},
+        {71, nullptr, "GetCurrentIlluminanceEx"},
+        {72, D<&ISelfController::SetInputDetectionPolicy>, "SetInputDetectionPolicy"},
+        {80, nullptr, "SetWirelessPriorityMode"},
+        {90, D<&ISelfController::GetAccumulatedSuspendedTickValue>, "GetAccumulatedSuspendedTickValue"},
+        {91, D<&ISelfController::GetAccumulatedSuspendedTickChangedEvent>, "GetAccumulatedSuspendedTickChangedEvent"},
+        {100, D<&ISelfController::SetAlbumImageTakenNotificationEnabled>, "SetAlbumImageTakenNotificationEnabled"},
+        {110, nullptr, "SetApplicationAlbumUserData"},
+        {120, D<&ISelfController::SaveCurrentScreenshot>, "SaveCurrentScreenshot"},
+        {130, D<&ISelfController::SetRecordVolumeMuted>, "SetRecordVolumeMuted"},
+        {1000, nullptr, "GetDebugStorageChannel"},
+    };
+    // clang-format on
+
+    RegisterHandlers(functions);
+}
+
+ISelfController::~ISelfController() = default;
+
+Result ISelfController::Exit() {
+    LOG_DEBUG(Service_AM, "called");
+
+    // TODO
+    system.Exit();
+
+    R_SUCCEED();
+}
+
+Result ISelfController::LockExit() {
+    LOG_DEBUG(Service_AM, "called");
+
+    system.SetExitLocked(true);
+
+    R_SUCCEED();
+}
+
+Result ISelfController::UnlockExit() {
+    LOG_DEBUG(Service_AM, "called");
+
+    system.SetExitLocked(false);
+
+    if (system.GetExitRequested()) {
+        system.Exit();
+    }
+
+    R_SUCCEED();
+}
+
+Result ISelfController::EnterFatalSection() {
+    std::scoped_lock lk{m_applet->lock};
+
+    m_applet->fatal_section_count++;
+    LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", m_applet->fatal_section_count);
+
+    R_SUCCEED();
+}
+
+Result ISelfController::LeaveFatalSection() {
+    LOG_DEBUG(Service_AM, "called");
+
+    // Entry and exit of fatal sections must be balanced.
+    std::scoped_lock lk{m_applet->lock};
+    R_UNLESS(m_applet->fatal_section_count > 0, AM::ResultFatalSectionCountImbalance);
+    m_applet->fatal_section_count--;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::GetLibraryAppletLaunchableEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    m_applet->library_applet_launchable_event.Signal();
+    *out_event = m_applet->library_applet_launchable_event.GetHandle();
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetScreenShotPermission(ScreenshotPermission screen_shot_permission) {
+    LOG_DEBUG(Service_AM, "called, permission={}", screen_shot_permission);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->screenshot_permission = screen_shot_permission;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetOperationModeChangedNotification(bool enabled) {
+    LOG_INFO(Service_AM, "called, enabled={}", enabled);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->operation_mode_changed_notification_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetPerformanceModeChangedNotification(bool enabled) {
+    LOG_INFO(Service_AM, "called, enabled={}", enabled);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->performance_mode_changed_notification_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetFocusHandlingMode(bool notify, bool background, bool suspend) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, notify={} background={} suspend={}", notify,
+                background, suspend);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->focus_handling_mode = {notify, background, suspend};
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetRestartMessageEnabled(bool enabled) {
+    LOG_INFO(Service_AM, "called, enabled={}", enabled);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->restart_message_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetScreenShotAppletIdentityInfo(
+    AppletIdentityInfo screen_shot_applet_identity_info) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->screen_shot_identity = screen_shot_applet_identity_info;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetOutOfFocusSuspendingEnabled(bool enabled) {
+    LOG_INFO(Service_AM, "called, enabled={}", enabled);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->out_of_focus_suspension_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetAlbumImageOrientation(
+    Capture::AlbumImageOrientation album_image_orientation) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, orientation={}", album_image_orientation);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->album_image_orientation = album_image_orientation;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::IsSystemBufferSharingEnabled() {
+    LOG_INFO(Service_AM, "called");
+    R_SUCCEED_IF(m_applet->system_buffer_manager.Initialize(
+        &m_nvnflinger, m_process, m_applet->applet_id, m_applet->library_applet_mode));
+    R_THROW(VI::ResultOperationFailed);
+}
+
+Result ISelfController::GetSystemSharedBufferHandle(Out<u64> out_buffer_id) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    R_TRY(this->IsSystemBufferSharingEnabled());
+
+    u64 layer_id;
+    m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, &layer_id);
+    R_SUCCEED();
+}
+
+Result ISelfController::GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id) {
+    LOG_INFO(Service_AM, "(STUBBED) called");
+
+    R_TRY(this->IsSystemBufferSharingEnabled());
+
+    m_applet->system_buffer_manager.GetSystemSharedLayerHandle(out_buffer_id, out_layer_id);
+    R_SUCCEED();
+}
+
+Result ISelfController::CreateManagedDisplayLayer(Out<u64> out_layer_id) {
+    LOG_INFO(Service_AM, "called");
+
+    m_applet->managed_layer_holder.Initialize(&m_nvnflinger);
+    m_applet->managed_layer_holder.CreateManagedDisplayLayer(out_layer_id);
+
+    R_SUCCEED();
+}
+
+Result ISelfController::CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id,
+                                                           Out<u64> out_recording_layer_id) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    m_applet->managed_layer_holder.Initialize(&m_nvnflinger);
+    m_applet->managed_layer_holder.CreateManagedDisplaySeparableLayer(out_layer_id,
+                                                                      out_recording_layer_id);
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetHandlesRequestToDisplay(bool enable) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, enable={}", enable);
+    R_SUCCEED();
+}
+
+Result ISelfController::ApproveToDisplay() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ISelfController::SetMediaPlaybackState(bool state) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, state={}", state);
+    R_SUCCEED();
+}
+
+Result ISelfController::OverrideAutoSleepTimeAndDimmingTime(s32 a, s32 b, s32 c, s32 d) {
+    LOG_WARNING(Service_AM, "(STUBBED) called, a={}, b={}, c={}, d={}", a, b, c, d);
+    R_SUCCEED();
+}
+
+Result ISelfController::SetIdleTimeDetectionExtension(
+    IdleTimeDetectionExtension idle_time_detection_extension) {
+    LOG_DEBUG(Service_AM, "(STUBBED) called extension={}", idle_time_detection_extension);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->idle_time_detection_extension = idle_time_detection_extension;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::GetIdleTimeDetectionExtension(
+    Out<IdleTimeDetectionExtension> out_idle_time_detection_extension) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    std::scoped_lock lk{m_applet->lock};
+    *out_idle_time_detection_extension = m_applet->idle_time_detection_extension;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::ReportUserIsActive() {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ISelfController::SetAutoSleepDisabled(bool is_auto_sleep_disabled) {
+    LOG_DEBUG(Service_AM, "called. is_auto_sleep_disabled={}", is_auto_sleep_disabled);
+
+    // On the system itself, if the previous state of is_auto_sleep_disabled
+    // differed from the current value passed in, it'd signify the internal
+    // window manager to update (and also increment some statistics like update counts)
+    //
+    // It'd also indicate this change to an idle handling context.
+    //
+    // However, given we're emulating this behavior, most of this can be ignored
+    // and it's sufficient to simply set the member variable for querying via
+    // IsAutoSleepDisabled().
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->auto_sleep_disabled = is_auto_sleep_disabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::IsAutoSleepDisabled(Out<bool> out_is_auto_sleep_disabled) {
+    LOG_DEBUG(Service_AM, "called.");
+
+    std::scoped_lock lk{m_applet->lock};
+    *out_is_auto_sleep_disabled = m_applet->auto_sleep_disabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+    R_SUCCEED();
+}
+
+Result ISelfController::GetAccumulatedSuspendedTickValue(
+    Out<u64> out_accumulated_suspended_tick_value) {
+    LOG_DEBUG(Service_AM, "called.");
+
+    // This command returns the total number of system ticks since ISelfController creation
+    // where the game was suspended. Since Yuzu doesn't implement game suspension, this command
+    // can just always return 0 ticks.
+    std::scoped_lock lk{m_applet->lock};
+    *out_accumulated_suspended_tick_value = m_applet->suspended_ticks;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::GetAccumulatedSuspendedTickChangedEvent(
+    OutCopyHandle<Kernel::KReadableEvent> out_event) {
+    LOG_DEBUG(Service_AM, "called.");
+
+    *out_event = m_applet->accumulated_suspended_tick_changed_event.GetHandle();
+    R_SUCCEED();
+}
+
+Result ISelfController::SetAlbumImageTakenNotificationEnabled(bool enabled) {
+    LOG_WARNING(Service_AM, "(STUBBED) called. enabled={}", enabled);
+
+    // This service call sets an internal flag whether a notification is shown when an image is
+    // captured. Currently we do not support capturing images via the capture button, so this can be
+    // stubbed for now.
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->album_image_taken_notification_enabled = enabled;
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option) {
+    LOG_INFO(Service_AM, "called, report_option={}", album_report_option);
+
+    const auto screenshot_service =
+        system.ServiceManager().GetService<Service::Capture::IScreenShotApplicationService>(
+            "caps:su");
+
+    if (screenshot_service) {
+        screenshot_service->CaptureAndSaveScreenshot(album_report_option);
+    }
+
+    R_SUCCEED();
+}
+
+Result ISelfController::SetRecordVolumeMuted(bool muted) {
+    LOG_WARNING(Service_AM, "(STUBBED) called. muted={}", muted);
+
+    std::scoped_lock lk{m_applet->lock};
+    m_applet->record_volume_muted = muted;
+
+    R_SUCCEED();
+}
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/self_controller.h b/src/core/hle/service/am/service/self_controller.h
new file mode 100644
index 000000000..01fa381a3
--- /dev/null
+++ b/src/core/hle/service/am/service/self_controller.h
@@ -0,0 +1,72 @@
+// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+#pragma once
+
+#include "core/hle/service/am/am_types.h"
+#include "core/hle/service/cmif_types.h"
+#include "core/hle/service/service.h"
+
+namespace Kernel {
+class KReadableEvent;
+}
+
+namespace Service::Capture {
+enum class AlbumImageOrientation;
+enum class AlbumReportOption;
+} // namespace Service::Capture
+
+namespace Service::AM {
+
+struct Applet;
+
+class ISelfController final : public ServiceFramework<ISelfController> {
+public:
+    explicit ISelfController(Core::System& system_, std::shared_ptr<Applet> applet,
+                             Kernel::KProcess* process, Nvnflinger::Nvnflinger& nvnflinger);
+    ~ISelfController() override;
+
+private:
+    Result Exit();
+    Result LockExit();
+    Result UnlockExit();
+    Result EnterFatalSection();
+    Result LeaveFatalSection();
+    Result GetLibraryAppletLaunchableEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result SetScreenShotPermission(ScreenshotPermission screen_shot_permission);
+    Result SetOperationModeChangedNotification(bool enabled);
+    Result SetPerformanceModeChangedNotification(bool enabled);
+    Result SetFocusHandlingMode(bool notify, bool background, bool suspend);
+    Result SetRestartMessageEnabled(bool enabled);
+    Result SetScreenShotAppletIdentityInfo(AppletIdentityInfo screen_shot_applet_identity_info);
+    Result SetOutOfFocusSuspendingEnabled(bool enabled);
+    Result SetAlbumImageOrientation(Capture::AlbumImageOrientation album_image_orientation);
+    Result IsSystemBufferSharingEnabled();
+    Result GetSystemSharedBufferHandle(Out<u64> out_buffer_id);
+    Result GetSystemSharedLayerHandle(Out<u64> out_buffer_id, Out<u64> out_layer_id);
+    Result CreateManagedDisplayLayer(Out<u64> out_layer_id);
+    Result CreateManagedDisplaySeparableLayer(Out<u64> out_layer_id,
+                                              Out<u64> out_recording_layer_id);
+    Result SetHandlesRequestToDisplay(bool enable);
+    Result ApproveToDisplay();
+    Result SetMediaPlaybackState(bool state);
+    Result OverrideAutoSleepTimeAndDimmingTime(s32 a, s32 b, s32 c, s32 d);
+    Result SetIdleTimeDetectionExtension(IdleTimeDetectionExtension idle_time_detection_extension);
+    Result GetIdleTimeDetectionExtension(
+        Out<IdleTimeDetectionExtension> out_idle_time_detection_extension);
+    Result ReportUserIsActive();
+    Result SetAutoSleepDisabled(bool is_auto_sleep_disabled);
+    Result IsAutoSleepDisabled(Out<bool> out_is_auto_sleep_disabled);
+    Result SetInputDetectionPolicy(InputDetectionPolicy input_detection_policy);
+    Result GetAccumulatedSuspendedTickValue(Out<u64> out_accumulated_suspended_tick_value);
+    Result GetAccumulatedSuspendedTickChangedEvent(OutCopyHandle<Kernel::KReadableEvent> out_event);
+    Result SetAlbumImageTakenNotificationEnabled(bool enabled);
+    Result SaveCurrentScreenshot(Capture::AlbumReportOption album_report_option);
+    Result SetRecordVolumeMuted(bool muted);
+
+    Nvnflinger::Nvnflinger& m_nvnflinger;
+    Kernel::KProcess* const m_process;
+    const std::shared_ptr<Applet> m_applet;
+};
+
+} // namespace Service::AM
diff --git a/src/core/hle/service/am/service/system_applet_proxy.cpp b/src/core/hle/service/am/service/system_applet_proxy.cpp
index 0f6175d32..da6e8dadd 100644
--- a/src/core/hle/service/am/service/system_applet_proxy.cpp
+++ b/src/core/hle/service/am/service/system_applet_proxy.cpp
@@ -2,7 +2,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 
 #include "core/hle/service/am/application_creator.h"
-#include "core/hle/service/am/self_controller.h"
 #include "core/hle/service/am/service/applet_common_functions.h"
 #include "core/hle/service/am/service/audio_controller.h"
 #include "core/hle/service/am/service/common_state_getter.h"
@@ -12,6 +11,7 @@
 #include "core/hle/service/am/service/home_menu_functions.h"
 #include "core/hle/service/am/service/library_applet_creator.h"
 #include "core/hle/service/am/service/process_winding_controller.h"
+#include "core/hle/service/am/service/self_controller.h"
 #include "core/hle/service/am/service/system_applet_proxy.h"
 #include "core/hle/service/am/window_controller.h"
 #include "core/hle/service/cmif_serialization.h"
@@ -83,7 +83,8 @@ Result ISystemAppletProxy::GetWindowController(
 Result ISystemAppletProxy::GetSelfController(
     Out<SharedPointer<ISelfController>> out_self_controller) {
     LOG_DEBUG(Service_AM, "called");
-    *out_self_controller = std::make_shared<ISelfController>(system, m_applet, m_nvnflinger);
+    *out_self_controller =
+        std::make_shared<ISelfController>(system, m_applet, m_process, m_nvnflinger);
     R_SUCCEED();
 }