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