ISelfController.cs 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.HLE.HOS.Ipc;
  3. using Ryujinx.HLE.HOS.Kernel.Common;
  4. using Ryujinx.HLE.HOS.Kernel.Threading;
  5. using System;
  6. namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.SystemAppletProxy
  7. {
  8. class ISelfController : IpcService
  9. {
  10. private KEvent _libraryAppletLaunchableEvent;
  11. private KEvent _accumulatedSuspendedTickChangedEvent;
  12. private int _accumulatedSuspendedTickChangedEventHandle = 0;
  13. private object _fatalSectionLock = new object();
  14. private int _fatalSectionCount;
  15. // TODO: Set this when the game goes in suspension (go back to home menu ect), we currently don't support that so we can keep it set to 0.
  16. private ulong _accumulatedSuspendedTickValue = 0;
  17. private int _idleTimeDetectionExtension;
  18. public ISelfController(Horizon system)
  19. {
  20. _libraryAppletLaunchableEvent = new KEvent(system);
  21. }
  22. [Command(0)]
  23. // Exit()
  24. public ResultCode Exit(ServiceCtx context)
  25. {
  26. Logger.PrintStub(LogClass.ServiceAm);
  27. return ResultCode.Success;
  28. }
  29. [Command(1)]
  30. // LockExit()
  31. public ResultCode LockExit(ServiceCtx context)
  32. {
  33. Logger.PrintStub(LogClass.ServiceAm);
  34. return ResultCode.Success;
  35. }
  36. [Command(2)]
  37. // UnlockExit()
  38. public ResultCode UnlockExit(ServiceCtx context)
  39. {
  40. Logger.PrintStub(LogClass.ServiceAm);
  41. return ResultCode.Success;
  42. }
  43. [Command(3)] // 2.0.0+
  44. // EnterFatalSection()
  45. public ResultCode EnterFatalSection(ServiceCtx context)
  46. {
  47. lock (_fatalSectionLock)
  48. {
  49. _fatalSectionCount++;
  50. }
  51. return ResultCode.Success;
  52. }
  53. [Command(4)] // 2.0.0+
  54. // LeaveFatalSection()
  55. public ResultCode LeaveFatalSection(ServiceCtx context)
  56. {
  57. ResultCode result = ResultCode.Success;
  58. lock (_fatalSectionLock)
  59. {
  60. if (_fatalSectionCount != 0)
  61. {
  62. _fatalSectionCount--;
  63. }
  64. else
  65. {
  66. result = ResultCode.UnbalancedFatalSection;
  67. }
  68. }
  69. return result;
  70. }
  71. [Command(9)]
  72. // GetLibraryAppletLaunchableEvent() -> handle<copy>
  73. public ResultCode GetLibraryAppletLaunchableEvent(ServiceCtx context)
  74. {
  75. _libraryAppletLaunchableEvent.ReadableEvent.Signal();
  76. if (context.Process.HandleTable.GenerateHandle(_libraryAppletLaunchableEvent.ReadableEvent, out int handle) != KernelResult.Success)
  77. {
  78. throw new InvalidOperationException("Out of handles!");
  79. }
  80. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(handle);
  81. Logger.PrintStub(LogClass.ServiceAm);
  82. return ResultCode.Success;
  83. }
  84. [Command(10)]
  85. // SetScreenShotPermission(u32)
  86. public ResultCode SetScreenShotPermission(ServiceCtx context)
  87. {
  88. bool enable = context.RequestData.ReadByte() != 0;
  89. Logger.PrintStub(LogClass.ServiceAm);
  90. return ResultCode.Success;
  91. }
  92. [Command(11)]
  93. // SetOperationModeChangedNotification(b8)
  94. public ResultCode SetOperationModeChangedNotification(ServiceCtx context)
  95. {
  96. bool enable = context.RequestData.ReadByte() != 0;
  97. Logger.PrintStub(LogClass.ServiceAm);
  98. return ResultCode.Success;
  99. }
  100. [Command(12)]
  101. // SetPerformanceModeChangedNotification(b8)
  102. public ResultCode SetPerformanceModeChangedNotification(ServiceCtx context)
  103. {
  104. bool enable = context.RequestData.ReadByte() != 0;
  105. Logger.PrintStub(LogClass.ServiceAm);
  106. return ResultCode.Success;
  107. }
  108. [Command(13)]
  109. // SetFocusHandlingMode(b8, b8, b8)
  110. public ResultCode SetFocusHandlingMode(ServiceCtx context)
  111. {
  112. bool flag1 = context.RequestData.ReadByte() != 0;
  113. bool flag2 = context.RequestData.ReadByte() != 0;
  114. bool flag3 = context.RequestData.ReadByte() != 0;
  115. Logger.PrintStub(LogClass.ServiceAm);
  116. return ResultCode.Success;
  117. }
  118. [Command(14)]
  119. // SetRestartMessageEnabled(b8)
  120. public ResultCode SetRestartMessageEnabled(ServiceCtx context)
  121. {
  122. bool enable = context.RequestData.ReadByte() != 0;
  123. Logger.PrintStub(LogClass.ServiceAm);
  124. return ResultCode.Success;
  125. }
  126. [Command(16)] // 2.0.0+
  127. // SetOutOfFocusSuspendingEnabled(b8)
  128. public ResultCode SetOutOfFocusSuspendingEnabled(ServiceCtx context)
  129. {
  130. bool enable = context.RequestData.ReadByte() != 0;
  131. Logger.PrintStub(LogClass.ServiceAm);
  132. return ResultCode.Success;
  133. }
  134. [Command(19)] // 3.0.0+
  135. public ResultCode SetScreenShotImageOrientation(ServiceCtx context)
  136. {
  137. int orientation = context.RequestData.ReadInt32();
  138. Logger.PrintStub(LogClass.ServiceAm);
  139. return ResultCode.Success;
  140. }
  141. [Command(50)]
  142. // SetHandlesRequestToDisplay(b8)
  143. public ResultCode SetHandlesRequestToDisplay(ServiceCtx context)
  144. {
  145. bool enable = context.RequestData.ReadByte() != 0;
  146. Logger.PrintStub(LogClass.ServiceAm);
  147. return ResultCode.Success;
  148. }
  149. [Command(62)]
  150. // SetIdleTimeDetectionExtension(u32)
  151. public ResultCode SetIdleTimeDetectionExtension(ServiceCtx context)
  152. {
  153. _idleTimeDetectionExtension = context.RequestData.ReadInt32();
  154. Logger.PrintStub(LogClass.ServiceAm, new { _idleTimeDetectionExtension });
  155. return ResultCode.Success;
  156. }
  157. [Command(63)]
  158. // GetIdleTimeDetectionExtension() -> u32
  159. public ResultCode GetIdleTimeDetectionExtension(ServiceCtx context)
  160. {
  161. context.ResponseData.Write(_idleTimeDetectionExtension);
  162. Logger.PrintStub(LogClass.ServiceAm, new { _idleTimeDetectionExtension });
  163. return ResultCode.Success;
  164. }
  165. [Command(90)] // 6.0.0+
  166. // GetAccumulatedSuspendedTickValue() -> u64
  167. public ResultCode GetAccumulatedSuspendedTickValue(ServiceCtx context)
  168. {
  169. context.ResponseData.Write(_accumulatedSuspendedTickValue);
  170. return ResultCode.Success;
  171. }
  172. [Command(91)] // 6.0.0+
  173. // GetAccumulatedSuspendedTickChangedEvent() -> handle<copy>
  174. public ResultCode GetAccumulatedSuspendedTickChangedEvent(ServiceCtx context)
  175. {
  176. if (_accumulatedSuspendedTickChangedEventHandle == 0)
  177. {
  178. _accumulatedSuspendedTickChangedEvent = new KEvent(context.Device.System);
  179. _accumulatedSuspendedTickChangedEvent.ReadableEvent.Signal();
  180. if (context.Process.HandleTable.GenerateHandle(_accumulatedSuspendedTickChangedEvent.ReadableEvent, out _accumulatedSuspendedTickChangedEventHandle) != KernelResult.Success)
  181. {
  182. throw new InvalidOperationException("Out of handles!");
  183. }
  184. }
  185. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_accumulatedSuspendedTickChangedEventHandle);
  186. return ResultCode.Success;
  187. }
  188. }
  189. }