Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Convergence / Tizen.Convergence / InternalService.cs
1 /*
2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
3 *
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 using System;
18 using System.Runtime.InteropServices;
19 using System.ComponentModel;
20
21 namespace Tizen.Convergence
22 {
23     /// <summary>
24     /// The class abstracts the features provided by Tizen D2D Convergence.
25     /// </summary>
26     /// <seealso cref="AppCommunicationService"/>
27     [EditorBrowsable(EditorBrowsableState.Never)]
28     public abstract class InternalService : IDisposable
29     {
30         internal Interop.Internal.ConvServiceHandle _serviceHandle;
31         internal const string ServiceIdKey = "service_id";
32         internal const string ServiceVersionKey = "service_version";
33
34         private event EventHandler<InternalServiceEventOccuredEventArgs> _serviceEventOccured;
35
36         internal InternalService(Interop.Internal.ServiceType type)
37         {
38             int ret = Interop.Internal.ConvService.Create(out _serviceHandle);
39             if (ret != (int)ConvErrorCode.None)
40             {
41                 Log.Error(ErrorFactory.LogTag, "Failed to create service handle");
42                 throw ErrorFactory.GetException(ret);
43             }
44
45             ret = Interop.Internal.ConvService.SetType(_serviceHandle, (int)type);
46             if (ret != (int)ConvErrorCode.None)
47             {
48                 Log.Error(ErrorFactory.LogTag, "Failed to create service handle");
49                 throw ErrorFactory.GetException(ret);
50             }
51         }
52
53         internal InternalService(IntPtr existingServiceHandle)
54         {
55             int ret = Interop.Internal.ConvService.Clone(existingServiceHandle, out _serviceHandle);
56             if (ret != (int)ConvErrorCode.None)
57             {
58                 Log.Error(ErrorFactory.LogTag, "Failed to clone device");
59                 throw ErrorFactory.GetException(ret);
60             }
61
62             IntPtr stringPtr = IntPtr.Zero;
63             ret = Interop.Internal.ConvService.GetPropertyString(_serviceHandle, ServiceIdKey, out stringPtr);
64             if (ret != (int)ConvErrorCode.None)
65             {
66                 Log.Error(ErrorFactory.LogTag, "Failed to get service Id");
67                 throw ErrorFactory.GetException(ret);
68             }
69
70             Id = Marshal.PtrToStringAnsi(stringPtr);
71             Interop.Libc.Free(stringPtr);
72
73             ret = Interop.Internal.ConvService.GetPropertyString(_serviceHandle, ServiceVersionKey, out stringPtr);
74             if (ret != (int)ConvErrorCode.None)
75             {
76                 Log.Error(ErrorFactory.LogTag, "Failed to get service version");
77                 throw ErrorFactory.GetException(ret);
78             }
79
80             Version = Marshal.PtrToStringAnsi(stringPtr);
81             Interop.Libc.Free(stringPtr);
82         }
83
84         /// <summary>
85         /// The ID of the service
86         /// </summary>
87         public string Id { get; }
88
89         /// <summary>
90         /// The Version of the service
91         /// </summary>
92         public string Version { get; }
93
94         /// <summary>
95         /// The event handler for Service Events(Start/Publish/Read/Stop)
96         /// </summary>
97         public event EventHandler<InternalServiceEventOccuredEventArgs> ServiceEventOccurred
98         {
99             add
100             {
101                 if (_serviceEventOccured == null)
102                 {
103                     RegisterServiceEventListener();
104                 }
105                 _serviceEventOccured += value;
106             }
107             remove
108             {
109                 _serviceEventOccured -= value;
110                 if (_serviceEventOccured == null)
111                 {
112                     UnregisterServiceEventListener();
113                 }
114             }
115         }
116
117         /// <summary>
118         /// The event handler for service error events
119         /// </summary>
120         public event EventHandler<InternalServiceErrorOccuredEventArgs> ServiceErrorOccured;
121
122         /// <summary>
123         /// The dispose method
124         /// </summary>
125         public void Dispose()
126         {
127             _serviceHandle.Dispose();
128         }
129
130         internal static InternalService GetService(IntPtr serviceHandle)
131         {
132             InternalService service = null;
133             int serviceType;
134             int ret = Interop.Internal.ConvService.GetType(serviceHandle, out serviceType);
135             if (ret != (int)ConvErrorCode.None)
136             {
137                 Log.Error(ErrorFactory.LogTag, "Failed to get service version");
138                 throw ErrorFactory.GetException(ret);
139             }
140             if (serviceType == (int)Interop.Internal.ServiceType.AppCommunication)
141             {
142                 service = new InternalAppCommunicationService(serviceHandle);
143             }
144
145             return service;
146         }
147
148         private void RegisterServiceEventListener()
149         {
150             int ret = Interop.Internal.ConvService.SetListenerCb(_serviceHandle, serviceEventsCb, IntPtr.Zero);
151             if (ret != (int)ConvErrorCode.None)
152             {
153                 Log.Error(ErrorFactory.LogTag, "Failed to set listener for service events");
154                 throw ErrorFactory.GetException(ret);
155             }
156         }
157
158         private void UnregisterServiceEventListener()
159         {
160             int ret = Interop.Internal.ConvService.UnsetListenerCb(_serviceHandle);
161             if (ret != (int)ConvErrorCode.None)
162             {
163                 Log.Error(ErrorFactory.LogTag, "Failed to unset listener for service events");
164                 throw ErrorFactory.GetException(ret);
165             }
166         }
167
168         private void serviceEventsCb(IntPtr serviceHandle, IntPtr channelHandle, int error, IntPtr resultPayloadHandle, IntPtr userData)
169         {
170             Log.Debug(ErrorFactory.LogTag, "service event occured. error code :[" + error + "]");
171
172             if (error == (int)ConvErrorCode.None)
173             {
174                 var channel = (channelHandle == IntPtr.Zero) ? null : new InternalChannel(channelHandle);
175                 var payload = (resultPayloadHandle == IntPtr.Zero) ? null : new InternalPayload(resultPayloadHandle);
176                 _serviceEventOccured?.Invoke(this, new InternalServiceEventOccuredEventArgs()
177                 {
178                     Payload = payload,
179                     Channel = channel
180                 });
181             }
182             else
183             {
184                 var eventArgs = new InternalServiceErrorOccuredEventArgs()
185                 {
186                     Exception = ErrorFactory.GetException(error)
187                 };
188                 ServiceErrorOccured?.Invoke(this, eventArgs);
189             }
190         }
191     }
192 }