Fix BoxReomve issue (#240)
[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             };
199             Interop.PushClient.ServiceError result = Interop.PushClient.ServiceRegister(_connection, registerResult, IntPtr.Zero);
200             Log.Info(Interop.PushClient.LogTag, "Interop.PushClient.ServiceRegister Completed");
201             if (result != Interop.PushClient.ServiceError.None)
202             {
203                 Log.Error(Interop.PushClient.LogTag, "Register failed with " + result);
204                 task.SetException(PushExceptionFactory.CreateResponseException(result));
205                 lock (_lock)
206                 {
207                     Log.Error(Interop.PushClient.LogTag, "resigterResult is unset (failed)");
208                     registerResult = null;
209                 }
210             }
211             return await task.Task;
212         }
213
214         internal async Task<ServerResponse> PushServerUnregister()
215         {
216             var task = new TaskCompletionSource<ServerResponse>();
217             unregisterResult = (Interop.PushClient.Result regResult, IntPtr msgPtr, IntPtr userData) =>
218             {
219                 Log.Info(Interop.PushClient.LogTag, "Unregister Callback Called with " + regResult);
220
221                 if (regResult < Interop.PushClient.Result.Success || regResult > Interop.PushClient.Result.SystemError)
222                 {
223                     Log.Error(Interop.PushClient.LogTag, "unregisterResult is called but has wrong resResult value");
224                     task.SetException(PushExceptionFactory.CreateResponseException(Interop.PushClient.ServiceError.OpearationFailed));
225                 }
226                                 else
227                 {
228                     string msg = "";
229                     if (msgPtr != IntPtr.Zero)
230                     {
231                         msg = Marshal.PtrToStringAnsi(msgPtr);
232                     }
233                     ServerResponse response = new ServerResponse();
234                     response.ServerResult = (ServerResponse.Result)regResult;
235                     response.ServerMessage = msg;
236                     if (task.TrySetResult(response) == false)
237                     {
238                         Log.Error(Interop.PushClient.LogTag, "Unable to set the Result for Unregister");
239                     }
240                 }
241             };
242             Interop.PushClient.ServiceError result = Interop.PushClient.ServiceDeregister(_connection, unregisterResult, IntPtr.Zero);
243             if (result != Interop.PushClient.ServiceError.None)
244             {
245                 task.SetException(PushExceptionFactory.CreateResponseException(result));
246             }
247             return await task.Task;
248         }
249
250         internal string GetRegistrationId()
251         {
252             string regID = "";
253             Interop.PushClient.ServiceError result = Interop.PushClient.GetRegistrationId(_connection, out regID);
254             if (result != Interop.PushClient.ServiceError.None)
255             {
256                 throw PushExceptionFactory.CreateResponseException(result);
257             }
258             Log.Info(Interop.PushClient.LogTag, "Returning Reg Id: " + regID);
259             return regID;
260         }
261
262         internal void GetUnreadNotifications()
263         {
264             Interop.PushClient.ServiceError result = Interop.PushClient.RequestUnreadNotification(_connection);
265             if (result != Interop.PushClient.ServiceError.None)
266             {
267                 throw PushExceptionFactory.CreateResponseException(result);
268             }
269         }
270
271         internal static void Reset()
272         {
273             lock (_lock)
274             {
275                 Log.Info(Interop.PushClient.LogTag, "Making _instance as null");
276                 _instance = null;
277             }
278         }
279     }
280 }