Release 4.0.0-preview1-00051
[platform/core/csapi/tizenfx.git] / src / Tizen.Applications.NotificationEventListener / Tizen.Applications.NotificationEventListener / NotificationListenerManager.cs
1 /*
2  * Copyright (c) 2017 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 namespace Tizen.Applications.NotificationEventListener
18 {
19     using System;
20     using System.Collections.Generic;
21     using System.ComponentModel;
22     using System.Runtime.InteropServices;
23
24     /// <summary>
25     /// This class provides a way to register callback function for some notification events.
26     /// </summary>
27     /// <remarks>
28     /// The event listener can use this class to get a list of notification or to clear notifications.
29     /// </remarks>
30     public partial class NotificationListenerManager
31     {
32         private const string LogTag = "Tizen.Applications.NotificationEventListener";
33
34         private static event EventHandler<NotificationEventArgs> AddEventHandler;
35
36         private static event EventHandler<NotificationEventArgs> UpdateEventHandler;
37
38         private static event EventHandler<NotificationDeleteEventArgs> DeleteEventHandler;
39
40         private static Interop.NotificationEventListener.ChangedCallback callback;
41
42         [StructLayout(LayoutKind.Sequential)]
43         private struct NotificationOperation
44         {
45             NotificationOperationType type;
46             int uniqueNumber;
47             int extraInformation1;
48             int extraInformation2;
49             IntPtr notification;
50         }
51
52         private static int GetEventHandleLength()
53         {
54             int length = 0;
55
56             length += (DeleteEventHandler == null) ? 0 : DeleteEventHandler.GetInvocationList().Length;
57             length += (UpdateEventHandler == null) ? 0 : UpdateEventHandler.GetInvocationList().Length;
58             length += (AddEventHandler == null) ? 0 : AddEventHandler.GetInvocationList().Length;
59
60             return length;
61         }
62
63         /// <summary>
64         /// Registers a callback for notification insert event.
65         /// </summary>
66         /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
67         /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
68         /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
69         /// <privilege>http://tizen.org/privilege/notification</privilege>
70         public static event EventHandler<NotificationEventArgs> NotificationAddEventHandler
71         {
72             add
73             {
74                 if (callback == null)
75                 {
76                     callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent);
77                 }
78
79                 if (GetEventHandleLength() == 0)
80                 {
81                     Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero);
82                     if (err != (int)Interop.NotificationEventListener.ErrorCode.None)
83                     {
84                         throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback");
85                     }
86                 }
87
88                 AddEventHandler += value;
89             }
90
91             remove
92             {
93                 if (AddEventHandler != null && AddEventHandler.GetInvocationList().Length > 0)
94                 {
95                     AddEventHandler -= value;
96
97                     if (GetEventHandleLength() == 0)
98                     {
99                         Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback);
100                         if (err != (int)Interop.NotificationEventListener.ErrorCode.None)
101                         {
102                             throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback");
103                         }
104                     }
105                 }
106             }
107         }
108
109         /// <summary>
110         /// Registers a callback for notification update event.
111         /// </summary>
112         /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
113         /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
114         /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
115         /// <privilege>http://tizen.org/privilege/notification</privilege>
116         public static event EventHandler<NotificationEventArgs> NotificationUpdateEventHandler
117         {
118             add
119             {
120                 if (callback == null)
121                 {
122                     callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent);
123                 }
124
125                 if (GetEventHandleLength() == 0)
126                 {
127                     Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero);
128                     if (err != Interop.NotificationEventListener.ErrorCode.None)
129                     {
130                         throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback");
131                     }
132                 }
133
134                 UpdateEventHandler += value;
135             }
136
137             remove
138             {
139                 if (UpdateEventHandler != null && UpdateEventHandler.GetInvocationList().Length > 0)
140                 {
141                     UpdateEventHandler -= value;
142
143                     if (GetEventHandleLength() == 0)
144                     {
145                         Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback);
146                         if (err != Interop.NotificationEventListener.ErrorCode.None)
147                         {
148                             throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback");
149                         }
150                     }
151                 }
152             }
153         }
154
155         /// <summary>
156         /// Registers a callback for notification delete event.
157         /// </summary>
158         /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
159         /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
160         /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
161         /// <privilege>http://tizen.org/privilege/notification</privilege>
162         public static event EventHandler<NotificationDeleteEventArgs> NotificationDeleteEventHandler
163         {
164             add
165             {
166                 if (callback == null)
167                 {
168                     callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent);
169                 }
170
171                 if (GetEventHandleLength() == 0)
172                 {
173                     Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero);
174                     if (err != Interop.NotificationEventListener.ErrorCode.None)
175                     {
176                         throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback");
177                     }
178                 }
179
180                 DeleteEventHandler += value;
181             }
182
183             remove
184             {
185                 if (DeleteEventHandler != null && DeleteEventHandler.GetInvocationList().Length > 0)
186                 {
187                     DeleteEventHandler -= value;
188
189                     if (GetEventHandleLength() == 0)
190                     {
191                         Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback);
192                         if (err != Interop.NotificationEventListener.ErrorCode.None)
193                         {
194                             throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback");
195                         }
196                     }
197                 }
198             }
199         }
200
201         private static void ChangedEvent(IntPtr userData, NotificationType type, IntPtr operationList, int num)
202         {
203             IntPtr operationType;
204             IntPtr uniqueNumber;
205             IntPtr notification;
206
207             NotificationEventArgs eventargs;
208             NotificationDeleteEventArgs deleteargs;
209
210             for (int i = 0; i < num; i++)
211             {
212                 uniqueNumber = IntPtr.Zero;
213                 operationType = IntPtr.Zero;
214                 notification = IntPtr.Zero;
215
216                 Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf<NotificationOperation>()), NotificationOperationDataType.Type, out operationType);
217                 Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf<NotificationOperation>()), NotificationOperationDataType.UniqueNumber, out uniqueNumber);
218                 Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf<NotificationOperation>()), NotificationOperationDataType.Notification, out notification);
219
220                 if (operationType == IntPtr.Zero)
221                 {
222                     Log.Error(LogTag, "unable to get operationType");
223                     continue;
224                 }
225
226                 Log.Info(LogTag, "type : " + ((int)operationType).ToString());
227                 Log.Info(LogTag, "Add : " + (AddEventHandler == null ? "0" : AddEventHandler.GetInvocationList().Length.ToString()));
228                 Log.Info(LogTag, "update: " + (UpdateEventHandler == null ? "0" : UpdateEventHandler.GetInvocationList().Length.ToString()));
229                 Log.Info(LogTag, "delete : " + (DeleteEventHandler == null ? "0" : DeleteEventHandler.GetInvocationList().Length.ToString()));
230
231                 switch ((int)operationType)
232                 {
233                     case (int)NotificationOperationType.Insert:
234                         if (notification != IntPtr.Zero)
235                         {
236                             try
237                             {
238                                 eventargs = NotificationEventArgsBinder.BindObject(notification, false);
239                                 AddEventHandler?.Invoke(null, eventargs);
240                             }
241                             catch (Exception e)
242                             {
243                                 Log.Error(LogTag, e.Message);
244                             }
245                         }
246
247                         break;
248
249                     case (int)NotificationOperationType.Update:
250                         if (notification != IntPtr.Zero)
251                         {
252                             try
253                             {
254                                 eventargs = NotificationEventArgsBinder.BindObject(notification, false);
255                                 UpdateEventHandler?.Invoke(null, eventargs);
256                             }
257                             catch (Exception e)
258                             {
259                                 Log.Error(LogTag, e.Message);
260                             }
261                         }
262
263                         break;
264
265                     case (int)NotificationOperationType.Delete:
266                         if (uniqueNumber != IntPtr.Zero)
267                         {
268                             try
269                             {
270                                 deleteargs = NotificationDeleteEventArgsBinder.BindObject((int)uniqueNumber);
271                                 DeleteEventHandler?.Invoke(null, deleteargs);
272                             }
273                             catch (Exception e)
274                             {
275                                 Log.Error(LogTag, e.Message);
276                             }
277                         }
278
279                         break;
280
281                     default:
282                         Log.Info(LogTag, "Event : " + (int)operationType);
283                         break;
284                 }
285             }
286         }
287
288         /// <summary>
289         /// Deletes a Notification with appId and uniqueNumber.
290         /// </summary>
291         /// <param name="appId">The name of the application you want to delete.</param>
292         /// <param name="uniqueNumber">The unique number of the notification.</param>
293         /// <exception cref="ArgumentException">Thrown in case of Invalid parameter.</exception>
294         /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
295         /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
296         /// <privilege>http://tizen.org/privilege/notification</privilege>
297         public static void Delete(string appId, int uniqueNumber)
298         {
299             Interop.NotificationEventListener.ErrorCode err;
300
301             if (string.IsNullOrEmpty(appId) || uniqueNumber < 0)
302             {
303                 throw NotificationEventListenerErrorFactory.GetException(Interop.NotificationEventListener.ErrorCode.InvalidParameter, "invalid parameter");
304             }
305
306             err = Interop.NotificationEventListener.Delete(appId, 0, uniqueNumber);
307             if (err != Interop.NotificationEventListener.ErrorCode.None)
308             {
309                 throw NotificationEventListenerErrorFactory.GetException(err, "unable to delete");
310             }
311         }
312
313         /// <summary>
314         /// Deletes all Notification.
315         /// </summary>
316         /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
317         /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
318         /// <privilege>http://tizen.org/privilege/notification</privilege>
319         public static void DeleteAll()
320         {
321             Interop.NotificationEventListener.ErrorCode err;
322
323             err = Interop.NotificationEventListener.DeleteAll((int)NotificationType.Notification);
324             if (err != Interop.NotificationEventListener.ErrorCode.None)
325             {
326                 throw NotificationEventListenerErrorFactory.GetException(err, "delete all notifications failed of Noti type");
327             }
328
329             err = Interop.NotificationEventListener.DeleteAll((int)NotificationType.Ongoing);
330             if (err != Interop.NotificationEventListener.ErrorCode.None)
331             {
332                 throw NotificationEventListenerErrorFactory.GetException(err, "delete all notifications failed of Ongoing type");
333             }
334         }
335
336         /// <summary>
337         /// Returns the notification list handle.
338         /// </summary>
339         /// <exception cref="UnauthorizedAccessException"> Thrown in case of Permission deny.</exception>
340         /// <exception cref="InvalidOperationException">Thrown in case of any internal error.</exception>
341         /// <privilege>http://tizen.org/privilege/notification</privilege>
342         public static IList<NotificationEventArgs> GetList()
343         {
344             Interop.NotificationEventListener.ErrorCode err;
345             IntPtr notificationList = IntPtr.Zero;
346             IntPtr currentList = IntPtr.Zero;
347             IList<NotificationEventArgs> list = new List<NotificationEventArgs>();
348
349             err = Interop.NotificationEventListener.GetList(NotificationType.Notification, -1, out notificationList);
350             if (err != Interop.NotificationEventListener.ErrorCode.None)
351             {
352                 throw NotificationEventListenerErrorFactory.GetException(err, "unable to get notification list");
353             }
354
355             if (notificationList != IntPtr.Zero)
356             {
357                 currentList = notificationList;
358                 while (currentList != IntPtr.Zero)
359                 {
360                     IntPtr notification;
361                     NotificationEventArgs eventargs = new NotificationEventArgs();
362
363                     notification = Interop.NotificationEventListener.GetData(currentList);
364
365                     eventargs = NotificationEventArgsBinder.BindObject(notification, false);
366
367                     list.Add(eventargs);
368
369                     currentList = Interop.NotificationEventListener.GetNext(currentList);
370                 }
371
372                 Interop.NotificationEventListener.NotificationListFree(notificationList);
373                 notificationList = IntPtr.Zero;
374             }
375
376             err = Interop.NotificationEventListener.GetList(NotificationType.Ongoing, -1, out notificationList);
377             if (err != Interop.NotificationEventListener.ErrorCode.None)
378             {
379                 throw NotificationEventListenerErrorFactory.GetException(err, "unable to get notification list");
380             }
381
382             if (notificationList != IntPtr.Zero)
383             {
384                 currentList = notificationList;
385                 while (currentList != IntPtr.Zero)
386                 {
387                     IntPtr notification;
388                     NotificationEventArgs eventargs = new NotificationEventArgs();
389
390                     notification = Interop.NotificationEventListener.GetData(currentList);
391
392                     eventargs = NotificationEventArgsBinder.BindObject(notification, false);
393
394                     list.Add(eventargs);
395
396                     currentList = Interop.NotificationEventListener.GetNext(currentList);
397                 }
398
399                 Interop.NotificationEventListener.NotificationListFree(notificationList);
400             }
401
402             return list;
403         }
404
405         [EditorBrowsable(EditorBrowsableState.Never)]
406         public static void SendEvent(int uniqueNumber, UserEventType type)
407         {
408             Interop.NotificationEventListener.ErrorCode err;
409
410             err = Interop.NotificationEventListener.SendEvent(uniqueNumber, (int)type);
411             if (err != Interop.NotificationEventListener.ErrorCode.None)
412             {
413                 throw NotificationEventListenerErrorFactory.GetException(err, "failed to send event");
414             }
415         }
416     }
417 }