ICommonStateGetter.cs 7.7 KB

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