IParentalControlService.cs 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. using Ryujinx.Common.Logging;
  2. using Ryujinx.HLE.HOS.Services.Arp;
  3. using System;
  4. namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
  5. {
  6. class IParentalControlService : IpcService
  7. {
  8. private int _permissionFlag;
  9. private ulong _titleId;
  10. private bool _freeCommunicationEnabled;
  11. private int[] _ratingAge;
  12. // TODO: Find where they are set.
  13. private bool _restrictionEnabled = false;
  14. private bool _featuresRestriction = false;
  15. private bool _stereoVisionRestrictionConfigurable = true;
  16. private bool _stereoVisionRestriction = false;
  17. public IParentalControlService(ServiceCtx context, bool withInitialize, int permissionFlag)
  18. {
  19. _permissionFlag = permissionFlag;
  20. if (withInitialize)
  21. {
  22. Initialize(context);
  23. }
  24. }
  25. [Command(1)] // 4.0.0+
  26. // Initialize()
  27. public ResultCode Initialize(ServiceCtx context)
  28. {
  29. if ((_permissionFlag & 0x8001) == 0)
  30. {
  31. return ResultCode.PermissionDenied;
  32. }
  33. ResultCode resultCode = ResultCode.InvalidPid;
  34. if (context.Process.Pid != 0)
  35. {
  36. if ((_permissionFlag & 0x40) == 0)
  37. {
  38. ulong titleId = ApplicationLaunchProperty.GetByPid(context).TitleId;
  39. if (titleId != 0)
  40. {
  41. _titleId = titleId;
  42. // TODO: Call nn::arp::GetApplicationControlProperty here when implemented, if it return ResultCode.Success we assign fields.
  43. _ratingAge = Array.ConvertAll(context.Device.Application.ControlData.Value.RatingAge.ToArray(), Convert.ToInt32);
  44. _freeCommunicationEnabled = context.Device.Application.ControlData.Value.ParentalControl == LibHac.Ns.ParentalControlFlagValue.FreeCommunication;
  45. }
  46. }
  47. if (_titleId != 0)
  48. {
  49. // TODO: Service store some private fields in another static object.
  50. if ((_permissionFlag & 0x8040) == 0)
  51. {
  52. // TODO: Service store TitleId and FreeCommunicationEnabled in another static object.
  53. // When it's done it signal an event in this static object.
  54. Logger.Stub?.PrintStub(LogClass.ServicePctl);
  55. }
  56. }
  57. resultCode = ResultCode.Success;
  58. }
  59. return resultCode;
  60. }
  61. [Command(1001)]
  62. // CheckFreeCommunicationPermission()
  63. public ResultCode CheckFreeCommunicationPermission(ServiceCtx context)
  64. {
  65. // TODO: This checks some extra internal fields which are to be determined.
  66. if (!_freeCommunicationEnabled && _restrictionEnabled)
  67. {
  68. return ResultCode.FreeCommunicationDisabled;
  69. }
  70. Logger.Stub?.PrintStub(LogClass.ServicePctl);
  71. return ResultCode.Success;
  72. }
  73. [Command(1013)] // 4.0.0+
  74. // ConfirmStereoVisionPermission()
  75. public ResultCode ConfirmStereoVisionPermission(ServiceCtx context)
  76. {
  77. return IsStereoVisionPermittedImpl();
  78. }
  79. [Command(1031)]
  80. // IsRestrictionEnabled() -> b8
  81. public ResultCode IsRestrictionEnabled(ServiceCtx context)
  82. {
  83. if ((_permissionFlag & 0x140) == 0)
  84. {
  85. return ResultCode.PermissionDenied;
  86. }
  87. context.ResponseData.Write(_restrictionEnabled);
  88. return ResultCode.Success;
  89. }
  90. [Command(1061)] // 4.0.0+
  91. // ConfirmStereoVisionRestrictionConfigurable()
  92. public ResultCode ConfirmStereoVisionRestrictionConfigurable(ServiceCtx context)
  93. {
  94. if ((_permissionFlag & 2) == 0)
  95. {
  96. return ResultCode.PermissionDenied;
  97. }
  98. if (_stereoVisionRestrictionConfigurable)
  99. {
  100. return ResultCode.Success;
  101. }
  102. else
  103. {
  104. return ResultCode.StereoVisionRestrictionConfigurableDisabled;
  105. }
  106. }
  107. [Command(1062)] // 4.0.0+
  108. // GetStereoVisionRestriction() -> bool
  109. public ResultCode GetStereoVisionRestriction(ServiceCtx context)
  110. {
  111. if ((_permissionFlag & 0x200) == 0)
  112. {
  113. return ResultCode.PermissionDenied;
  114. }
  115. bool stereoVisionRestriction = false;
  116. if (_stereoVisionRestrictionConfigurable)
  117. {
  118. stereoVisionRestriction = _stereoVisionRestriction;
  119. }
  120. context.ResponseData.Write(stereoVisionRestriction);
  121. return ResultCode.Success;
  122. }
  123. [Command(1063)] // 4.0.0+
  124. // SetStereoVisionRestriction(bool)
  125. public ResultCode SetStereoVisionRestriction(ServiceCtx context)
  126. {
  127. if ((_permissionFlag & 0x200) == 0)
  128. {
  129. return ResultCode.PermissionDenied;
  130. }
  131. bool stereoVisionRestriction = context.RequestData.ReadBoolean();
  132. if (!_featuresRestriction)
  133. {
  134. if (_stereoVisionRestrictionConfigurable)
  135. {
  136. _stereoVisionRestriction = stereoVisionRestriction;
  137. // TODO: It signals an internal event of service. We have to determine where this event is used.
  138. }
  139. }
  140. return ResultCode.Success;
  141. }
  142. [Command(1064)] // 5.0.0+
  143. // ResetConfirmedStereoVisionPermission()
  144. public ResultCode ResetConfirmedStereoVisionPermission(ServiceCtx context)
  145. {
  146. return ResultCode.Success;
  147. }
  148. [Command(1065)] // 5.0.0+
  149. // IsStereoVisionPermitted() -> bool
  150. public ResultCode IsStereoVisionPermitted(ServiceCtx context)
  151. {
  152. bool isStereoVisionPermitted = false;
  153. ResultCode resultCode = IsStereoVisionPermittedImpl();
  154. if (resultCode == ResultCode.Success)
  155. {
  156. isStereoVisionPermitted = true;
  157. }
  158. context.ResponseData.Write(isStereoVisionPermitted);
  159. return resultCode;
  160. }
  161. private ResultCode IsStereoVisionPermittedImpl()
  162. {
  163. /*
  164. // TODO: Application Exemptions are readed from file "appExemptions.dat" in the service savedata.
  165. // Since we don't support the pctl savedata for now, this can be implemented later.
  166. if (appExemption)
  167. {
  168. return ResultCode.Success;
  169. }
  170. */
  171. if (_stereoVisionRestrictionConfigurable && _stereoVisionRestriction)
  172. {
  173. return ResultCode.StereoVisionDenied;
  174. }
  175. else
  176. {
  177. return ResultCode.Success;
  178. }
  179. }
  180. }
  181. }