ICommonStateGetter.cs 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  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 ICommonStateGetter : IpcService
  9. {
  10. private Apm.ManagerServer _apmManagerServer;
  11. private Apm.SystemManagerServer _apmSystemManagerServer;
  12. private Lbl.LblControllerServer _lblControllerServer;
  13. private bool _vrModeEnabled;
  14. #pragma warning disable CS0169
  15. private bool _lcdBacklighOffEnabled;
  16. private bool _requestExitToLibraryAppletAtExecuteNextProgramEnabled;
  17. #pragma warning restore CS0169
  18. private int _messageEventHandle;
  19. private int _displayResolutionChangedEventHandle;
  20. public ICommonStateGetter(ServiceCtx context)
  21. {
  22. _apmManagerServer = new Apm.ManagerServer(context);
  23. _apmSystemManagerServer = new Apm.SystemManagerServer(context);
  24. _lblControllerServer = new Lbl.LblControllerServer(context);
  25. }
  26. [Command(0)]
  27. // GetEventHandle() -> handle<copy>
  28. public ResultCode GetEventHandle(ServiceCtx context)
  29. {
  30. KEvent messageEvent = context.Device.System.AppletState.MessageEvent;
  31. if (_messageEventHandle == 0)
  32. {
  33. if (context.Process.HandleTable.GenerateHandle(messageEvent.ReadableEvent, out _messageEventHandle) != KernelResult.Success)
  34. {
  35. throw new InvalidOperationException("Out of handles!");
  36. }
  37. }
  38. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_messageEventHandle);
  39. return ResultCode.Success;
  40. }
  41. [Command(1)]
  42. // ReceiveMessage() -> nn::am::AppletMessage
  43. public ResultCode ReceiveMessage(ServiceCtx context)
  44. {
  45. if (!context.Device.System.AppletState.Messages.TryDequeue(out MessageInfo message))
  46. {
  47. return ResultCode.NoMessages;
  48. }
  49. KEvent messageEvent = context.Device.System.AppletState.MessageEvent;
  50. // NOTE: Service checks if current states are different than the stored ones.
  51. // Since we don't support any states for now, it's fine to check if there is still messages available.
  52. if (context.Device.System.AppletState.Messages.IsEmpty)
  53. {
  54. messageEvent.ReadableEvent.Clear();
  55. }
  56. else
  57. {
  58. messageEvent.ReadableEvent.Signal();
  59. }
  60. context.ResponseData.Write((int)message);
  61. return ResultCode.Success;
  62. }
  63. [Command(5)]
  64. // GetOperationMode() -> u8
  65. public ResultCode GetOperationMode(ServiceCtx context)
  66. {
  67. OperationMode mode = context.Device.System.State.DockedMode
  68. ? OperationMode.Docked
  69. : OperationMode.Handheld;
  70. context.ResponseData.Write((byte)mode);
  71. return ResultCode.Success;
  72. }
  73. [Command(6)]
  74. // GetPerformanceMode() -> nn::apm::PerformanceMode
  75. public ResultCode GetPerformanceMode(ServiceCtx context)
  76. {
  77. return (ResultCode)_apmManagerServer.GetPerformanceMode(context);
  78. }
  79. [Command(8)]
  80. // GetBootMode() -> u8
  81. public ResultCode GetBootMode(ServiceCtx context)
  82. {
  83. context.ResponseData.Write((byte)0); //Unknown value.
  84. Logger.Stub?.PrintStub(LogClass.ServiceAm);
  85. return ResultCode.Success;
  86. }
  87. [Command(9)]
  88. // GetCurrentFocusState() -> u8
  89. public ResultCode GetCurrentFocusState(ServiceCtx context)
  90. {
  91. context.ResponseData.Write((byte)context.Device.System.AppletState.FocusState);
  92. return ResultCode.Success;
  93. }
  94. [Command(50)] // 3.0.0+
  95. // IsVrModeEnabled() -> b8
  96. public ResultCode IsVrModeEnabled(ServiceCtx context)
  97. {
  98. context.ResponseData.Write(_vrModeEnabled);
  99. return ResultCode.Success;
  100. }
  101. [Command(51)] // 3.0.0+
  102. // SetVrModeEnabled(b8)
  103. public ResultCode SetVrModeEnabled(ServiceCtx context)
  104. {
  105. bool vrModeEnabled = context.RequestData.ReadBoolean();
  106. UpdateVrMode(vrModeEnabled);
  107. return ResultCode.Success;
  108. }
  109. [Command(52)] // 4.0.0+
  110. // SetLcdBacklighOffEnabled(b8)
  111. public ResultCode SetLcdBacklighOffEnabled(ServiceCtx context)
  112. {
  113. // NOTE: Service sets a private field here, maybe this field is used somewhere else to turned off the backlight.
  114. // Since we don't support backlight, it's fine to do nothing.
  115. _lcdBacklighOffEnabled = context.RequestData.ReadBoolean();
  116. Logger.Stub?.PrintStub(LogClass.ServiceAm);
  117. return ResultCode.Success;
  118. }
  119. [Command(53)] // 7.0.0+
  120. // BeginVrModeEx()
  121. public ResultCode BeginVrModeEx(ServiceCtx context)
  122. {
  123. UpdateVrMode(true);
  124. return ResultCode.Success;
  125. }
  126. [Command(54)] // 7.0.0+
  127. // EndVrModeEx()
  128. public ResultCode EndVrModeEx(ServiceCtx context)
  129. {
  130. UpdateVrMode(false);
  131. return ResultCode.Success;
  132. }
  133. private void UpdateVrMode(bool vrModeEnabled)
  134. {
  135. if (_vrModeEnabled == vrModeEnabled)
  136. {
  137. return;
  138. }
  139. _vrModeEnabled = vrModeEnabled;
  140. if (vrModeEnabled)
  141. {
  142. _lblControllerServer.EnableVrMode();
  143. }
  144. else
  145. {
  146. _lblControllerServer.DisableVrMode();
  147. }
  148. // TODO: It signals an internal event of ICommonStateGetter. We have to determine where this event is used.
  149. }
  150. [Command(60)] // 3.0.0+
  151. // GetDefaultDisplayResolution() -> (u32, u32)
  152. public ResultCode GetDefaultDisplayResolution(ServiceCtx context)
  153. {
  154. context.ResponseData.Write(1280);
  155. context.ResponseData.Write(720);
  156. return ResultCode.Success;
  157. }
  158. [Command(61)] // 3.0.0+
  159. // GetDefaultDisplayResolutionChangeEvent() -> handle<copy>
  160. public ResultCode GetDefaultDisplayResolutionChangeEvent(ServiceCtx context)
  161. {
  162. if (_displayResolutionChangedEventHandle == 0)
  163. {
  164. if (context.Process.HandleTable.GenerateHandle(context.Device.System.DisplayResolutionChangeEvent.ReadableEvent, out _displayResolutionChangedEventHandle) != KernelResult.Success)
  165. {
  166. throw new InvalidOperationException("Out of handles!");
  167. }
  168. }
  169. context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_displayResolutionChangedEventHandle);
  170. Logger.Stub?.PrintStub(LogClass.ServiceAm);
  171. return ResultCode.Success;
  172. }
  173. [Command(66)] // 6.0.0+
  174. // SetCpuBoostMode(u32 cpu_boost_mode)
  175. public ResultCode SetCpuBoostMode(ServiceCtx context)
  176. {
  177. uint cpuBoostMode = context.RequestData.ReadUInt32();
  178. if (cpuBoostMode > 1)
  179. {
  180. return ResultCode.InvalidParameters;
  181. }
  182. _apmSystemManagerServer.SetCpuBoostMode((Apm.CpuBoostMode)cpuBoostMode);
  183. // TODO: It signals an internal event of ICommonStateGetter. We have to determine where this event is used.
  184. return ResultCode.Success;
  185. }
  186. [Command(91)] // 7.0.0+
  187. // GetCurrentPerformanceConfiguration() -> nn::apm::PerformanceConfiguration
  188. public ResultCode GetCurrentPerformanceConfiguration(ServiceCtx context)
  189. {
  190. return (ResultCode)_apmSystemManagerServer.GetCurrentPerformanceConfiguration(context);
  191. }
  192. [Command(900)] // 11.0.0+
  193. // SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled()
  194. public ResultCode SetRequestExitToLibraryAppletAtExecuteNextProgramEnabled(ServiceCtx context)
  195. {
  196. // TODO : Find where the field is used.
  197. _requestExitToLibraryAppletAtExecuteNextProgramEnabled = true;
  198. return ResultCode.Success;
  199. }
  200. }
  201. }