ソースを参照

Merge pull request #2294 from lioncash/fatal

service/am: Implement EnterFatalSection/LeaveFatalSection
bunnei 7 年 前
コミット
a6d5ff05dc
2 ファイル変更63 行追加36 行削除
  1. 54 30
      src/core/hle/service/am/am.cpp
  2. 9 6
      src/core/hle/service/am/am.h

+ 54 - 30
src/core/hle/service/am/am.cpp

@@ -239,8 +239,8 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
         {0, nullptr, "Exit"},
         {1, &ISelfController::LockExit, "LockExit"},
         {2, &ISelfController::UnlockExit, "UnlockExit"},
-        {3, nullptr, "EnterFatalSection"},
-        {4, nullptr, "LeaveFatalSection"},
+        {3, &ISelfController::EnterFatalSection, "EnterFatalSection"},
+        {4, &ISelfController::LeaveFatalSection, "LeaveFatalSection"},
         {9, &ISelfController::GetLibraryAppletLaunchableEvent, "GetLibraryAppletLaunchableEvent"},
         {10, &ISelfController::SetScreenShotPermission, "SetScreenShotPermission"},
         {11, &ISelfController::SetOperationModeChangedNotification, "SetOperationModeChangedNotification"},
@@ -285,41 +285,54 @@ ISelfController::ISelfController(std::shared_ptr<NVFlinger::NVFlinger> nvflinger
 
 ISelfController::~ISelfController() = default;
 
-void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
-    // Takes 3 input u8s with each field located immediately after the previous
-    // u8, these are bool flags. No output.
+void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
-    IPC::RequestParser rp{ctx};
+    IPC::ResponseBuilder rb{ctx, 2};
+    rb.Push(RESULT_SUCCESS);
+}
 
-    struct FocusHandlingModeParams {
-        u8 unknown0;
-        u8 unknown1;
-        u8 unknown2;
-    };
-    auto flags = rp.PopRaw<FocusHandlingModeParams>();
+void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(RESULT_SUCCESS);
 }
 
-void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
+void ISelfController::EnterFatalSection(Kernel::HLERequestContext& ctx) {
+    ++num_fatal_sections_entered;
+    LOG_DEBUG(Service_AM, "called. Num fatal sections entered: {}", num_fatal_sections_entered);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(RESULT_SUCCESS);
 }
 
-void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
-    IPC::RequestParser rp{ctx};
+void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
+    LOG_DEBUG(Service_AM, "called.");
 
-    bool flag = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
+    // Entry and exit of fatal sections must be balanced.
+    if (num_fatal_sections_entered == 0) {
+        IPC::ResponseBuilder rb{ctx, 2};
+        rb.Push(ResultCode{ErrorModule::AM, 512});
+        return;
+    }
+
+    --num_fatal_sections_entered;
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(RESULT_SUCCESS);
 }
 
+void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
+    LOG_WARNING(Service_AM, "(STUBBED) called");
+
+    launchable_event.writable->Signal();
+
+    IPC::ResponseBuilder rb{ctx, 2, 1};
+    rb.Push(RESULT_SUCCESS);
+    rb.PushCopyObjects(launchable_event.readable);
+}
+
 void ISelfController::SetScreenShotPermission(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
@@ -337,40 +350,51 @@ void ISelfController::SetOperationModeChangedNotification(Kernel::HLERequestCont
     rb.Push(RESULT_SUCCESS);
 }
 
-void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
-    // Takes 3 input u8s with each field located immediately after the previous
-    // u8, these are bool flags. No output.
+void ISelfController::SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
     IPC::RequestParser rp{ctx};
 
-    bool enabled = rp.Pop<bool>();
-    LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
+    bool flag = rp.Pop<bool>();
+    LOG_WARNING(Service_AM, "(STUBBED) called flag={}", flag);
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(RESULT_SUCCESS);
 }
 
-void ISelfController::LockExit(Kernel::HLERequestContext& ctx) {
+void ISelfController::SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
+    // Takes 3 input u8s with each field located immediately after the previous
+    // u8, these are bool flags. No output.
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
+    IPC::RequestParser rp{ctx};
+
+    struct FocusHandlingModeParams {
+        u8 unknown0;
+        u8 unknown1;
+        u8 unknown2;
+    };
+    auto flags = rp.PopRaw<FocusHandlingModeParams>();
+
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(RESULT_SUCCESS);
 }
 
-void ISelfController::UnlockExit(Kernel::HLERequestContext& ctx) {
+void ISelfController::SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
     LOG_WARNING(Service_AM, "(STUBBED) called");
 
     IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(RESULT_SUCCESS);
 }
 
-void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
-    LOG_WARNING(Service_AM, "(STUBBED) called");
+void ISelfController::SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
+    // Takes 3 input u8s with each field located immediately after the previous
+    // u8, these are bool flags. No output.
+    IPC::RequestParser rp{ctx};
 
-    launchable_event.writable->Signal();
+    bool enabled = rp.Pop<bool>();
+    LOG_WARNING(Service_AM, "(STUBBED) called enabled={}", enabled);
 
-    IPC::ResponseBuilder rb{ctx, 2, 1};
+    IPC::ResponseBuilder rb{ctx, 2};
     rb.Push(RESULT_SUCCESS);
-    rb.PushCopyObjects(launchable_event.readable);
 }
 
 void ISelfController::SetScreenShotImageOrientation(Kernel::HLERequestContext& ctx) {

+ 9 - 6
src/core/hle/service/am/am.h

@@ -117,17 +117,19 @@ public:
     ~ISelfController() override;
 
 private:
-    void SetFocusHandlingMode(Kernel::HLERequestContext& ctx);
-    void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx);
-    void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx);
-    void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx);
-    void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx);
     void LockExit(Kernel::HLERequestContext& ctx);
     void UnlockExit(Kernel::HLERequestContext& ctx);
+    void EnterFatalSection(Kernel::HLERequestContext& ctx);
+    void LeaveFatalSection(Kernel::HLERequestContext& ctx);
     void GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx);
+    void SetScreenShotPermission(Kernel::HLERequestContext& ctx);
+    void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx);
+    void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx);
+    void SetFocusHandlingMode(Kernel::HLERequestContext& ctx);
+    void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx);
+    void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx);
     void SetScreenShotImageOrientation(Kernel::HLERequestContext& ctx);
     void CreateManagedDisplayLayer(Kernel::HLERequestContext& ctx);
-    void SetScreenShotPermission(Kernel::HLERequestContext& ctx);
     void SetHandlesRequestToDisplay(Kernel::HLERequestContext& ctx);
     void SetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
     void GetIdleTimeDetectionExtension(Kernel::HLERequestContext& ctx);
@@ -135,6 +137,7 @@ private:
     std::shared_ptr<NVFlinger::NVFlinger> nvflinger;
     Kernel::EventPair launchable_event;
     u32 idle_time_detection_extension = 0;
+    u64 num_fatal_sections_entered = 0;
 };
 
 class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {