Exemple #1
0
        private void NotifyNode(INotifiable source)
        {
            bool evaluating = true;
            var  stack      = new Stack <Tuple <INotifiable, int> >();

            stack.Push(new Tuple <INotifiable, int>(source, 1));

            while (stack.Count > 0)
            {
                var tuple    = stack.Pop();
                var node     = tuple.Item1;
                var metaData = node.ExecutionMetaData;
                metaData.RemainingVisits -= tuple.Item2;
                if (metaData.RemainingVisits > 0)
                {
                    continue;
                }

                INotificationResult result = null;
                if (evaluating || metaData.Results.Count > 0)
                {
                    result     = node.Notify(metaData.Results);
                    evaluating = result.Changed;
                    foreach (var item in metaData.Results)
                    {
                        item.FreeReference();
                    }
                    metaData.Results.Clear();
                }

                if (node.Successors.HasSuccessors)
                {
                    if (evaluating)
                    {
                        result.IncreaseReferences(node.Successors.Count);
                        foreach (var succ in node.Successors)
                        {
                            if (result != null)
                            {
                                succ.ExecutionMetaData.Results.UnsafeAdd(result);
                            }
                            stack.Push(new Tuple <INotifiable, int>(succ, metaData.TotalVisits));
                        }
                    }
                    else
                    {
                        foreach (var succ in node.Successors)
                        {
                            stack.Push(new Tuple <INotifiable, int>(succ, metaData.TotalVisits));
                        }
                    }
                }

                metaData.TotalVisits = 0;
            }
        }
Exemple #2
0
        private void NotifyNode(INotifiable source)
        {
            bool evaluating = true;
            var  stack      = new Stack <Tuple <INotifiable, int> >();

            stack.Push(new Tuple <INotifiable, int>(source, 1));

            while (stack.Count > 0)
            {
                var tuple    = stack.Pop();
                var node     = tuple.Item1;
                var metaData = node.ExecutionMetaData;

                if (metaData.RemainingVisits != tuple.Item2)
                {
                    int remaining = Interlocked.Add(ref metaData.RemainingVisits, -tuple.Item2);
                    if (remaining > 0)
                    {
                        continue;
                    }
                }
                else
                {
                    metaData.RemainingVisits = 0;
                }

                INotificationResult result = null;
                if (evaluating || metaData.Results.Count > 0)
                {
                    result     = node.Notify(metaData.Results);
                    evaluating = result.Changed;
                    metaData.Results.Clear();
                }

                if (node.Successors.HasSuccessors)
                {
                    foreach (var succ in node.Successors)
                    {
                        if (result != null && evaluating)
                        {
                            succ.ExecutionMetaData.Results.Add(result);
                        }
                        stack.Push(new Tuple <INotifiable, int>(succ, metaData.TotalVisits));
                    }
                }

                metaData.TotalVisits = 0;
            }
        }
        private async Task <INotificationResult> Notify(INotificationOptions options)
        {
            INotificationResult result = null;

            return(await Task.Run(() =>
            {
                if (UIDevice.CurrentDevice.CheckSystemVersion(10, 0))
                {
                    return _NotificationManager.Notify(options);
                }
                else
                {
                    ManualResetEvent reset = new ManualResetEvent(false);
                    UIApplication.SharedApplication.InvokeOnMainThread(() => { result = _LocalNotificationManager.Notify(options); reset.Set(); });
                    reset.WaitOne();
                    return result;
                }
            }));
        }
        public Task <INotificationResult> Notify(INotificationOptions options)
        {
            return(Task.Run(() =>
            {
                ToastNotifier ToastNotifier = ToastNotificationManager.CreateToastNotifier();
                Windows.Data.Xml.Dom.XmlDocument toastXml = ToastNotificationManager.GetTemplateContent(ToastTemplateType.ToastText02);
                Windows.Data.Xml.Dom.XmlNodeList toastNodeList = toastXml.GetElementsByTagName("text");
                toastNodeList.Item(0).AppendChild(toastXml.CreateTextNode(options.Title));
                toastNodeList.Item(1).AppendChild(toastXml.CreateTextNode(options.Description));
                Windows.Data.Xml.Dom.IXmlNode toastNode = toastXml.SelectSingleNode("/toast");

                var id = _count.ToString();

                var root = toastXml.DocumentElement;
                root.SetAttribute("launch", id.ToString());

                if (!string.IsNullOrEmpty(options.WindowsOptions.LogoUri))
                {
                    Windows.Data.Xml.Dom.XmlElement image = toastXml.CreateElement("image");
                    image.SetAttribute("placement", "appLogoOverride");

                    var imageUri = options.WindowsOptions.LogoUri;
                    if (!options.WindowsOptions.LogoUri.Contains("//"))
                    {
                        imageUri = $"ms-appx:///{options.WindowsOptions.LogoUri}";
                    }

                    image.SetAttribute("src", imageUri);

                    toastXml.GetElementsByTagName("binding")[0].AppendChild(image);
                    toastXml.GetElementsByTagName("binding")[0].Attributes[0].InnerText = "ToastGeneric";
                }

                if (options.DelayUntil.HasValue)
                {
                    ScheduledToastNotification toast = new ScheduledToastNotification(toastXml, options.DelayUntil.Value);
                    ToastNotifier.AddToSchedule(toast);
                    return new NotificationResult()
                    {
                        Action = NotificationAction.NotApplicable
                    };
                }
                else
                {
                    Windows.UI.Notifications.ToastNotification toast = new Windows.UI.Notifications.ToastNotification(toastXml);


                    toast.Tag = id;
                    _count++;
                    toast.Dismissed += Toast_Dismissed;
                    toast.Activated += Toast_Activated;
                    toast.Failed += Toast_Failed;
                    _notificationOptions.Add(id, options);

                    var waitEvent = new ManualResetEvent(false);

                    _resetEvents.Add(id, waitEvent);

                    ToastNotifier.Show(toast);

                    waitEvent.WaitOne();

                    INotificationResult result = _eventResult[id];

                    if (!options.IsClickable && result.Action == NotificationAction.Clicked) // A click is transformed to manual dismiss
                    {
                        result = new NotificationResult()
                        {
                            Action = NotificationAction.Dismissed
                        }
                    }
                    ;

                    if (_resetEvents.ContainsKey(id))
                    {
                        _resetEvents.Remove(id);
                    }
                    if (_eventResult.ContainsKey(id))
                    {
                        _eventResult.Remove(id);
                    }
                    if (_notificationOptions.ContainsKey(id))
                    {
                        _notificationOptions.Remove(id);
                    }

                    return result;
                }
            }));
        }
 public Entry(INotificationResult item)
 {
     Item = item;
 }
        private void NotifyNode(INotifiable node, bool evaluating, int visits)
        {
            while (node != null)
            {
                var metaData = node.ExecutionMetaData;

                if (metaData.RemainingVisits == 0)
                {
                    return;
                }
                if (metaData.RemainingVisits != visits)
                {
                    int remaining = Interlocked.Add(ref metaData.RemainingVisits, -visits);
                    if (remaining != 0)
                    {
                        return;
                    }
                }
                else
                {
                    metaData.RemainingVisits = 0;
                }

                INotificationResult result = null;
                if (evaluating || metaData.Results.Count > 0)
                {
                    result     = node.Notify(metaData.Results);
                    evaluating = result.Changed;
                    foreach (var item in metaData.Results)
                    {
                        item.FreeReference();
                    }
                    metaData.Results.Clear();
                }

                visits = metaData.TotalVisits;
                metaData.RemainingVisits = 0;
                metaData.TotalVisits     = 0;

                if (node.Successors.HasSuccessors)
                {
                    if (evaluating)
                    {
                        result.IncreaseReferences(node.Successors.Count);
                        if (node.Successors.Count == 1)
                        {
                            node = node.Successors[0];
                            node.ExecutionMetaData.Results.Add(result);
                        }
                        else
                        {
                            var childTasks = new Task[node.Successors.Count];
                            for (int i = 0; i < node.Successors.Count && i < childTasks.Length; i++)
                            {
                                var successor = node.Successors[i];
                                successor.ExecutionMetaData.Results.Add(result);
                                childTasks[i] = Task.Factory.StartNew(() => NotifyNode(successor, true, visits));
                            }
                            Task.WaitAll(childTasks);
                            return;
                        }
                    }
                    else
                    {
                        if (node.Successors.Count == 1)
                        {
                            node = node.Successors[0];
                        }
                        else
                        {
                            var childTasks = new Task[node.Successors.Count];
                            for (int i = 0; i < node.Successors.Count; i++)
                            {
                                var successor = node.Successors[i];
                                childTasks[i] = Task.Factory.StartNew(() => NotifyNode(successor, true, visits));
                            }
                            Task.WaitAll(childTasks);
                            return;
                        }
                    }
                }
            }
        }
        public INotificationResult Notify(Activity activity, INotificationOptions options)
        {
            INotificationResult notificationResult = null;

            if (options != null)
            {
                var notificationId = 0;
                var id             = "";
                lock (_lock)
                {
                    notificationId = _count;
                    id             = _count.ToString();
                    _count++;
                }

                int smallIcon;

                if (options.AndroidOptions.SmallDrawableIcon.HasValue)
                {
                    smallIcon = options.AndroidOptions.SmallDrawableIcon.Value;
                }
                else if (_androidOptions.SmallIconDrawable.HasValue)
                {
                    smallIcon = _androidOptions.SmallIconDrawable.Value;
                }
                else
                {
                    smallIcon = Android.Resource.Drawable.IcDialogInfo; // As last resort
                }
                if (options.DelayUntil.HasValue)
                {
                    options.AndroidOptions.SmallDrawableIcon = smallIcon;
                    ScheduleNotification(id, options);
                    return(new NotificationResult()
                    {
                        Action = NotificationAction.NotApplicable, Id = notificationId
                    });
                }

                // Show Notification Right Now
                var dismissIntent = new Intent(DismissedClickIntent);
                dismissIntent.PutExtra(NotificationId, notificationId);

                var pendingDismissIntent = PendingIntent.GetBroadcast(Application.Context, (StartId + notificationId), dismissIntent, 0);

                var clickIntent = new Intent(OnClickIntent);
                clickIntent.PutExtra(NotificationId, notificationId);
                clickIntent.PutExtra(NotificationForceOpenApp, options.AndroidOptions.ForceOpenAppOnNotificationTap);

                // Add custom args
                if (options.CustomArgs != null)
                {
                    foreach (var arg in options.CustomArgs)
                    {
                        clickIntent.PutExtra(arg.Key, arg.Value);
                    }
                }

                var pendingClickIntent = PendingIntent.GetBroadcast(Application.Context, (StartId + notificationId), clickIntent, 0);

                if (!string.IsNullOrEmpty(options.AndroidOptions.HexColor) && options.AndroidOptions.HexColor.Substring(0, 1) != "#")
                {
                    options.AndroidOptions.HexColor = "#" + options.AndroidOptions.HexColor;
                }

                Android.App.Notification.Builder builder = new Android.App.Notification.Builder(Application.Context)
                                                           .SetContentTitle(options.Title)
                                                           .SetContentText(options.Description)
                                                           .SetSmallIcon(smallIcon)                     // Must have small icon to display
                                                           .SetPriority((int)NotificationPriority.High) // Must be set to High to get Heads-up notification
                                                           .SetDefaults(NotificationDefaults.All)       // Must also include vibrate to get Heads-up notification
                                                           .SetAutoCancel(true)                         // To allow click event to trigger delete Intent
                                                           .SetContentIntent(pendingClickIntent)        // Must have Intent to accept the click
                                                           .SetDeleteIntent(pendingDismissIntent)
                                                           .SetColor(Color.ParseColor(options.AndroidOptions.HexColor));

                try
                {
                    // Notification Channel
                    if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
                    {
                        var notificationChannelId = GetOrCreateChannel(options.AndroidOptions.ChannelOptions);
                        if (!string.IsNullOrEmpty(notificationChannelId))
                        {
                            builder.SetChannelId(notificationChannelId);
                        }
                    }
                }
                catch { }
                // System.MissingMethodException: Method 'Android.App.Notification/Builder.SetChannelId' not found.
                // I know this is bad, but I can't replicate it on any version, and many people are experiencing it.

                Android.App.Notification notification = builder.Build();

                NotificationManager notificationManager = Application.Context.GetSystemService(Context.NotificationService) as NotificationManager;

                notificationManager.Notify(notificationId, notification);

                if (options.DelayUntil.HasValue)
                {
                    return(new NotificationResult()
                    {
                        Action = NotificationAction.NotApplicable, Id = notificationId
                    });
                }

                var timer = new Timer(x => TimerFinished(id, options.ClearFromHistory, options.AllowTapInNotificationCenter), null, TimeSpan.FromSeconds(7), TimeSpan.FromMilliseconds(-1));

                var resetEvent = new ManualResetEvent(false);
                ResetEvent.Add(id, resetEvent);

                resetEvent.WaitOne(); // Wait for a result

                notificationResult = EventResult[id];

                if (!options.IsClickable && notificationResult.Action == NotificationAction.Clicked)
                {
                    notificationResult.Action = NotificationAction.Dismissed;
                    notificationResult.Id     = notificationId;
                }

                if (EventResult.ContainsKey(id))
                {
                    EventResult.Remove(id);
                }
                if (ResetEvent.ContainsKey(id))
                {
                    ResetEvent.Remove(id);
                }

                // Dispose of Intents and Timer
                pendingClickIntent.Cancel();
                pendingDismissIntent.Cancel();
                timer.Dispose();
            }
            return(notificationResult);
        }