mirror of
https://git.suyu.dev/suyu/suyu.git
synced 2024-12-19 03:50:59 +01:00
am: rewrite ISelfController
This commit is contained in:
parent
79f225bd59
commit
9e271f2017
9 changed files with 479 additions and 542 deletions
|
@ -439,8 +439,6 @@ add_library(core STATIC
|
||||||
hle/service/am/omm.h
|
hle/service/am/omm.h
|
||||||
hle/service/am/process.cpp
|
hle/service/am/process.cpp
|
||||||
hle/service/am/process.h
|
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.cpp
|
||||||
hle/service/am/service/all_system_applet_proxies_service.h
|
hle/service/am/service/all_system_applet_proxies_service.h
|
||||||
hle/service/am/service/applet_common_functions.cpp
|
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/library_applet_self_accessor.h
|
||||||
hle/service/am/service/process_winding_controller.cpp
|
hle/service/am/service/process_winding_controller.cpp
|
||||||
hle/service/am/service/process_winding_controller.h
|
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.cpp
|
||||||
hle/service/am/service/system_applet_proxy.h
|
hle/service/am/service/system_applet_proxy.h
|
||||||
hle/service/am/system_buffer_manager.cpp
|
hle/service/am/system_buffer_manager.cpp
|
||||||
|
|
|
@ -67,10 +67,9 @@ enum class ScreenshotPermission : u32 {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FocusHandlingMode {
|
struct FocusHandlingMode {
|
||||||
bool unknown0;
|
bool notify;
|
||||||
bool unknown1;
|
bool background;
|
||||||
bool unknown2;
|
bool suspend;
|
||||||
bool unknown3;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
enum class IdleTimeDetectionExtension : u32 {
|
enum class IdleTimeDetectionExtension : u32 {
|
||||||
|
|
|
@ -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
|
|
|
@ -1,7 +1,6 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// 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/applet_common_functions.h"
|
||||||
#include "core/hle/service/am/service/application_functions.h"
|
#include "core/hle/service/am/service/application_functions.h"
|
||||||
#include "core/hle/service/am/service/application_proxy.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/display_controller.h"
|
||||||
#include "core/hle/service/am/service/library_applet_creator.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/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/am/window_controller.h"
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
|
||||||
|
@ -77,7 +77,8 @@ Result IApplicationProxy::GetWindowController(
|
||||||
Result IApplicationProxy::GetSelfController(
|
Result IApplicationProxy::GetSelfController(
|
||||||
Out<SharedPointer<ISelfController>> out_self_controller) {
|
Out<SharedPointer<ISelfController>> out_self_controller) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2024 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// 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/applet_common_functions.h"
|
||||||
#include "core/hle/service/am/service/audio_controller.h"
|
#include "core/hle/service/am/service/audio_controller.h"
|
||||||
#include "core/hle/service/am/service/common_state_getter.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_proxy.h"
|
||||||
#include "core/hle/service/am/service/library_applet_self_accessor.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/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/am/window_controller.h"
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
|
||||||
|
@ -83,7 +83,8 @@ Result ILibraryAppletProxy::GetWindowController(
|
||||||
Result ILibraryAppletProxy::GetSelfController(
|
Result ILibraryAppletProxy::GetSelfController(
|
||||||
Out<SharedPointer<ISelfController>> out_self_controller) {
|
Out<SharedPointer<ISelfController>> out_self_controller) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
393
src/core/hle/service/am/service/self_controller.cpp
Normal file
393
src/core/hle/service/am/service/self_controller.cpp
Normal file
|
@ -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
|
72
src/core/hle/service/am/service/self_controller.h
Normal file
72
src/core/hle/service/am/service/self_controller.h
Normal file
|
@ -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
|
|
@ -2,7 +2,6 @@
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#include "core/hle/service/am/application_creator.h"
|
#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/applet_common_functions.h"
|
||||||
#include "core/hle/service/am/service/audio_controller.h"
|
#include "core/hle/service/am/service/audio_controller.h"
|
||||||
#include "core/hle/service/am/service/common_state_getter.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/home_menu_functions.h"
|
||||||
#include "core/hle/service/am/service/library_applet_creator.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/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/service/system_applet_proxy.h"
|
||||||
#include "core/hle/service/am/window_controller.h"
|
#include "core/hle/service/am/window_controller.h"
|
||||||
#include "core/hle/service/cmif_serialization.h"
|
#include "core/hle/service/cmif_serialization.h"
|
||||||
|
@ -83,7 +83,8 @@ Result ISystemAppletProxy::GetWindowController(
|
||||||
Result ISystemAppletProxy::GetSelfController(
|
Result ISystemAppletProxy::GetSelfController(
|
||||||
Out<SharedPointer<ISelfController>> out_self_controller) {
|
Out<SharedPointer<ISelfController>> out_self_controller) {
|
||||||
LOG_DEBUG(Service_AM, "called");
|
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();
|
R_SUCCEED();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue