ICommonStateGetter.cs 7.1 KB

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