--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Applications;
+using Tizen.Applications.ComponentBased;
+
+internal static partial class Interop
+{
+ internal static partial class ComponentPort
+ {
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ComponentPortRequestCallback(string sender, IntPtr request, IntPtr userData);
+ // typedef void (*component_port_request_cb)(const char *sender, parcel_h request, IntPtr user_data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ComponentPortSyncRequestCallback(string sender, IntPtr request, IntPtr response, IntPtr userData);
+ // typedef void (*component_port_request_cb)(const char *sender, parcel_h request, parcel_h response IntPtr user_data);
+
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ IOError = Tizen.Internals.Errors.ErrorCode.IoError,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ }
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_create")]
+ internal static extern ErrorCode Create(string portName, out IntPtr handle);
+ // int component_port_create(const char *port_name, component_port_h *port);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_destroy")]
+ internal static extern ErrorCode Destroy(IntPtr handle);
+ // int component_port_destroy(component_port_h port);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_set_request_cb")]
+ internal static extern ErrorCode SetRequestCb(IntPtr handle, ComponentPortRequestCallback callback, IntPtr userData);
+ // int component_port_set_request_cb(component_port_h port, component_port_request_cb callback, void *user_data);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_set_sync_request_cb")]
+ internal static extern ErrorCode SetSyncRequestCb(IntPtr handle, ComponentPortSyncRequestCallback callback, IntPtr userData);
+ // int component_port_set_sync_request_cb(component_port_h port, component_port_sync_request_cb callback, void *user_data);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_add_privilege")]
+ internal static extern ErrorCode AddPrivilege(IntPtr handle, string privilege);
+ // int component_port_add_privilege(component_port_h port, const char *privilege);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_wait_for_event")]
+ internal static extern void WaitForEvent(IntPtr handle);
+ // void component_port_wait_for_event(component_port_h port);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_cancel")]
+ internal static extern void Cancel(IntPtr handle);
+ // void component_port_cancel(component_port_h port);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_send")]
+ internal static extern ErrorCode Send(IntPtr handle, string endpoint, Int32 timeout, SafeParcelHandle request);
+ // int component_port_send(component_port_h port, const char *endpoint, int timeout, parcel_h request);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_send_sync")]
+ internal static extern ErrorCode SendSync(IntPtr handle, string endpoint, Int32 timeout, SafeParcelHandle request, out SafeParcelHandle response);
+ // int component_port_send(component_port_h port, const char *endpoint, int timeout, parcel_h request, parcel_h *response);
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string ComponentPort = "libcomponent-based-port.so.1";
+ public const string Parcel = "libparcel.so.0";
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+using Tizen.Internals;
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class Parcel
+ {
+ internal enum ErrorCode
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ IllegalByteSeq = Tizen.Internals.Errors.ErrorCode.IllegalByteSeq,
+ NoData = Tizen.Internals.Errors.ErrorCode.NoData,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ }
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_create")]
+ internal static extern ErrorCode Create(out SafeParcelHandle handle);
+ // int parcel_create(parcel_h *parcel);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_destroy")]
+ internal static extern ErrorCode DangerousDestroy(IntPtr handle);
+ // int parcel_destroy(parcel_h parcel);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_clone")]
+ internal static extern ErrorCode DangerousClone(IntPtr handle, out SafeParcelHandle clone);
+ // int parcel_clone(parcel_h parcel, parcel_h *clone);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_burst_write")]
+ internal static extern ErrorCode BurstWrite(SafeParcelHandle handle, byte[] buf, UInt32 size);
+ // int parcel_burst_write(parcel_h parcel, cont void *buf, uint32_t size);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_burst_read")]
+ internal static extern ErrorCode BurstRead(SafeParcelHandle handle, [In, Out] byte[] buf, UInt32 size);
+ // int parcel_burst_read(parcel_h parcel, void *buf, uint32_t size);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_bool")]
+ internal static extern ErrorCode WriteBool(SafeParcelHandle handle, bool val);
+ // int parcel_write_bool(parcel_h parcel, bool val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_byte")]
+ internal static extern ErrorCode WriteByte(SafeParcelHandle handle, byte val);
+ // int parcel_write_byte(parcel_h parcel, char val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_uint16")]
+ internal static extern ErrorCode WriteUInt16(SafeParcelHandle handle, UInt16 val);
+ // int parcel_write_uint16(parcel_h parcel, uint16_t val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_uint32")]
+ internal static extern ErrorCode WriteUInt32(SafeParcelHandle handle, UInt32 val);
+ // int parcel_write_uint32(parcel_h parcel, uint32_t val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_uint64")]
+ internal static extern ErrorCode WriteUInt64(SafeParcelHandle handle, UInt64 val);
+ // int parcel_write_uint64(parcel_h parcel, uint64_t val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_int16")]
+ internal static extern ErrorCode WriteInt16(SafeParcelHandle handle, Int16 val);
+ // int parcel_write_int16(parcel_h parcel, int16_t val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_int32")]
+ internal static extern ErrorCode WriteInt32(SafeParcelHandle handle, Int32 val);
+ // int parcel_write_int32(parcel_h parcel, int32_t val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_int64")]
+ internal static extern ErrorCode WriteInt64(SafeParcelHandle handle, Int64 val);
+ // int parcel_write_int64(parcel_h parcel, int64_t val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_float")]
+ internal static extern ErrorCode WriteFloat(SafeParcelHandle handle, float val);
+ // int parcel_write_float(parcel_h parcel, float val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_double")]
+ internal static extern ErrorCode WriteDouble(SafeParcelHandle handle, double val);
+ // int parcel_write_double(parcel_h parcel, double val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_string")]
+ internal static extern ErrorCode WriteString(SafeParcelHandle handle, string str);
+ // int parcel_write_string(parcel_h parcel, const char *str);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_write_bundle")]
+ internal static extern ErrorCode WriteBundle(SafeParcelHandle handle, IntPtr b);
+ // int parcel_write_bundle(parcel_h parcel, bundle *b);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_bool")]
+ internal static extern ErrorCode ReadBool(SafeParcelHandle handle, out bool val);
+ // int parcel_read_bool(parcel_h parcel, bool *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_byte")]
+ internal static extern ErrorCode ReadByte(SafeParcelHandle handle, out byte val);
+ // int parcel_read_byte(parcel_h parcel, char *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_uint16")]
+ internal static extern ErrorCode ReadUInt16(SafeParcelHandle handle, out UInt16 val);
+ // int parcel_read_uint16(parcel_h parcel, uint16_t *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_uint32")]
+ internal static extern ErrorCode ReadUInt32(SafeParcelHandle handle, out UInt32 val);
+ // int parcel_read_uint32(parcel_h parcel, uint32_t *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_uint64")]
+ internal static extern ErrorCode ReadUInt64(SafeParcelHandle handle, out UInt64 val);
+ // int parcel_read_uint64(parcel_h parcel, uint64_t *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_int16")]
+ internal static extern ErrorCode ReadInt16(SafeParcelHandle handle, out Int16 val);
+ // int parcel_read_int16(parcel_h parcel, int16_t *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_int32")]
+ internal static extern ErrorCode ReadInt32(SafeParcelHandle handle, out Int32 val);
+ // int parcel_read_int32(parcel_h parcel, int32_t *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_int64")]
+ internal static extern ErrorCode ReadInt64(SafeParcelHandle handle, out Int64 val);
+ // int parcel_read_int64(parcel_h parcel, int64_t *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_float")]
+ internal static extern ErrorCode ReadFloat(SafeParcelHandle handle, out float val);
+ // int parcel_read_float(parcel_h parcel, float *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_double")]
+ internal static extern ErrorCode ReadDouble(SafeParcelHandle handle, out double val);
+ // int parcel_read_double(parcel_h parcel, double *val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_string")]
+ internal static extern ErrorCode ReadString(SafeParcelHandle handle, out string val);
+ // int parcel_read_string(parcel_h parcel, char **val);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_read_bundle")]
+ internal static extern ErrorCode ReadBundle(SafeParcelHandle handle, out IntPtr b);
+ // int parcel_read_bundle(parcel_h parcel, bundle **b);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_get_raw")]
+ internal static extern ErrorCode GetRaw(SafeParcelHandle handle, out IntPtr raw, out UInt32 size);
+ // int parcel_get_raw(parcel_h parcel, void **raw, uint32_t *size);
+
+ [DllImport(Libraries.Parcel, EntryPoint = "parcel_reset")]
+ internal static extern ErrorCode Reset(SafeParcelHandle handle, byte[] buf, UInt32 size);
+ // int parcel_reset(parcel_h parcel, const void *buf, uint32_t size);
+ }
+}
\ No newline at end of file
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Tizen\Tizen.csproj" />
+ <ProjectReference Include="..\Tizen.Log\Tizen.Log.csproj" />
+ </ItemGroup>
+
+</Project>
\ No newline at end of file
--- /dev/null
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30517.126
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Applications.ComponentBased.Port", "Tizen.Applications.ComponentBased.Port.csproj", "{FF190549-DDD6-47ED-ABA3-717B0C130C3D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen", "..\Tizen\Tizen.csproj", "{2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Tizen.Log", "..\Tizen.Log\Tizen.Log.csproj", "{8DA5B43B-63E9-460C-B64F-0B691539DC5D}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {FF190549-DDD6-47ED-ABA3-717B0C130C3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FF190549-DDD6-47ED-ABA3-717B0C130C3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FF190549-DDD6-47ED-ABA3-717B0C130C3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FF190549-DDD6-47ED-ABA3-717B0C130C3D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2E04FB0F-03F4-40B0-BB25-5ADFB08C8DF3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8DA5B43B-63E9-460C-B64F-0B691539DC5D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8DA5B43B-63E9-460C-B64F-0B691539DC5D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8DA5B43B-63E9-460C-B64F-0B691539DC5D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8DA5B43B-63E9-460C-B64F-0B691539DC5D}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {0335C3BF-98CA-4337-96E5-088E9CEFDFFC}
+ EndGlobalSection
+EndGlobal
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.IO;
+using System.Reflection;
+using System.Runtime.Serialization;
+using System.Runtime.Serialization.Formatters;
+using System.Runtime.Serialization.Formatters.Binary;
+using System.Security;
+using System.Xml.Serialization;
+
+namespace Tizen.Applications.ComponentBased
+{
+ /// <summary>
+ /// Abstract class for creating a component port class.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public abstract class ComponentPort : IDisposable
+ {
+ private static string LogTag = "ComponentPort";
+ private readonly string _portName;
+ private IntPtr _port = IntPtr.Zero;
+ private Interop.ComponentPort.ComponentPortRequestCallback _requestEventCallback;
+ private Interop.ComponentPort.ComponentPortSyncRequestCallback _syncRequestEventCallback;
+
+ /// <summary>
+ /// Constructor for this class.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when the argument is invalid.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the memory is insufficient.</exception>
+ /// <exception cref="global::System.IO.IOException">Thrown when because of I/O error.</exception>
+ /// <param name="portName">The name of the port.</param>
+ /// <since_tizen> 9 </since_tizen>
+ public ComponentPort(string portName)
+ {
+ var ret = Interop.ComponentPort.Create(portName, out _port);
+ if (ret != Interop.ComponentPort.ErrorCode.None)
+ throw ComponentPortErrorFactory.GetException(ret, "ComponentPort(" + portName + ").");
+
+ _portName = portName;
+ _requestEventCallback = new Interop.ComponentPort.ComponentPortRequestCallback(OnRequestEvent);
+ _syncRequestEventCallback = new Interop.ComponentPort.ComponentPortSyncRequestCallback(OnSyncRequestEvent);
+ Interop.ComponentPort.SetRequestCb(_port, _requestEventCallback, IntPtr.Zero);
+ Interop.ComponentPort.SetSyncRequestCb(_port, _syncRequestEventCallback, IntPtr.Zero);
+ }
+
+ /// <summary>
+ /// Gets the port name.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string PortName
+ {
+ get
+ {
+ return _portName;
+ }
+ }
+
+ /// <summary>
+ /// Adds a privilege to the port object.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when the argument is invalid.</exception>
+ /// <param name="privilege">privilege data</param>
+ /// <since_tizen> 9 </since_tizen>
+ public void AddPrivilege(string privilege)
+ {
+ Interop.ComponentPort.AddPrivilege(_port, privilege);
+ }
+
+ /// <summary>
+ /// Waits for events.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void WaitForEvent()
+ {
+ Interop.ComponentPort.WaitForEvent(_port);
+ }
+
+ /// <summary>
+ /// Cancels waiting for events.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Cancel()
+ {
+ Interop.ComponentPort.Cancel(_port);
+ }
+
+ /// <summary>
+ /// Sends the request data.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when the argument is invalid.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the memory is insufficient.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when because of permission denied.</exception>
+ /// <exception cref="global::System.IO.IOException">Thrown when because of I/O error.</exception>
+ /// <param name="endpoint">The name of the endpoint</param>
+ /// <param name="timeout">The interval of timeout</param>
+ /// <param name="request">The serializable data to send</param>
+ /// <since_tizen> 9 </since_tizen>
+ public void Send(string endpoint, int timeout, object request)
+ {
+ if (request == null)
+ {
+ throw new ArgumentException("request is null");
+ }
+
+ if (!request.GetType().IsSerializable)
+ {
+ throw new ArgumentException("request is not serializable");
+ }
+
+ Interop.ComponentPort.ErrorCode err;
+ using (Parcel reqParcel = ToParcel(request))
+ {
+ err = Interop.ComponentPort.Send(_port, endpoint, timeout, reqParcel.SafeParcelHandle);
+ }
+ if (err != Interop.ComponentPort.ErrorCode.None)
+ {
+ throw ComponentPortErrorFactory.GetException(err, "Failed to send the request.");
+ }
+ }
+
+ /// <summary>
+ /// Sends the request data synchronously.
+ /// </summary>
+ /// <exception cref="ArgumentException">Thrown when the argument is invalid.</exception>
+ /// <exception cref="OutOfMemoryException">Thrown when the memory is insufficient.</exception>
+ /// <exception cref="UnauthorizedAccessException">Thrown when because of permission denied.</exception>
+ /// <exception cref="global::System.IO.IOException">Thrown when because of I/O error.</exception>
+ /// <param name="endpoint">The name of the endpoint</param>
+ /// <param name="timeout">The interval of timeout</param>
+ /// <param name="request">The serializable data to send</param>
+ /// <returns>The received serializable data</returns>
+ /// /// <since_tizen> 9 </since_tizen>
+ public object SendSync(string endpoint, int timeout, object request)
+ {
+ if (request == null)
+ {
+ throw new ArgumentException("request is null");
+ }
+
+ if (!request.GetType().IsSerializable)
+ {
+ throw new ArgumentException("request is not serializable");
+ }
+
+ SafeParcelHandle resSafeHandle = null;
+ Interop.ComponentPort.ErrorCode err;
+ using (Parcel reqParcel = ToParcel(request))
+ {
+ err = Interop.ComponentPort.SendSync(_port, endpoint, timeout, reqParcel.SafeParcelHandle, out resSafeHandle);
+ }
+ if (err != Interop.ComponentPort.ErrorCode.None)
+ {
+ throw ComponentPortErrorFactory.GetException(err, "Failed to send the request.");
+ }
+
+ using (Parcel resParcel = new Parcel(resSafeHandle))
+ {
+ object response = FromParcel(resParcel);
+ return response;
+ }
+ }
+
+ /// <summary>
+ /// Abstract method for receiving a request event.
+ /// </summary>
+ /// <param name="sender">The name of the sender</param>
+ /// <param name="request">The serializable data</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract void OnRequestEvent(string sender, object request);
+
+ /// <summary>
+ /// Abstract method for receiving a synchronous request event.
+ /// </summary>
+ /// <param name="sender">The name of the sender</param>
+ /// <param name="request">The serializable data</param>
+ /// <returns>The serializable data</returns>
+ /// <since_tizen> 9 </since_tizen>
+ protected abstract object OnSyncRequestEvent(string sender, object request);
+
+
+ private void OnRequestEvent(string sender, IntPtr request, IntPtr data)
+ {
+ SafeParcelHandle reqSafeHandle = new SafeParcelHandle(request, false);
+ using (var reqParcel = new Parcel(reqSafeHandle))
+ {
+ object req = FromParcel(reqParcel);
+ OnRequestEvent(sender, req);
+ }
+ }
+
+ private void OnSyncRequestEvent(string sender, IntPtr request, IntPtr response, IntPtr data)
+ {
+ SafeParcelHandle reqSafeHandle = new SafeParcelHandle(request, false);
+
+ object req = null;
+ using (Parcel reqParcel = new Parcel(reqSafeHandle))
+ {
+ req = FromParcel(reqParcel);
+ }
+
+ object result = OnSyncRequestEvent(sender, req);
+ if (!result.GetType().IsSerializable)
+ {
+ Log.Error(LogTag, "result is not serializable");
+ }
+ else
+ {
+ SafeParcelHandle resSafeHandle = new SafeParcelHandle(response, false);
+ using (Parcel resParcel = new Parcel(resSafeHandle))
+ {
+ using (Parcel resultParcel = ToParcel(result))
+ {
+ resParcel.UnMarshall(resultParcel.Marshall());
+ }
+ }
+ }
+ }
+
+ private Parcel ToParcel(object envelope)
+ {
+ if (envelope == null)
+ return null;
+
+ BinaryFormatter formatter = new BinaryFormatter
+ {
+ Binder = new PortBinder(),
+ AssemblyFormat = FormatterAssemblyStyle.Full
+ };
+
+ using (MemoryStream stream = new MemoryStream())
+ {
+ formatter.Serialize(stream, envelope);
+ Parcel parcel = new Parcel();
+ parcel.UnMarshall(stream.ToArray());
+ return parcel;
+ }
+ }
+
+ private object FromParcel(Parcel parcel)
+ {
+ if (parcel == null)
+ return null;
+
+ BinaryFormatter formatter = new BinaryFormatter
+ {
+ Binder = new PortBinder(),
+ AssemblyFormat = FormatterAssemblyStyle.Full,
+ };
+
+ object envelope = null;
+ using (MemoryStream stream = new MemoryStream(parcel.Marshall()))
+ {
+ try
+ {
+ envelope = (object)formatter.Deserialize(stream);
+ }
+ catch (ArgumentException e)
+ {
+ Log.Error(LogTag, "ArgumentException occurs: " + e.Message);
+ }
+ catch (SerializationException e)
+ {
+ Log.Error(LogTag, "SerializationException occurs: " + e.Message);
+ }
+ catch (SecurityException e)
+ {
+ Log.Error(LogTag, "SecurityException occurs: " + e.Message);
+ }
+ }
+
+ return envelope;
+ }
+
+
+ #region IDisposable Support
+ private bool disposedValue = false;
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable objects, or false not to dispose disposable objects.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ if (_port != IntPtr.Zero)
+ Interop.ComponentPort.Destroy(_port);
+ _port = IntPtr.Zero;
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Finalizer of the class ComponentPort.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ ~ComponentPort()
+ {
+ Dispose(disposing: false);
+ }
+
+ /// <summary>
+ /// Releases all the resources used by the class ComponentPort.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>>
+ public void Dispose()
+ {
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ internal sealed class PortBinder : SerializationBinder
+ {
+ private static string LogTag = "PortBinder";
+
+ private string GetAssemblyName(string typeName)
+ {
+ foreach (Assembly a in AppDomain.CurrentDomain.GetAssemblies())
+ {
+ foreach (Type t in a.GetTypes())
+ {
+ if (t.FullName == typeName)
+ {
+ Log.Warn(LogTag, "Found! AssemblyName: " + a.FullName);
+ return a.FullName;
+ }
+ }
+ }
+
+ return string.Empty;
+ }
+
+ public override Type BindToType(string assemblyName, string typeName)
+ {
+ Type returntype = null;
+ Log.Warn(LogTag, "AssemblyName: " + assemblyName);
+ Log.Warn(LogTag, "TypeName: " + typeName);
+ string foundAssemblyName = GetAssemblyName(typeName);
+ if (foundAssemblyName.Length != 0)
+ {
+ returntype = Type.GetType(String.Format("{0}, {1}", typeName, foundAssemblyName));
+ }
+ else
+ {
+ returntype = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));
+ }
+ return returntype;
+ }
+ }
+
+ internal static class ComponentPortErrorFactory
+ {
+ internal static Exception GetException(Interop.ComponentPort.ErrorCode err, string message)
+ {
+ string errMessage = string.Format("{0} err = {1}", message, err);
+ switch (err)
+ {
+ case Interop.ComponentPort.ErrorCode.InvalidParameter:
+ return new ArgumentException(errMessage);
+ case Interop.ComponentPort.ErrorCode.PermissionDenied:
+ return new UnauthorizedAccessException(errMessage);
+ case Interop.ComponentPort.ErrorCode.OutOfMemory:
+ return new OutOfMemoryException(errMessage);
+ default:
+ return new global::System.IO.IOException(errMessage);
+ }
+ }
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications.ComponentBased
+{
+ internal class Parcel : IDisposable
+ {
+ private readonly SafeParcelHandle _handle;
+
+ public Parcel()
+ {
+ var ret = Interop.Parcel.Create(out _handle);
+ if (ret != Interop.Parcel.ErrorCode.None)
+ {
+ throw ParcelErrorFactory.GetException(ret, "Parcel() is failed.");
+ }
+ }
+
+ public Parcel(SafeParcelHandle handle)
+ {
+ if (handle == null)
+ {
+ throw new ArgumentException("handle is null");
+ }
+
+ _handle = handle;
+ }
+
+ public SafeParcelHandle SafeParcelHandle
+ {
+ get
+ {
+ return _handle;
+ }
+ }
+
+ public byte[] Marshall()
+ {
+ Interop.Parcel.GetRaw(_handle, out IntPtr raw, out UInt32 size);
+ byte[] ret = new byte[size];
+ Marshal.Copy((IntPtr)raw, (byte[])ret, 0, (int)size);
+ return ret;
+ }
+
+ public void UnMarshall(byte[] bytes)
+ {
+ Interop.Parcel.Reset(_handle, bytes, (UInt32)bytes.Length);
+ }
+
+ #region IDisposable Support
+ private bool disposedValue = false;
+
+ /// <summary>
+ /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
+ /// </summary>
+ /// <param name="disposing">If true, disposes any disposable object.</param>
+ /// <since_tizen> 9 </since_tizen>
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!disposedValue)
+ {
+ if (disposing)
+ {
+ if (_handle != null && !_handle.IsInvalid)
+ _handle.Dispose();
+ }
+
+ disposedValue = true;
+ }
+ }
+
+ /// <summary>
+ /// Finalizer of the class Parcel.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ ~Parcel()
+ {
+ Dispose(disposing: false);
+ }
+
+ /// <summary>
+ /// Releases all the resources used by the class parcel.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>>
+ public void Dispose()
+ {
+ Dispose(disposing: true);
+ GC.SuppressFinalize(this);
+ }
+ #endregion
+
+ internal static class ParcelErrorFactory
+ {
+ internal static Exception GetException(Interop.Parcel.ErrorCode err, string message)
+ {
+ string errMessage = string.Format("{0} err = {1}", message, err);
+ switch (err)
+ {
+ case Interop.Parcel.ErrorCode.NoData:
+ case Interop.Parcel.ErrorCode.IllegalByteSeq:
+ return new InvalidOperationException(errMessage);
+ case Interop.Parcel.ErrorCode.InvalidParameter:
+ return new ArgumentException(errMessage);
+ default:
+ return new OutOfMemoryException(errMessage);
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+/*
+ * Copyright (c) 2021 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Applications
+{
+ internal sealed class SafeParcelHandle : SafeHandle
+ {
+ public SafeParcelHandle() : base(IntPtr.Zero, true)
+ {
+
+ }
+
+ public SafeParcelHandle(IntPtr existingHandle, bool ownsHandle) : base(IntPtr.Zero, ownsHandle)
+ {
+ SetHandle(existingHandle);
+ }
+
+ public override bool IsInvalid
+ {
+ get { return this.handle == IntPtr.Zero; }
+ }
+
+ protected override bool ReleaseHandle()
+ {
+ Interop.Parcel.DangerousDestroy(this.handle);
+ this.SetHandle(IntPtr.Zero);
+ return true;
+ }
+ }
+}
\ No newline at end of file