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