9 changed files with 479 additions and 542 deletions
-
4src/core/CMakeLists.txt
-
7src/core/hle/service/am/am_types.h
-
470src/core/hle/service/am/self_controller.cpp
-
60src/core/hle/service/am/self_controller.h
-
5src/core/hle/service/am/service/application_proxy.cpp
-
5src/core/hle/service/am/service/library_applet_proxy.cpp
-
393src/core/hle/service/am/service/self_controller.cpp
-
72src/core/hle/service/am/service/self_controller.h
-
5src/core/hle/service/am/service/system_applet_proxy.cpp
@ -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
|
|||
@ -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 |
|||
@ -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
|
|||
@ -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 |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue