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