{
[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);
+ // typedef void (*component_port_request_cb)(const char *sender, parcel_h request, void *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);
+ // typedef void (*component_port_request_cb)(const char *sender, parcel_h request, parcel_h response, void *user_data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ComponentPortAppearedCallback(string endpoint, int owner, IntPtr userData);
+ // typedef void (*component_port_appeared_cb)(const char *endpoint, int owner, owner user_data);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ComponentPortVanishedCallback(string endpoint, IntPtr userData);
+ // typedef void (*component_port_vanished_cb)(const char *endpoint, void *user_data);
+
internal enum ErrorCode
{
[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);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_is_running")]
+ internal static extern ErrorCode IsRunning(string endpoint, out bool isRunning);
+ // int component_port_is_running(const char *endpoint, bool *is_running);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_watch")]
+ internal static extern ErrorCode Watch(string endpoint, ComponentPortAppearedCallback appearedCallback, ComponentPortVanishedCallback vanishedCallback, IntPtr userData, out uint watcherId);
+ // int component_port_watch(const char *endpoint, component_port_appeared_cb appeared_cb, component_port_vanished_cb vanished_cb, void *user_data, unsigned int *watcher_id);
+
+ [DllImport(Libraries.ComponentPort, EntryPoint = "component_port_unwatch")]
+ internal static extern ErrorCode Unwatch(uint watcherId);
+ // int component_port_unwatch(unsigned int watcher_id);
}
}
\ No newline at end of file
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);
*/
using System;
+using System.Collections.Generic;
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;
+using System.Threading;
+using System.Threading.Tasks;
namespace Tizen.Applications.ComponentBased
{
/// <summary>
- /// Abstract class for creating a component port class.
+ /// The component port API provides functions to send and receive requests between components of component-based-application.
/// </summary>
/// <since_tizen> 9 </since_tizen>
- public abstract class ComponentPort : IDisposable
+ public 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;
+ private static Dictionary<int, uint> _watcherIdMap = new Dictionary<int, uint>();
+ private static Dictionary<int, Interop.ComponentPort.ComponentPortAppearedCallback> _appearedNativeCallbackMap = new Dictionary<int, Interop.ComponentPort.ComponentPortAppearedCallback>();
+ private static Dictionary<int, Interop.ComponentPort.ComponentPortVanishedCallback> _vanishedNativeCallbackMap = new Dictionary<int, Interop.ComponentPort.ComponentPortVanishedCallback>();
+ private static int _requestId = 0;
/// <summary>
/// Constructor for this class.
if (ret != Interop.ComponentPort.ErrorCode.None)
throw ComponentPortErrorFactory.GetException(ret, "ComponentPort(" + portName + ").");
- _portName = portName;
+ PortName = portName;
_requestEventCallback = new Interop.ComponentPort.ComponentPortRequestCallback(OnRequestEvent);
_syncRequestEventCallback = new Interop.ComponentPort.ComponentPortSyncRequestCallback(OnSyncRequestEvent);
Interop.ComponentPort.SetRequestCb(_port, _requestEventCallback, IntPtr.Zero);
/// <since_tizen> 9 </since_tizen>
public string PortName
{
- get
- {
- return _portName;
- }
+ get;
+ private set;
}
/// <summary>
Interop.ComponentPort.AddPrivilege(_port, privilege);
}
+ private static Task<bool> WaitForPortCore(string endpoint)
+ {
+ Interop.ComponentPort.IsRunning(endpoint, out bool isRunning);
+ if (isRunning)
+ {
+ return Task.FromResult(true);
+ }
+
+ var task = new TaskCompletionSource<bool>();
+ int requestId;
+ lock (_appearedNativeCallbackMap)
+ {
+ requestId = _requestId++;
+ _appearedNativeCallbackMap[requestId] = (string portName, int owner, IntPtr userData) =>
+ {
+ int id = (int)userData;
+ Log.Info(LogTag, portName + " is appeared");
+ task.SetResult(true);
+ lock (_watcherIdMap)
+ {
+ Interop.ComponentPort.Unwatch(_watcherIdMap[id]);
+ _watcherIdMap.Remove(id);
+ }
+
+ lock (_vanishedNativeCallbackMap)
+ {
+ _vanishedNativeCallbackMap.Remove(id);
+ }
+
+ lock (_appearedNativeCallbackMap)
+ {
+ _appearedNativeCallbackMap.Remove(id);
+ }
+ };
+ }
+
+ lock (_vanishedNativeCallbackMap)
+ {
+ _vanishedNativeCallbackMap[requestId] = (string portName, IntPtr userData) =>
+ {
+ Log.Info(LogTag, portName + " is vanished");
+ };
+ }
+
+ lock (_watcherIdMap)
+ {
+ Interop.ComponentPort.Watch(endpoint, _appearedNativeCallbackMap[requestId], _vanishedNativeCallbackMap[requestId], (IntPtr)requestId, out uint watcherId);
+ _watcherIdMap[requestId] = watcherId;
+ }
+
+ return task.Task;
+ }
+
+ /// <summary>
+ /// Waits until the port is ready.
+ /// </summary>
+ /// <param name="endpoint">The name of the port</param>
+ /// <returns>A task.</returns>
+ public static Task WaitForPort(string endpoint)
+ {
+ return WaitForPortCore(endpoint);
+ }
+
/// <summary>
/// Waits for events.
/// </summary>
+ /// <remarks>
+ /// This method runs a main loop until Cancel() is called.
+ /// The code in the next line will not run until Cancel() is called.
+ /// To avoid blocking the main thread, it's recommended to use the ComponentTask class.
+ /// </remarks>
+ /// <example>
+ /// <code>
+ /// ComponentTask task = new ComponentTask(new ComponentPort("Comm"));
+ /// task.Start();
+ /// </code>
+ /// </example>
/// <since_tizen> 9 </since_tizen>
public void WaitForEvent()
{
/// </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="UnauthorizedAccessException">Thrown when permission is 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="timeout">The timeout in milliseconds, -1 to use the default 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)
}
/// <summary>
- /// Sends the request data synchronously.
+ /// Sends the request data and receives the reply 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="UnauthorizedAccessException">Thrown when permission is 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="timeout">The timeout in milliseconds, -1 to use the default 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)
+ /// <since_tizen> 9 </since_tizen>
+ public object SendAndReceive(string endpoint, int timeout, object request)
{
if (request == null)
{
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)
{
object response = FromParcel(resParcel);
return response;
- }
+ }
}
/// <summary>
- /// Abstract method for receiving a request event.
+ /// Sends the request data and receives the reply data asynchronously.
/// </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);
+ /// <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 permission is 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 timeout in milliseconds, -1 to use the default timeout</param>
+ /// <param name="request">The serializable data to send</param>
+ /// <returns>The received serializable data</returns>
+ /// /// <since_tizen> 9 </since_tizen>
+ public async Task<object> SendAndReceiveAsync(string endpoint, int timeout, object request)
+ {
+ try
+ {
+ return Task.Run(() => SendAndReceive(endpoint, timeout, request));
+ }
+ catch
+ {
+ throw;
+ }
+ }
/// <summary>
- /// Abstract method for receiving a synchronous request event.
+ /// Occurs whenever the request is received.
/// </summary>
- /// <param name="sender">The name of the sender</param>
- /// <param name="request">The serializable data</param>
- /// <returns>The serializable data</returns>
+ /// <remarks>
+ /// If the reply is requested, RequestEventArgs.Request should be set.
+ /// </remarks>
/// <since_tizen> 9 </since_tizen>
- protected abstract object OnSyncRequestEvent(string sender, object request);
-
+ public event EventHandler<RequestEventArgs> RequestReceived;
private void OnRequestEvent(string sender, IntPtr request, IntPtr data)
{
using (var reqParcel = new Parcel(reqSafeHandle))
{
object req = FromParcel(reqParcel);
- OnRequestEvent(sender, req);
+ RequestReceived?.Invoke(this, new RequestEventArgs(sender, req, false));
}
}
req = FromParcel(reqParcel);
}
- object result = OnSyncRequestEvent(sender, req);
- if (!result.GetType().IsSerializable)
+ var args = new RequestEventArgs(sender, req, true);
+ RequestReceived?.Invoke(this, args);
+
+ var result = args.Reply;
+ if (result == null)
+ {
+ Log.Error(LogTag, "result is null");
+ }
+ else if (!result.GetType().IsSerializable)
{
Log.Error(LogTag, "result is not serializable");
}
--- /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.Collections.Generic;
+using System.Threading;
+
+namespace Tizen.Applications.ComponentBased
+{
+ /// <summary>
+ /// Provides a task class for the ComponentPort class.
+ /// This is a convenience class to manage ComponentPort communication in a separate thread.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public class ComponentTask
+ {
+ private Thread _thread;
+ private object _threadLock = new object();
+ private static List<ComponentTask> _holder = new List<ComponentTask>();
+
+ /// <summary>
+ /// Initializes the instance of the ComponentTask class.
+ /// </summary>
+ /// <param name="port">The component port object</param>
+ /// <since_tizen> 9 </since_tizen>
+ public ComponentTask(ComponentPort port)
+ {
+ Port = port;
+ }
+
+ private void OnThread()
+ {
+ lock (_holder)
+ {
+ _holder.Add(this);
+ }
+
+ IsRunning = true;
+ Port?.WaitForEvent();
+ IsRunning = false;
+
+ lock (_holder)
+ {
+ _holder.Remove(this);
+ }
+ }
+
+ /// <summary>
+ /// Starts the task.
+ /// <remark>
+ /// This method calls ComponentPort.WaitForEvent() in the thread.
+ /// </remark>
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public void Start()
+ {
+ lock (_threadLock)
+ {
+ if (_thread == null)
+ {
+ _thread = new Thread(new ThreadStart(OnThread));
+ _thread.Start();
+ IsRunning = true;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Stops the task.
+ /// </summary>
+ /// <remarks>
+ /// This method calls ComponentPort.Cancel() before stopping the thread.
+ /// </remarks>
+ /// <since_tizen> 9 </since_tizen>
+ public void Stop()
+ {
+ lock (_threadLock)
+ {
+ if (_thread != null)
+ {
+ Port?.Cancel();
+ _thread.Join();
+ _thread = null;
+ }
+ }
+ }
+
+ /// <summary>
+ /// Checks whether the component task is running.
+ /// </summary>
+ /// <value>If the task is running, true; otherwise, false</value>
+ /// <since_tizen> 9 </since_tizen>
+ public bool IsRunning
+ {
+ get;
+ private set;
+ }
+
+ /// <summary>
+ /// Gets the component port.
+ /// </summary>
+ /// <value>The instance of the component port</value>
+ /// <since_tizen> 9 </since_tizen>
+ public ComponentPort Port
+ {
+ get;
+ private set;
+ }
+ }
+}
--- /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;
+
+namespace Tizen.Applications.ComponentBased
+{
+ /// <summary>
+ /// Arguments for the event raised when the request is received.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public class RequestEventArgs : EventArgs
+ {
+ internal RequestEventArgs(string sender, object request, bool isReplyRequested)
+ {
+ Sender = sender;
+ Request = request;
+ IsReplyRequested = isReplyRequested;
+ Reply = null;
+ }
+
+ /// <summary>
+ /// The name of the sender port
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public string Sender
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The received serialized data.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public object Request
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The flag indicating whether the reply is requested or not.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public bool IsReplyRequested
+ {
+ get;
+ internal set;
+ }
+
+ /// <summary>
+ /// The serialized reply data.
+ /// </summary>
+ /// <since_tizen> 9 </since_tizen>
+ public object Reply
+ {
+ get;
+ set;
+ }
+ }
+}