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