/* * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved * * Licensed under the Apache License, Version 2.0 (the License); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an AS IS BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ namespace Tizen.Applications.NotificationEventListener { using System; using System.Collections.Generic; using System.ComponentModel; using System.Runtime.InteropServices; /// /// This class provides a way to register callback function for some notification events. /// /// /// The event listener can use this class to get a list of notifications or to clear notifications. /// public partial class NotificationListenerManager { private const string LogTag = "Tizen.Applications.NotificationEventListener"; private static event EventHandler AddEventHandler; private static event EventHandler UpdateEventHandler; private static event EventHandler DeleteEventHandler; private static Interop.NotificationEventListener.ChangedCallback callback; [StructLayout(LayoutKind.Sequential)] private struct NotificationOperation { NotificationOperationType type; int uniqueNumber; int extraInformation1; int extraInformation2; IntPtr notification; } private static int GetEventHandleLength() { int length = 0; length += (DeleteEventHandler == null) ? 0 : DeleteEventHandler.GetInvocationList().Length; length += (UpdateEventHandler == null) ? 0 : UpdateEventHandler.GetInvocationList().Length; length += (AddEventHandler == null) ? 0 : AddEventHandler.GetInvocationList().Length; return length; } /// /// Event handler for notification insert event. /// /// Thrown in case of an invalid parameter. /// Thrown in case of a permission is denied. /// Thrown in case of any internal error. /// http://tizen.org/privilege/notification public static event EventHandler Added { add { if (callback == null) { callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent); } if (GetEventHandleLength() == 0) { Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero); if (err != (int)Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback"); } } AddEventHandler += value; } remove { if (AddEventHandler != null && AddEventHandler.GetInvocationList().Length > 0) { AddEventHandler -= value; if (GetEventHandleLength() == 0) { Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback); if (err != (int)Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback"); } } } } } /// /// Event handler for notification update event. /// /// Thrown in case of an invalid parameter. /// Thrown in case of a permission is denied. /// Thrown in case of any internal error. /// http://tizen.org/privilege/notification public static event EventHandler Updated { add { if (callback == null) { callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent); } if (GetEventHandleLength() == 0) { Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback"); } } UpdateEventHandler += value; } remove { if (UpdateEventHandler != null && UpdateEventHandler.GetInvocationList().Length > 0) { UpdateEventHandler -= value; if (GetEventHandleLength() == 0) { Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback"); } } } } } /// /// Event handler for notification delete event. /// /// Thrown in case of an invalid parameter. /// Thrown in case of a permission is denied. /// Thrown in case of any internal error. /// http://tizen.org/privilege/notification public static event EventHandler Deleted { add { if (callback == null) { callback = new Interop.NotificationEventListener.ChangedCallback(ChangedEvent); } if (GetEventHandleLength() == 0) { Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.SetChangedCallback(callback, IntPtr.Zero); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to set changed callback"); } } DeleteEventHandler += value; } remove { if (DeleteEventHandler != null && DeleteEventHandler.GetInvocationList().Length > 0) { DeleteEventHandler -= value; if (GetEventHandleLength() == 0) { Interop.NotificationEventListener.ErrorCode err = Interop.NotificationEventListener.UnsetChangedCallback(callback); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to unset changed callback"); } } } } } private static void ChangedEvent(IntPtr userData, NotificationType type, IntPtr operationList, int num) { IntPtr operationType; IntPtr uniqueNumber; IntPtr notification; NotificationEventArgs eventargs; NotificationDeleteEventArgs deleteargs; for (int i = 0; i < num; i++) { uniqueNumber = IntPtr.Zero; operationType = IntPtr.Zero; notification = IntPtr.Zero; Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf()), NotificationOperationDataType.Type, out operationType); Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf()), NotificationOperationDataType.UniqueNumber, out uniqueNumber); Interop.NotificationEventListener.GetOperationData(operationList + (i * Marshal.SizeOf()), NotificationOperationDataType.Notification, out notification); if (operationType == IntPtr.Zero) { Log.Error(LogTag, "unable to get operationType"); continue; } Log.Info(LogTag, "type : " + ((int)operationType).ToString()); Log.Info(LogTag, "Add : " + (AddEventHandler == null ? "0" : AddEventHandler.GetInvocationList().Length.ToString())); Log.Info(LogTag, "update: " + (UpdateEventHandler == null ? "0" : UpdateEventHandler.GetInvocationList().Length.ToString())); Log.Info(LogTag, "delete : " + (DeleteEventHandler == null ? "0" : DeleteEventHandler.GetInvocationList().Length.ToString())); switch ((int)operationType) { case (int)NotificationOperationType.Insert: if (notification != IntPtr.Zero) { try { eventargs = NotificationEventArgsBinder.BindObject(notification, false); AddEventHandler?.Invoke(null, eventargs); } catch (Exception e) { Log.Error(LogTag, e.Message); } } break; case (int)NotificationOperationType.Update: if (notification != IntPtr.Zero) { try { eventargs = NotificationEventArgsBinder.BindObject(notification, false); UpdateEventHandler?.Invoke(null, eventargs); } catch (Exception e) { Log.Error(LogTag, e.Message); } } break; case (int)NotificationOperationType.Delete: if (uniqueNumber != IntPtr.Zero) { try { deleteargs = NotificationDeleteEventArgsBinder.BindObject((int)uniqueNumber); DeleteEventHandler?.Invoke(null, deleteargs); } catch (Exception e) { Log.Error(LogTag, e.Message); } } break; default: Log.Info(LogTag, "Event : " + (int)operationType); break; } } } /// /// Deletes a notification with appId and uniqueNumber. /// /// The name of the application you want to delete. /// The unique number of the notification. /// Thrown in case of an invalid parameter. /// Thrown in case of a permission is denied. /// Thrown in case of any internal error. /// http://tizen.org/privilege/notification public static void Delete(string appId, int uniqueNumber) { Interop.NotificationEventListener.ErrorCode err; if (string.IsNullOrEmpty(appId) || uniqueNumber < 0) { throw NotificationEventListenerErrorFactory.GetException(Interop.NotificationEventListener.ErrorCode.InvalidParameter, "invalid parameter"); } err = Interop.NotificationEventListener.Delete(appId, 0, uniqueNumber); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to delete"); } } /// /// Deletes all notifications. /// /// Thrown in case of a permission is denied. /// Thrown in case of any internal error. /// http://tizen.org/privilege/notification public static void DeleteAll() { Interop.NotificationEventListener.ErrorCode err; err = Interop.NotificationEventListener.DeleteAll((int)NotificationType.Notification); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "delete all notifications failed of Noti type"); } err = Interop.NotificationEventListener.DeleteAll((int)NotificationType.Ongoing); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "delete all notifications failed of Ongoing type"); } } /// /// Returns the notification list. /// /// Thrown in case of a permission is denied. /// Thrown in case of any internal error. /// http://tizen.org/privilege/notification public static IList GetList() { Interop.NotificationEventListener.ErrorCode err; IntPtr notificationList = IntPtr.Zero; IntPtr currentList = IntPtr.Zero; IList list = new List(); err = Interop.NotificationEventListener.GetList(NotificationType.Notification, -1, out notificationList); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to get notification list"); } if (notificationList != IntPtr.Zero) { currentList = notificationList; while (currentList != IntPtr.Zero) { IntPtr notification; NotificationEventArgs eventargs = new NotificationEventArgs(); notification = Interop.NotificationEventListener.GetData(currentList); eventargs = NotificationEventArgsBinder.BindObject(notification, false); list.Add(eventargs); currentList = Interop.NotificationEventListener.GetNext(currentList); } Interop.NotificationEventListener.NotificationListFree(notificationList); notificationList = IntPtr.Zero; } err = Interop.NotificationEventListener.GetList(NotificationType.Ongoing, -1, out notificationList); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "unable to get notification list"); } if (notificationList != IntPtr.Zero) { currentList = notificationList; while (currentList != IntPtr.Zero) { IntPtr notification; NotificationEventArgs eventargs = new NotificationEventArgs(); notification = Interop.NotificationEventListener.GetData(currentList); eventargs = NotificationEventArgsBinder.BindObject(notification, false); list.Add(eventargs); currentList = Interop.NotificationEventListener.GetNext(currentList); } Interop.NotificationEventListener.NotificationListFree(notificationList); } return list; } /// /// Sends occured event from viewer application to the notification owner. /// /// The unique number of the notification. /// Event type on notification. /// Thrown in case of an invalid parameter. /// Thrown in case of a permission is denied. /// Thrown in case of any internal error. /// http://tizen.org/privilege/notification [EditorBrowsable(EditorBrowsableState.Never)] public static void SendEvent(int uniqueNumber, UserEventType type) { Interop.NotificationEventListener.ErrorCode err; err = Interop.NotificationEventListener.SendEvent(uniqueNumber, (int)type); if (err != Interop.NotificationEventListener.ErrorCode.None) { throw NotificationEventListenerErrorFactory.GetException(err, "failed to send event"); } } /// /// Returns NotificationEventArgs by UniqueNumber. /// /// The unique number of the Notification. /// Thrown in case of an invalid parameter. /// Thrown in case of a permission is denied. /// Thrown in case of any internal error. /// http://tizen.org/privilege/notification [EditorBrowsable(EditorBrowsableState.Never)] public static NotificationEventArgs GetNotificationEventArgs(int uniqueNumber) { if (uniqueNumber <= 0) { throw NotificationEventListenerErrorFactory.GetException(Interop.NotificationEventListener.ErrorCode.InvalidParameter, "Invalid parameter"); } IntPtr notificationPtr = Interop.NotificationEventListener.LoadNotification(null, uniqueNumber); if (notificationPtr == IntPtr.Zero) { int err = Tizen.Internals.Errors.ErrorFacts.GetLastResult(); if (err.Equals((int)Interop.NotificationEventListener.ErrorCode.DbError)) { throw NotificationEventListenerErrorFactory.GetException(Interop.NotificationEventListener.ErrorCode.InvalidParameter, "Not exist"); } else { throw NotificationEventListenerErrorFactory.GetException((Interop.NotificationEventListener.ErrorCode)err, "failed to get NotificationEventArgs"); } } NotificationEventArgs eventArgs = new NotificationEventArgs(); eventArgs = NotificationEventArgsBinder.BindObject(notificationPtr, false); return eventArgs; } } }