ICommonStateGetter.cs 8.9 KB

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