Fix description (#3619)
[platform/core/csapi/tizenfx.git] / src / Tizen.Applications.Cion / Tizen.Applications.Cion / GroupBase.cs
1 /*
2  * Copyright (c) 2021 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
19 namespace Tizen.Applications.Cion
20 {
21     /// <summary>
22     /// An abstract class to represent cion group.
23     /// </summary>
24     /// <since_tizen> 9 </since_tizen>
25     public abstract class GroupBase : IDisposable
26     {
27         private readonly string LogTag = "Tizen.Applications.Cion";
28         private readonly GroupSafeHandle _handle;
29
30         private Interop.CionGroup.CionGroupPayloadReceivedCb _payloadReceivedCb;
31         private Interop.CionGroup.CionGroupLeftCb _leftCb;
32         private Interop.CionGroup.CionGroupJoinedCb _joinedCb;
33
34         /// <summary>
35         /// Gets the topic of current cion group.
36         /// </summary>
37         /// <since_tizen> 9 </since_tizen>
38         public string Topic { get; }
39
40         /// <summary>
41         /// The constructor of GroupBase class.
42         /// </summary>
43         /// <param name="topicName">The topic of group.</param>
44         /// <remarks>The maximum length of topic name is 512.</remarks>
45         /// <exception cref="ArgumentException">Thrown when the given topic name is too long.</exception>
46         /// <exception cref="InvalidOperationException">Thrown when there is not enough memory to continue the execution of the method.</exception>
47         /// <since_tizen> 9 </since_tizen>
48         public GroupBase(string topicName) : this(topicName, null) { }
49
50         /// <summary>
51         /// The constructor of GroupBase class.
52         /// </summary>
53         /// <param name="topicName">The topic of group.</param>
54         /// <param name="security">The security configuration.</param>
55         /// <remarks>The maximum length of topic name is 512.</remarks>
56         /// <exception cref="ArgumentException">Thrown when the given topic name is too long.</exception>
57         /// <exception cref="InvalidOperationException">Thrown when there is not enough memory to continue the execution of the method.</exception>
58         /// <since_tizen> 9 </since_tizen>
59         public GroupBase(string topicName, Cion.SecurityInfo security)
60         {
61             Topic = topicName;
62
63             Cion.SecuritySafeHandle handle = security?._handle;
64             Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupCreate(out _handle, topicName, handle?.DangerousGetHandle() ?? IntPtr.Zero);
65             if (ret != Interop.Cion.ErrorCode.None)
66             {
67                 throw CionErrorFactory.GetException(ret, "Failed to create group.");
68             }
69
70             _payloadReceivedCb = new Interop.CionGroup.CionGroupPayloadReceivedCb(
71                 (IntPtr group, IntPtr peerInfo, IntPtr payload, IntPtr userData) =>
72                 {
73                     Payload receivedPayload;
74                     Interop.CionPayload.CionPayloadGetType(payload, out Interop.CionPayload.PayloadType type);
75                     switch (type)
76                     {
77                         case Interop.CionPayload.PayloadType.Data:
78                             receivedPayload = new DataPayload(new PayloadSafeHandle(payload, false));
79                             break;
80                         case Interop.CionPayload.PayloadType.File:
81                             receivedPayload = new FilePayload(new PayloadSafeHandle(payload, false));
82                             break;
83                         default:
84                             Log.Error(LogTag, "Invalid payload type received.");
85                             return;
86                     }
87                     Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
88                     if (clone_ret != Interop.Cion.ErrorCode.None)
89                     {
90                         Log.Error(LogTag, "Failed to clone peer info.");
91                         return;
92                     }
93                     OnPayloadReceived(receivedPayload, new PeerInfo(clone));
94                 });
95             ret = Interop.CionGroup.CionGroupAddPayloadReceivedCb(_handle, _payloadReceivedCb, IntPtr.Zero);
96             if (ret != Interop.Cion.ErrorCode.None)
97             {
98                 _handle.Dispose();
99                 throw CionErrorFactory.GetException(ret, "Failed to add payload received callback.");
100             }
101
102             _joinedCb = new Interop.CionGroup.CionGroupJoinedCb(
103                 (string name, IntPtr peerInfo, IntPtr userData) =>
104                 {
105                     Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
106                     if (clone_ret != Interop.Cion.ErrorCode.None)
107                     {
108                         return;
109                     }
110                     OnJoined(new PeerInfo(clone));
111                 });
112             ret = Interop.CionGroup.CionGroupAddJoinedCb(_handle, _joinedCb, IntPtr.Zero);
113             if (ret != Interop.Cion.ErrorCode.None)
114             {
115                 _handle.Dispose();
116                 throw CionErrorFactory.GetException(ret, "Failed to add joined callback.");
117             }
118
119             _leftCb = new Interop.CionGroup.CionGroupLeftCb(
120                 (string name, IntPtr peerInfo, IntPtr userData) =>
121                 {
122                     Interop.Cion.ErrorCode clone_ret = Interop.CionPeerInfo.CionPeerInfoClone(peerInfo, out PeerInfoSafeHandle clone);
123                     if (clone_ret != Interop.Cion.ErrorCode.None)
124                     {
125                         return;
126                     }
127                     OnLeft(new PeerInfo(clone));
128                 });
129             ret = Interop.CionGroup.CionGroupAddLeftCb(_handle, _leftCb, IntPtr.Zero);
130             if (ret != Interop.Cion.ErrorCode.None)
131             {
132                 _handle.Dispose();
133                 throw CionErrorFactory.GetException(ret, "Failed to add joined callback.");
134             }
135         }
136
137         /// <summary>
138         /// Subscribes the topic.
139         /// </summary>
140         /// <privilege>http://tizen.org/privilege/d2d.datasharing</privilege>
141         /// <privilege>http://tizen.org/privilege/internet</privilege>
142         /// <privlevel>public</privlevel>
143         /// <exception cref="InvalidOperationException">Thrown when failed to subscribe.</exception>
144         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
145         /// <since_tizen> 9 </since_tizen>
146         public void Subscribe()
147         {
148             Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupSubscribe(_handle);
149             if (ret != Interop.Cion.ErrorCode.None)
150             {
151                 throw CionErrorFactory.GetException(ret, "Failed to subscribe.");
152             }
153         }
154
155         /// <summary>
156         /// Unsubscribes the topic.
157         /// </summary>
158         /// <since_tizen> 9 </since_tizen>
159         public void Unsubscribe()
160         {
161             Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupUnsubscribe(_handle);
162             if (ret != Interop.Cion.ErrorCode.None)
163             {
164                 Log.Error(LogTag, string.Format("Failed to unsubscribe: {0}", ret));
165             }
166         }
167
168         /// <summary>
169         /// Publishes payload to current group.
170         /// </summary>
171         /// <param name="payload">The payload to publish.</param>
172         /// <exception cref="ArgumentException">Thrown when the payload is invalid.</exception>
173         /// <exception cref="InvalidOperationException">Thrown when failed to publish.</exception>
174         /// <since_tizen> 9 </since_tizen>
175         public void Publish(Payload payload)
176         {
177             Interop.Cion.ErrorCode ret = Interop.CionGroup.CionGroupPublish(_handle, payload?._handle);
178             if (ret != Interop.Cion.ErrorCode.None)
179             {
180                 throw CionErrorFactory.GetException(ret, "Failed to publish payload.");
181             }
182         }
183
184         /// <summary>
185         /// The callback invoked when payload received.
186         /// </summary>
187         /// <since_tizen> 9 </since_tizen>
188         protected abstract void OnPayloadReceived(Payload payload, PeerInfo peer);
189
190         /// <summary>
191         /// The callback invoked when another peer joined in the current group.
192         /// </summary>
193         /// <param name="peerInfo">The peer info of joined in the current group.</param>
194         /// <since_tizen> 9 </since_tizen>
195         protected abstract void OnJoined(PeerInfo peerInfo);
196
197         /// <summary>
198         /// The callback invoked when another peer left from the current group.
199         /// </summary>
200         /// <param name="peerInfo">The peer info of left from the current group.</param>
201         /// <since_tizen> 9 </since_tizen>
202         protected abstract void OnLeft(PeerInfo peerInfo);
203
204         #region IDisposable Support
205         private bool disposedValue = false;
206
207         /// <summary>
208         /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
209         /// </summary>
210         /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
211         /// <since_tizen> 9 </since_tizen>
212         protected virtual void Dispose(bool disposing)
213         {
214             if (!disposedValue)
215             {
216                 if (disposing)
217                 {
218                     _handle.Dispose();
219                 }
220                 disposedValue = true;
221             }
222         }
223
224         /// <summary>
225         /// Releases all resources used by the GroupBase class.
226         /// </summary>
227         /// <since_tizen> 9 </since_tizen>
228         public void Dispose()
229         {
230             Dispose(true);
231             GC.SuppressFinalize(this);
232         }
233         #endregion
234     }
235 }