aboutsummaryrefslogtreecommitdiff
path: root/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator
diff options
context:
space:
mode:
authorTSR Berry <20988865+TSRBerry@users.noreply.github.com>2023-04-08 01:22:00 +0200
committerMary <thog@protonmail.com>2023-04-27 23:51:14 +0200
commitcee712105850ac3385cd0091a923438167433f9f (patch)
tree4a5274b21d8b7f938c0d0ce18736d3f2993b11b1 /src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator
parentcd124bda587ef09668a971fa1cac1c3f0cfc9f21 (diff)
Move solution and projects to src
Diffstat (limited to 'src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator')
-rw-r--r--src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs261
1 files changed, 261 insertions, 0 deletions
diff --git a/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs
new file mode 100644
index 00000000..0057eba3
--- /dev/null
+++ b/src/Ryujinx.HLE/HOS/Services/Am/AppletAE/AllSystemAppletProxiesService/LibraryAppletCreator/ILibraryAppletAccessor.cs
@@ -0,0 +1,261 @@
+using Ryujinx.Common.Logging;
+using Ryujinx.HLE.HOS.Applets;
+using Ryujinx.HLE.HOS.Ipc;
+using Ryujinx.HLE.HOS.Kernel;
+using Ryujinx.HLE.HOS.Kernel.Threading;
+using Ryujinx.Horizon.Common;
+using System;
+
+namespace Ryujinx.HLE.HOS.Services.Am.AppletAE.AllSystemAppletProxiesService.LibraryAppletCreator
+{
+ class ILibraryAppletAccessor : DisposableIpcService
+ {
+ private KernelContext _kernelContext;
+
+ private IApplet _applet;
+
+ private AppletSession _normalSession;
+ private AppletSession _interactiveSession;
+
+ private KEvent _stateChangedEvent;
+ private KEvent _normalOutDataEvent;
+ private KEvent _interactiveOutDataEvent;
+
+ private int _stateChangedEventHandle;
+ private int _normalOutDataEventHandle;
+ private int _interactiveOutDataEventHandle;
+
+ private int _indirectLayerHandle;
+
+ public ILibraryAppletAccessor(AppletId appletId, Horizon system)
+ {
+ _kernelContext = system.KernelContext;
+
+ _stateChangedEvent = new KEvent(system.KernelContext);
+ _normalOutDataEvent = new KEvent(system.KernelContext);
+ _interactiveOutDataEvent = new KEvent(system.KernelContext);
+
+ _applet = AppletManager.Create(appletId, system);
+
+ _normalSession = new AppletSession();
+ _interactiveSession = new AppletSession();
+
+ _applet.AppletStateChanged += OnAppletStateChanged;
+ _normalSession.DataAvailable += OnNormalOutData;
+ _interactiveSession.DataAvailable += OnInteractiveOutData;
+
+ Logger.Info?.Print(LogClass.ServiceAm, $"Applet '{appletId}' created.");
+ }
+
+ private void OnAppletStateChanged(object sender, EventArgs e)
+ {
+ _stateChangedEvent.WritableEvent.Signal();
+ }
+
+ private void OnNormalOutData(object sender, EventArgs e)
+ {
+ _normalOutDataEvent.WritableEvent.Signal();
+ }
+
+ private void OnInteractiveOutData(object sender, EventArgs e)
+ {
+ _interactiveOutDataEvent.WritableEvent.Signal();
+ }
+
+ [CommandCmif(0)]
+ // GetAppletStateChangedEvent() -> handle<copy>
+ public ResultCode GetAppletStateChangedEvent(ServiceCtx context)
+ {
+ if (_stateChangedEventHandle == 0)
+ {
+ if (context.Process.HandleTable.GenerateHandle(_stateChangedEvent.ReadableEvent, out _stateChangedEventHandle) != Result.Success)
+ {
+ throw new InvalidOperationException("Out of handles!");
+ }
+ }
+
+ context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_stateChangedEventHandle);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(10)]
+ // Start()
+ public ResultCode Start(ServiceCtx context)
+ {
+ return (ResultCode)_applet.Start(_normalSession.GetConsumer(), _interactiveSession.GetConsumer());
+ }
+
+ [CommandCmif(20)]
+ // RequestExit()
+ public ResultCode RequestExit(ServiceCtx context)
+ {
+ // TODO: Since we don't support software Applet for now, we can just signals the changed state of the applet.
+ _stateChangedEvent.ReadableEvent.Signal();
+
+ Logger.Stub?.PrintStub(LogClass.ServiceAm);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(30)]
+ // GetResult()
+ public ResultCode GetResult(ServiceCtx context)
+ {
+ return (ResultCode)_applet.GetResult();
+ }
+
+ [CommandCmif(60)]
+ // PresetLibraryAppletGpuTimeSliceZero()
+ public ResultCode PresetLibraryAppletGpuTimeSliceZero(ServiceCtx context)
+ {
+ // NOTE: This call reset two internal fields to 0 and one internal field to "true".
+ // It seems to be used only with software keyboard inline.
+ // Since we doesn't support applets for now, it's fine to stub it.
+
+ Logger.Stub?.PrintStub(LogClass.ServiceAm);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(100)]
+ // PushInData(object<nn::am::service::IStorage>)
+ public ResultCode PushInData(ServiceCtx context)
+ {
+ IStorage data = GetObject<IStorage>(context, 0);
+
+ _normalSession.Push(data.Data);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(101)]
+ // PopOutData() -> object<nn::am::service::IStorage>
+ public ResultCode PopOutData(ServiceCtx context)
+ {
+ if (_normalSession.TryPop(out byte[] data))
+ {
+ MakeObject(context, new IStorage(data));
+
+ _normalOutDataEvent.WritableEvent.Clear();
+
+ return ResultCode.Success;
+ }
+
+ return ResultCode.NotAvailable;
+ }
+
+ [CommandCmif(103)]
+ // PushInteractiveInData(object<nn::am::service::IStorage>)
+ public ResultCode PushInteractiveInData(ServiceCtx context)
+ {
+ IStorage data = GetObject<IStorage>(context, 0);
+
+ _interactiveSession.Push(data.Data);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(104)]
+ // PopInteractiveOutData() -> object<nn::am::service::IStorage>
+ public ResultCode PopInteractiveOutData(ServiceCtx context)
+ {
+ if (_interactiveSession.TryPop(out byte[] data))
+ {
+ MakeObject(context, new IStorage(data));
+
+ _interactiveOutDataEvent.WritableEvent.Clear();
+
+ return ResultCode.Success;
+ }
+
+ return ResultCode.NotAvailable;
+ }
+
+ [CommandCmif(105)]
+ // GetPopOutDataEvent() -> handle<copy>
+ public ResultCode GetPopOutDataEvent(ServiceCtx context)
+ {
+ if (_normalOutDataEventHandle == 0)
+ {
+ if (context.Process.HandleTable.GenerateHandle(_normalOutDataEvent.ReadableEvent, out _normalOutDataEventHandle) != Result.Success)
+ {
+ throw new InvalidOperationException("Out of handles!");
+ }
+ }
+
+ context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_normalOutDataEventHandle);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(106)]
+ // GetPopInteractiveOutDataEvent() -> handle<copy>
+ public ResultCode GetPopInteractiveOutDataEvent(ServiceCtx context)
+ {
+ if (_interactiveOutDataEventHandle == 0)
+ {
+ if (context.Process.HandleTable.GenerateHandle(_interactiveOutDataEvent.ReadableEvent, out _interactiveOutDataEventHandle) != Result.Success)
+ {
+ throw new InvalidOperationException("Out of handles!");
+ }
+ }
+
+ context.Response.HandleDesc = IpcHandleDesc.MakeCopy(_interactiveOutDataEventHandle);
+
+ return ResultCode.Success;
+ }
+
+ [CommandCmif(110)]
+ // NeedsToExitProcess()
+ public ResultCode NeedsToExitProcess(ServiceCtx context)
+ {
+ return ResultCode.Stubbed;
+ }
+
+ [CommandCmif(150)]
+ // RequestForAppletToGetForeground()
+ public ResultCode RequestForAppletToGetForeground(ServiceCtx context)
+ {
+ return ResultCode.Stubbed;
+ }
+
+ [CommandCmif(160)] // 2.0.0+
+ // GetIndirectLayerConsumerHandle() -> u64 indirect_layer_consumer_handle
+ public ResultCode GetIndirectLayerConsumerHandle(ServiceCtx context)
+ {
+ Horizon horizon = _kernelContext.Device.System;
+
+ _indirectLayerHandle = horizon.AppletState.IndirectLayerHandles.Add(_applet);
+
+ context.ResponseData.Write((ulong)_indirectLayerHandle);
+
+ return ResultCode.Success;
+ }
+
+ protected override void Dispose(bool isDisposing)
+ {
+ if (isDisposing)
+ {
+ if (_stateChangedEventHandle != 0)
+ {
+ _kernelContext.Syscall.CloseHandle(_stateChangedEventHandle);
+ }
+
+ if (_normalOutDataEventHandle != 0)
+ {
+ _kernelContext.Syscall.CloseHandle(_normalOutDataEventHandle);
+ }
+
+ if (_interactiveOutDataEventHandle != 0)
+ {
+ _kernelContext.Syscall.CloseHandle(_interactiveOutDataEventHandle);
+ }
+ }
+
+ Horizon horizon = _kernelContext.Device.System;
+
+ horizon.AppletState.IndirectLayerHandles.Delete(_indirectLayerHandle);
+ }
+ }
+}