2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using System.Threading.Tasks;
20 using System.Runtime.InteropServices;
23 namespace Tizen.Messaging.Push
25 internal class PushImpl
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;
34 internal static PushImpl Instance
40 if (_instance == null)
42 Log.Info(Interop.PushClient.LogTag, "Creating New Instance");
43 _instance = new PushImpl();
55 private IntPtr _connection;
57 internal void PushServiceConnect(string pushAppId)
59 stateDelegate = (int state, string err, IntPtr userData) =>
65 PushConnectionStateEventArgs args = new PushConnectionStateEventArgs((PushConnectionStateEventArgs.PushState)state, err);
66 PushClient.StateChange(args);
68 notifyDelegate = (IntPtr notification, IntPtr userData) =>
70 Interop.PushClient.ServiceError result;
71 PushMessageEventArgs ob = new PushMessageEventArgs();
73 result = Interop.PushClient.GetNotificationData(notification, out data);
74 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(data)))
83 result = Interop.PushClient.GetNotificationMessage(notification, out message);
84 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(message)))
93 result = Interop.PushClient.GetNotificationSender(notification, out sender);
94 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(sender)))
103 result = Interop.PushClient.GetNotificationSessionInfo(notification, out sessioninfo);
104 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(sessioninfo)))
106 ob.SessionInfo = sessioninfo;
113 result = Interop.PushClient.GetNotificationRequestId(notification, out requestid);
114 if ((result == Interop.PushClient.ServiceError.None) && !(String.IsNullOrEmpty(requestid)))
116 ob.RequestId = requestid;
123 result = Interop.PushClient.GetNotificationTime(notification, out time);
125 if ((result == Interop.PushClient.ServiceError.None) && (time != 0))
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();
133 Log.Info(Interop.PushClient.LogTag, "No Date received");
134 ob.ReceivedAt = DateTime.Now;
137 result = Interop.PushClient.GetNotificationType(notification, out type);
138 if (result == Interop.PushClient.ServiceError.None)
142 PushClient.Notify(ob);
144 Interop.PushClient.ServiceError connectResult = Interop.PushClient.ServiceConnect(pushAppId, stateDelegate, notifyDelegate, IntPtr.Zero, out _connection);
145 if (connectResult != Interop.PushClient.ServiceError.None)
147 Log.Error(Interop.PushClient.LogTag, "Connect failed with " + connectResult);
148 throw PushExceptionFactory.CreateResponseException(connectResult);
152 internal void PushServiceDisconnect()
154 Interop.PushClient.ServiceDisconnect(_connection);
155 Log.Info(Interop.PushClient.LogTag, "PushServiceDisconnect Completed");
158 internal async Task<ServerResponse> PushServerRegister()
160 Log.Info(Interop.PushClient.LogTag, "Register Called");
161 var task = new TaskCompletionSource<ServerResponse>();
162 if (registerResult != null)
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;
169 registerResult = (Interop.PushClient.Result regResult, IntPtr msgPtr, IntPtr userData) =>
171 Log.Info(Interop.PushClient.LogTag, "Register Callback Called with " + regResult);
173 if (regResult < Interop.PushClient.Result.Success || regResult > Interop.PushClient.Result.SystemError)
175 Log.Error(Interop.PushClient.LogTag, "registerResult is called but has wrong resResult value");
176 task.SetException(PushExceptionFactory.CreateResponseException(Interop.PushClient.ServiceError.OpearationFailed));
181 if (msgPtr != IntPtr.Zero)
183 msg = Marshal.PtrToStringAnsi(msgPtr);
185 ServerResponse response = new ServerResponse();
186 response.ServerResult = (ServerResponse.Result)regResult;
187 response.ServerMessage = msg;
188 if (task.TrySetResult(response) == false)
190 Log.Error(Interop.PushClient.LogTag, "Unable to set the Result for register");
195 Log.Error(Interop.PushClient.LogTag, "resigterResult is unset");
196 registerResult = null;
200 Log.Error(Interop.PushClient.LogTag, "resigterResult is unset");
201 registerResult = null;
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)
208 Log.Error(Interop.PushClient.LogTag, "Register failed with " + result);
209 task.SetException(PushExceptionFactory.CreateResponseException(result));
212 Log.Error(Interop.PushClient.LogTag, "resigterResult is unset (failed)");
213 registerResult = null;
216 return await task.Task;
219 internal async Task<ServerResponse> PushServerUnregister()
221 var task = new TaskCompletionSource<ServerResponse>();
222 unregisterResult = (Interop.PushClient.Result regResult, IntPtr msgPtr, IntPtr userData) =>
224 Log.Info(Interop.PushClient.LogTag, "Unregister Callback Called with " + regResult);
226 if (regResult < Interop.PushClient.Result.Success || regResult > Interop.PushClient.Result.SystemError)
228 Log.Error(Interop.PushClient.LogTag, "unregisterResult is called but has wrong resResult value");
229 task.SetException(PushExceptionFactory.CreateResponseException(Interop.PushClient.ServiceError.OpearationFailed));
234 if (msgPtr != IntPtr.Zero)
236 msg = Marshal.PtrToStringAnsi(msgPtr);
238 ServerResponse response = new ServerResponse();
239 response.ServerResult = (ServerResponse.Result)regResult;
240 response.ServerMessage = msg;
241 if (task.TrySetResult(response) == false)
243 Log.Error(Interop.PushClient.LogTag, "Unable to set the Result for Unregister");
247 Interop.PushClient.ServiceError result = Interop.PushClient.ServiceDeregister(_connection, unregisterResult, IntPtr.Zero);
248 if (result != Interop.PushClient.ServiceError.None)
250 task.SetException(PushExceptionFactory.CreateResponseException(result));
252 return await task.Task;
255 internal string GetRegistrationId()
258 Interop.PushClient.ServiceError result = Interop.PushClient.GetRegistrationId(_connection, out regID);
259 if (result != Interop.PushClient.ServiceError.None)
261 throw PushExceptionFactory.CreateResponseException(result);
263 Log.Info(Interop.PushClient.LogTag, "Returning Reg Id: " + regID);
267 internal void GetUnreadNotifications()
269 Interop.PushClient.ServiceError result = Interop.PushClient.RequestUnreadNotification(_connection);
270 if (result != Interop.PushClient.ServiceError.None)
272 throw PushExceptionFactory.CreateResponseException(result);
276 internal static void Reset()
280 Log.Info(Interop.PushClient.LogTag, "Making _instance as null");