| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259 |
- using Ryujinx.Common.Logging;
- using Ryujinx.HLE.HOS.Services.Arp;
- using System;
- using static LibHac.Ns.ApplicationControlProperty;
- namespace Ryujinx.HLE.HOS.Services.Pctl.ParentalControlServiceFactory
- {
- class IParentalControlService : IpcService
- {
- private ulong _pid;
- private int _permissionFlag;
- private ulong _titleId;
- private ParentalControlFlagValue _parentalControlFlag;
- private int[] _ratingAge;
- #pragma warning disable CS0414
- // TODO: Find where they are set.
- private bool _restrictionEnabled = false;
- private bool _featuresRestriction = false;
- private bool _freeCommunicationEnabled = false;
- private bool _stereoVisionRestrictionConfigurable = true;
- private bool _stereoVisionRestriction = false;
- #pragma warning restore CS0414
- public IParentalControlService(ServiceCtx context, ulong pid, bool withInitialize, int permissionFlag)
- {
- _pid = pid;
- _permissionFlag = permissionFlag;
- if (withInitialize)
- {
- Initialize(context);
- }
- }
- [CommandHipc(1)] // 4.0.0+
- // Initialize()
- public ResultCode Initialize(ServiceCtx context)
- {
- if ((_permissionFlag & 0x8001) == 0)
- {
- return ResultCode.PermissionDenied;
- }
- ResultCode resultCode = ResultCode.InvalidPid;
- if (_pid != 0)
- {
- if ((_permissionFlag & 0x40) == 0)
- {
- ulong titleId = ApplicationLaunchProperty.GetByPid(context).TitleId;
- if (titleId != 0)
- {
- _titleId = titleId;
- // TODO: Call nn::arp::GetApplicationControlProperty here when implemented, if it return ResultCode.Success we assign fields.
- _ratingAge = Array.ConvertAll(context.Device.Application.ControlData.Value.RatingAge.ItemsRo.ToArray(), Convert.ToInt32);
- _parentalControlFlag = context.Device.Application.ControlData.Value.ParentalControlFlag;
- }
- }
- if (_titleId != 0)
- {
- // TODO: Service store some private fields in another static object.
- if ((_permissionFlag & 0x8040) == 0)
- {
- // TODO: Service store TitleId and FreeCommunicationEnabled in another static object.
- // When it's done it signal an event in this static object.
- Logger.Stub?.PrintStub(LogClass.ServicePctl);
- }
- }
- resultCode = ResultCode.Success;
- }
- return resultCode;
- }
- [CommandHipc(1001)]
- // CheckFreeCommunicationPermission()
- public ResultCode CheckFreeCommunicationPermission(ServiceCtx context)
- {
- if (_parentalControlFlag == ParentalControlFlagValue.FreeCommunication && _restrictionEnabled)
- {
- // TODO: It seems to checks if an entry exists in the FreeCommunicationApplicationList using the TitleId.
- // Then it returns FreeCommunicationDisabled if the entry doesn't exist.
- return ResultCode.FreeCommunicationDisabled;
- }
- _freeCommunicationEnabled = true;
- Logger.Stub?.PrintStub(LogClass.ServicePctl);
- return ResultCode.Success;
- }
- [CommandHipc(1017)] // 10.0.0+
- // EndFreeCommunication()
- public ResultCode EndFreeCommunication(ServiceCtx context)
- {
- _freeCommunicationEnabled = false;
- return ResultCode.Success;
- }
- [CommandHipc(1013)] // 4.0.0+
- // ConfirmStereoVisionPermission()
- public ResultCode ConfirmStereoVisionPermission(ServiceCtx context)
- {
- return IsStereoVisionPermittedImpl();
- }
- [CommandHipc(1018)]
- // IsFreeCommunicationAvailable()
- public ResultCode IsFreeCommunicationAvailable(ServiceCtx context)
- {
- if (_parentalControlFlag == ParentalControlFlagValue.FreeCommunication && _restrictionEnabled)
- {
- // TODO: It seems to checks if an entry exists in the FreeCommunicationApplicationList using the TitleId.
- // Then it returns FreeCommunicationDisabled if the entry doesn't exist.
- return ResultCode.FreeCommunicationDisabled;
- }
- Logger.Stub?.PrintStub(LogClass.ServicePctl);
- return ResultCode.Success;
- }
- [CommandHipc(1031)]
- // IsRestrictionEnabled() -> b8
- public ResultCode IsRestrictionEnabled(ServiceCtx context)
- {
- if ((_permissionFlag & 0x140) == 0)
- {
- return ResultCode.PermissionDenied;
- }
- context.ResponseData.Write(_restrictionEnabled);
- return ResultCode.Success;
- }
- [CommandHipc(1061)] // 4.0.0+
- // ConfirmStereoVisionRestrictionConfigurable()
- public ResultCode ConfirmStereoVisionRestrictionConfigurable(ServiceCtx context)
- {
- if ((_permissionFlag & 2) == 0)
- {
- return ResultCode.PermissionDenied;
- }
- if (_stereoVisionRestrictionConfigurable)
- {
- return ResultCode.Success;
- }
- else
- {
- return ResultCode.StereoVisionRestrictionConfigurableDisabled;
- }
- }
- [CommandHipc(1062)] // 4.0.0+
- // GetStereoVisionRestriction() -> bool
- public ResultCode GetStereoVisionRestriction(ServiceCtx context)
- {
- if ((_permissionFlag & 0x200) == 0)
- {
- return ResultCode.PermissionDenied;
- }
- bool stereoVisionRestriction = false;
- if (_stereoVisionRestrictionConfigurable)
- {
- stereoVisionRestriction = _stereoVisionRestriction;
- }
- context.ResponseData.Write(stereoVisionRestriction);
- return ResultCode.Success;
- }
- [CommandHipc(1063)] // 4.0.0+
- // SetStereoVisionRestriction(bool)
- public ResultCode SetStereoVisionRestriction(ServiceCtx context)
- {
- if ((_permissionFlag & 0x200) == 0)
- {
- return ResultCode.PermissionDenied;
- }
- bool stereoVisionRestriction = context.RequestData.ReadBoolean();
- if (!_featuresRestriction)
- {
- if (_stereoVisionRestrictionConfigurable)
- {
- _stereoVisionRestriction = stereoVisionRestriction;
- // TODO: It signals an internal event of service. We have to determine where this event is used.
- }
- }
- return ResultCode.Success;
- }
- [CommandHipc(1064)] // 5.0.0+
- // ResetConfirmedStereoVisionPermission()
- public ResultCode ResetConfirmedStereoVisionPermission(ServiceCtx context)
- {
- return ResultCode.Success;
- }
- [CommandHipc(1065)] // 5.0.0+
- // IsStereoVisionPermitted() -> bool
- public ResultCode IsStereoVisionPermitted(ServiceCtx context)
- {
- bool isStereoVisionPermitted = false;
- ResultCode resultCode = IsStereoVisionPermittedImpl();
- if (resultCode == ResultCode.Success)
- {
- isStereoVisionPermitted = true;
- }
- context.ResponseData.Write(isStereoVisionPermitted);
- return resultCode;
- }
- private ResultCode IsStereoVisionPermittedImpl()
- {
- /*
- // TODO: Application Exemptions are read from file "appExemptions.dat" in the service savedata.
- // Since we don't support the pctl savedata for now, this can be implemented later.
- if (appExemption)
- {
- return ResultCode.Success;
- }
- */
- if (_stereoVisionRestrictionConfigurable && _stereoVisionRestriction)
- {
- return ResultCode.StereoVisionDenied;
- }
- else
- {
- return ResultCode.Success;
- }
- }
- }
- }
|