Merge remote-tracking branch 'github/API4' into tizen_4.0
[platform/core/csapi/tizenfx.git] / src / Tizen.Messaging.Push / Tizen.Messaging.Push / PushImpl.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.Collections.Generic;
19 using System.Threading.Tasks;
20 using System.Runtime.InteropServices;
21 using Tizen;
22
23 namespace Tizen.Messaging.Push
24 {
25     internal class PushImpl
26     {
27         private static readonly object _lock = new object();
28         private static PushImpl _instance;
29         private static Interop.PushClient.VoidStateChangedCallback stateDelegate = null;
30                 private static Interop.PushClient.VoidNotifyCallback notifyDelegate = null;
31         private static Interop.PushClient.VoidResultCallback registerResult = null;
32         private static Interop.PushClient.VoidResultCallback unregisterResult = null;
33
34         internal static PushImpl Instance
35         {
36             get
37             {
38                 lock (_lock)
39                 {
40                     if (_instance == null)
41                     {
42                         Log.Info(Interop.PushClient.LogTag, "Creating New Instance");
43                         _instance = new PushImpl();
44                     }
45                     return _instance;
46                 }
47             }
48         }
49
50         internal PushImpl()
51         {
52             // Empty
53         }
54
55         private IntPtr _connection;
56
57         internal void PushServiceConnect(string pushAppId)
58         {
59             stateDelegate = (int state, string err, IntPtr userData) =>
60             {
61                 if (err == null)
62                 {
63                     err = "";
64                 }
65                 PushConnectionStateEventArgs args = new PushConnectionStateEventArgs((PushConnectionStateEventArgs.PushState)state, err);
66                 PushClient.StateChange(args);
67             };
68             notifyDelegate = (IntPtr notification, IntPtr userData) =>
69             {
70                 Interop.PushClient.ServiceError result;
71                 PushMessageEventArgs ob = new PushMessageEventArgs();
72                 string data;
73                 result = Interop.PushClient.GetNotificationData(notification, out data);
74                 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(data)))
75                 {
76                     ob.AppData = data;
77                 }
78                 else
79                 {
80                     ob.AppData = "";
81                 }
82                 string message;
83                 result = Interop.PushClient.GetNotificationMessage(notification, out message);
84                 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(message)))
85                 {
86                     ob.Message = message;
87                 }
88                 else
89                 {
90                     ob.Message = "";
91                 }
92                 string sender;
93                 result = Interop.PushClient.GetNotificationSender(notification, out sender);
94                 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(sender)))
95                 {
96                     ob.Sender = sender;
97                 }
98                 else
99                 {
100                     ob.Sender = "";
101                 }
102                 string sessioninfo;
103                 result = Interop.PushClient.GetNotificationSessionInfo(notification, out sessioninfo);
104                 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(sessioninfo)))
105                 {
106                     ob.SessionInfo = sessioninfo;
107                 }
108                 else
109                 {
110                     ob.SessionInfo = "";
111                 }
112                 string requestid;
113                 result = Interop.PushClient.GetNotificationRequestId(notification, out requestid);
114                 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(requestid)))
115                 {
116                     ob.RequestId = requestid;
117                 }
118                 else
119                 {
120                     ob.RequestId = "";
121                 }
122                 int time;
123                 result = Interop.PushClient.GetNotificationTime(notification, out time);
124                 DateTime utc;
125                 if ((result == Interop.PushClient.ServiceError.None) && (time != 0))
126                 {
127                     Log.Info(Interop.PushClient.LogTag, "Ticks received: " + time);
128                     utc = DateTime.SpecifyKind(new DateTime(1970, 1, 1).AddSeconds(time), DateTimeKind.Utc);
129                     ob.ReceivedAt = utc.ToLocalTime();
130                 }
131                 else
132                 {
133                     Log.Info(Interop.PushClient.LogTag, "No Date received");
134                     ob.ReceivedAt = DateTime.Now;
135                 }
136                 int type = -1;
137                 result = Interop.PushClient.GetNotificationType(notification, out type);
138                 if (result == Interop.PushClient.ServiceError.None)
139                 {
140                     ob.Type = type;
141                 }
142                 PushClient.Notify(ob);
143             };
144             Interop.PushClient.ServiceError connectResult = Interop.PushClient.ServiceConnect(pushAppId, stateDelegate, notifyDelegate, IntPtr.Zero, out _connection);
145             if (connectResult != Interop.PushClient.ServiceError.None)
146             {
147                 Log.Error(Interop.PushClient.LogTag, "Connect failed with " + connectResult);
148                 throw PushExceptionFactory.CreateResponseException(connectResult);
149             }
150         }
151
152         internal void PushServiceDisconnect()
153         {
154             Interop.PushClient.ServiceDisconnect(_connection);
155             Log.Info(Interop.PushClient.LogTag, "PushServiceDisconnect Completed");
156         }
157
158         internal async Task<ServerResponse> PushServerRegister()
159         {
160             Log.Info(Interop.PushClient.LogTag, "Register Called");
161             var task = new TaskCompletionSource<ServerResponse>();
162             if (registerResult != null)
163             {
164                 Log.Error(Interop.PushClient.LogTag, "Register callback was already registered with same callback");
165                 task.SetException(PushExceptionFactory.CreateResponseException(Interop.PushClient.ServiceError.OpearationFailed));
166                 return await task.Task;
167             }
168
169             registerResult = (Interop.PushClient.Result regResult, IntPtr msgPtr, IntPtr userData) =>
170             {
171                 Log.Info(Interop.PushClient.LogTag, "Register Callback Called with " + regResult);
172
173                 if (regResult < Interop.PushClient.Result.Success || regResult > Interop.PushClient.Result.SystemError)
174                 {
175                     Log.Error(Interop.PushClient.LogTag, "registerResult is called but has wrong resResult value");
176                     task.SetException(PushExceptionFactory.CreateResponseException(Interop.PushClient.ServiceError.OpearationFailed));
177                                 }
178                 else
179                 {
180                     string msg = "";
181                     if (msgPtr != IntPtr.Zero)
182                     {
183                         msg = Marshal.PtrToStringAnsi(msgPtr);
184                     }
185                     ServerResponse response = new ServerResponse();
186                     response.ServerResult = (ServerResponse.Result)regResult;
187                     response.ServerMessage = msg;
188                     if (task.TrySetResult(response) == false)
189                     {
190                         Log.Error(Interop.PushClient.LogTag, "Unable to set the Result for register");
191                     }
192                 }
193                 lock (_lock)
194                 {
195                     Log.Error(Interop.PushClient.LogTag, "resigterResult is unset");
196                     registerResult = null;
197                 }
198                 lock (_lock)
199                 {
200                     Log.Error(Interop.PushClient.LogTag, "resigterResult is unset");
201                     registerResult = null;
202                 }
203             };
204             Interop.PushClient.ServiceError result = Interop.PushClient.ServiceRegister(_connection, registerResult, IntPtr.Zero);
205             Log.Info(Interop.PushClient.LogTag, "Interop.PushClient.ServiceRegister Completed");
206             if (result != Interop.PushClient.ServiceError.None)
207             {
208                 Log.Error(Interop.PushClient.LogTag, "Register failed with " + result);
209                 task.SetException(PushExceptionFactory.CreateResponseException(result));
210                 lock (_lock)
211                 {
212                     Log.Error(Interop.PushClient.LogTag, "resigterResult is unset (failed)");
213                     registerResult = null;
214                 }
215             }
216             return await task.Task;
217         }
218
219         internal async Task<ServerResponse> PushServerUnregister()
220         {
221             var task = new TaskCompletionSource<ServerResponse>();
222             unregisterResult = (Interop.PushClient.Result regResult, IntPtr msgPtr, IntPtr userData) =>
223             {
224                 Log.Info(Interop.PushClient.LogTag, "Unregister Callback Called with " + regResult);
225
226                 if (regResult < Interop.PushClient.Result.Success || regResult > Interop.PushClient.Result.SystemError)
227                 {
228                     Log.Error(Interop.PushClient.LogTag, "unregisterResult is called but has wrong resResult value");
229                     task.SetException(PushExceptionFactory.CreateResponseException(Interop.PushClient.ServiceError.OpearationFailed));
230                 }
231                                 else
232                 {
233                     string msg = "";
234                     if (msgPtr != IntPtr.Zero)
235                     {
236                         msg = Marshal.PtrToStringAnsi(msgPtr);
237                     }
238                     ServerResponse response = new ServerResponse();
239                     response.ServerResult = (ServerResponse.Result)regResult;
240                     response.ServerMessage = msg;
241                     if (task.TrySetResult(response) == false)
242                     {
243                         Log.Error(Interop.PushClient.LogTag, "Unable to set the Result for Unregister");
244                     }
245                 }
246             };
247             Interop.PushClient.ServiceError result = Interop.PushClient.ServiceDeregister(_connection, unregisterResult, IntPtr.Zero);
248             if (result != Interop.PushClient.ServiceError.None)
249             {
250                 task.SetException(PushExceptionFactory.CreateResponseException(result));
251             }
252             return await task.Task;
253         }
254
255         internal string GetRegistrationId()
256         {
257             string regID = "";
258             Interop.PushClient.ServiceError result = Interop.PushClient.GetRegistrationId(_connection, out regID);
259             if (result != Interop.PushClient.ServiceError.None)
260             {
261                 throw PushExceptionFactory.CreateResponseException(result);
262             }
263             Log.Info(Interop.PushClient.LogTag, "Returning Reg Id: " + regID);
264             return regID;
265         }
266
267         internal void GetUnreadNotifications()
268         {
269             Interop.PushClient.ServiceError result = Interop.PushClient.RequestUnreadNotification(_connection);
270             if (result != Interop.PushClient.ServiceError.None)
271             {
272                 throw PushExceptionFactory.CreateResponseException(result);
273             }
274         }
275
276         internal static void Reset()
277         {
278             lock (_lock)
279             {
280                 Log.Info(Interop.PushClient.LogTag, "Making _instance as null");
281                 _instance = null;
282             }
283         }
284     }
285 }