ff6906a48887d8cd823c3af1cb378103eac52e03
[platform/core/csapi/tizenfx.git] / src / Tizen.Applications.WidgetControl / Tizen.Applications / WidgetControl.cs
1 /*
2  * Copyright (c) 2016 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 using System;
18 using System.Collections.Generic;
19 using Tizen.Applications;
20 using System.Runtime.InteropServices;
21
22 namespace Tizen.Applications
23 {
24     /// <summary>
25     /// The class for receiving widget events and sending data to the widget.
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public class WidgetControl : IDisposable
29     {
30         private const string LogTag = "Tizen.Applications.WidgetControl";
31         /// <summary>
32         /// Class for the widget instance.
33         /// </summary>
34         /// <since_tizen> 3 </since_tizen>
35         public class Instance
36         {
37             private string _widgetId;
38
39             internal Instance(string widgetId)
40             {
41                 _widgetId = widgetId;
42             }
43
44             /// <summary>
45             /// The widget ID.
46             /// </summary>
47             /// <since_tizen> 3 </since_tizen>
48             public string Id { get; internal set; }
49
50             /// <summary>
51             /// Gets the widget content.
52             /// </summary>
53             /// <since_tizen> 3 </since_tizen>
54             /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
55             public Bundle GetContent()
56             {
57                 IntPtr h;
58
59                 Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetContent(_widgetId, Id, out h);
60
61                 switch (err)
62                 {
63                     case Interop.WidgetService.ErrorCode.InvalidParameter:
64                         throw new InvalidOperationException("Invalid parameter at unmanaged code");
65
66                     case Interop.WidgetService.ErrorCode.IoError:
67                         throw new InvalidOperationException("Failed to access DB");
68                 }
69
70                 return new Bundle(new SafeBundleHandle(h, true));
71             }
72
73             /// <summary>
74             /// Changes the content for the widget instance.
75             /// </summary>
76             /// <since_tizen> 3 </since_tizen>
77             /// <param name="content">Content to be changed.</param>
78             /// <param name="force"> True if you want to update your widget even if the provider is paused, otherwise false.</param>
79             /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
80             /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
81             /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
82             public void ChangeContent(Bundle content, bool force)
83             {
84                 Interop.WidgetService.ErrorCode err = Interop.WidgetService.UpdateContent(_widgetId, Id, content.SafeBundleHandle, force ? 1 : 0);
85
86                 switch (err)
87                 {
88                     case Interop.WidgetService.ErrorCode.InvalidParameter:
89                         throw new ArgumentException("Invalid parameter");
90
91                     case Interop.WidgetService.ErrorCode.Canceled:
92                         throw new InvalidOperationException("Provider is paused, so this update request is canceld");
93
94                     case Interop.WidgetService.ErrorCode.OutOfMemory:
95                         throw new InvalidOperationException("Out-of-memory at unmanaged code");
96
97                     case Interop.WidgetService.ErrorCode.Fault:
98                         throw new InvalidOperationException("Failed to create a request packet");
99
100                     case Interop.WidgetService.ErrorCode.PermissionDenied:
101                         throw new UnauthorizedAccessException();
102                 }
103             }
104
105             /// <summary>
106             /// Changes the update period for the widget instance.
107             /// </summary>
108             /// <since_tizen> 3 </since_tizen>
109             /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
110             /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
111             /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
112             public void ChangePeriod(double period)
113             {
114                 Interop.WidgetService.ErrorCode err = Interop.WidgetService.ChangePeriod(_widgetId, Id, period);
115
116                 switch (err)
117                 {
118                     case Interop.WidgetService.ErrorCode.InvalidParameter:
119                         throw new ArgumentException("Invalid parameter");
120
121                     case Interop.WidgetService.ErrorCode.OutOfMemory:
122                         throw new InvalidOperationException("Out-of-memory at unmanaged code");
123
124                     case Interop.WidgetService.ErrorCode.Fault:
125                         throw new InvalidOperationException("Failed to create a request packet");
126
127                     case Interop.WidgetService.ErrorCode.PermissionDenied:
128                         throw new UnauthorizedAccessException();
129                 }
130             }
131         }
132
133         /// <summary>
134         /// The class for the widget size information.
135         /// </summary>
136         /// <since_tizen> 3 </since_tizen>
137         public class Scale
138         {
139
140             internal Scale()
141             {
142             }
143
144             /// <summary>
145             /// Enumeration for the types of widget size.
146             /// </summary>
147             /// <since_tizen> 3 </since_tizen>
148             public enum SizeType : int
149             {
150                 /// <summary>
151                 /// 175x175 based on 720x1280 resolution.
152                 /// </summary>
153                 Basic1x1 = 0x0001,
154
155                 /// <summary>
156                 /// 354x175 based on 720x1280 resolution.
157                 /// </summary>
158                 Basic2x1 = 0x0002,
159
160                 /// <summary>
161                 /// 354x354 based on 720x1280 resolution.
162                 /// </summary>
163                 Basic2x2 = 0x0004,
164
165                 /// <summary>
166                 /// 712x175 based on 720x1280 resolution.
167                 /// </summary>
168                 Basic4x1 = 0x0008,
169
170                 /// <summary>
171                 /// 712x354 based on 720x1280 resolution.
172                 /// </summary>
173                 Basic4x2 = 0x0010,
174
175                 /// <summary>
176                 /// 712x533 based on 720x1280 resolution.
177                 /// </summary>
178                 Basic4x3 = 0x0020,
179
180                 /// <summary>
181                 /// 712x712 based on 720x1280 resolution.
182                 /// </summary>
183                 Basic4x4 = 0x0040,
184
185                 /// <summary>
186                 /// 712x891 based on 720x1280 resolution.
187                 /// </summary>
188                 Basic4x5 = 0x0080,
189
190                 /// <summary>
191                 /// 712x1070 based on 720x1280 resolution.
192                 /// </summary>
193                 Basic4x6 = 0x0100,
194
195
196                 /// <summary>
197                 /// 224x215 based on 720x1280 resolution.
198                 /// </summary>
199                 Easy1x1 = 0x1000,
200
201                 /// <summary>
202                 /// 680x215 based on 720x1280 resolution.
203                 /// </summary>
204                 Easy1x2 = 0x2000,
205
206                 /// <summary>
207                 /// 680x653 based on 720x1280 resolution.
208                 /// </summary>
209                 Easy1x3 = 0x4000,
210
211                 /// <summary>
212                 /// 720x1280 based on 720x1280 resolution.
213                 /// </summary>
214                 Full = 0x0800,
215             }
216
217             /// <summary>
218             /// Widget width.
219             /// </summary>
220             /// <since_tizen> 3 </since_tizen>
221             public int Width { get; internal set; }
222
223             /// <summary>
224             ///Widget height.
225             /// </summary>
226             /// <since_tizen> 3 </since_tizen>
227             public int Height { get; internal set; }
228
229             /// <summary>
230             /// The path for the widget preview image file.
231             /// </summary>
232             /// <since_tizen> 3 </since_tizen>
233             public string PreviewImagePath { get; internal set; }
234
235             /// <summary>
236             /// The size type of the widget.
237             /// </summary>
238             /// <since_tizen> 3 </since_tizen>
239             public SizeType Type { get; internal set; }
240         }
241
242         private event EventHandler<WidgetLifecycleEventArgs> _created;
243         private event EventHandler<WidgetLifecycleEventArgs> _resumed;
244         private event EventHandler<WidgetLifecycleEventArgs> _paused;
245         private event EventHandler<WidgetLifecycleEventArgs> _destroyed;
246         private bool _disposedValue = false;
247         private static IDictionary<string, int> s_lifecycleEventRefCnt = new Dictionary<string, int>();
248         private static IList<WidgetControl> s_eventObjects = new List<WidgetControl>();
249
250         /// <summary>
251         /// Factory method for the WidgetControl.
252         /// It will create all the objects of WidgetControl based on the package ID.
253         /// </summary>
254         /// <since_tizen> 3 </since_tizen>
255         /// <param name="pkgId">Package ID.</param>
256         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
257         /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
258         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
259         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
260         public static WidgetControl[] CreateAll(string pkgId)
261         {
262             List<WidgetControl> list = new List<WidgetControl>();
263
264             Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetWidgetListByPkgId(pkgId, (widgetId, isPrime, userData) =>
265             {
266                 list.Add(new WidgetControl(widgetId));
267             }, IntPtr.Zero);
268
269             switch (err)
270             {
271                 case Interop.WidgetService.ErrorCode.InvalidParameter:
272                     throw new ArgumentException("Invalid parameter");
273
274                 case Interop.WidgetService.ErrorCode.IoError:
275                     throw new InvalidOperationException("Failed to access DB");
276
277                 case Interop.WidgetService.ErrorCode.PermissionDenied:
278                     throw new UnauthorizedAccessException();
279             }
280
281             return list.ToArray();
282         }
283
284         /// <summary>
285         /// Gets all the widget IDs by the package ID.
286         /// </summary>
287         /// <since_tizen> 3 </since_tizen>
288         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
289         /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
290         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
291         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
292         public static string[] GetWidgetIds(string pkgId)
293         {
294             List<string> list = new List<string>();
295
296             Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetWidgetListByPkgId(pkgId, (widgetId, isPrime, userData) =>
297             {
298                 list.Add(widgetId);
299             }, IntPtr.Zero);
300
301             switch (err)
302             {
303                 case Interop.WidgetService.ErrorCode.InvalidParameter:
304                     throw new ArgumentException("Invalid parameter");
305
306                 case Interop.WidgetService.ErrorCode.IoError:
307                     throw new InvalidOperationException("Failed to access DB");
308
309                 case Interop.WidgetService.ErrorCode.PermissionDenied:
310                     throw new UnauthorizedAccessException();
311             }
312
313             return list.ToArray();
314         }
315
316         /// <summary>
317         /// The widget ID.
318         /// </summary>
319         /// <since_tizen> 3 </since_tizen>
320         public string Id { get; internal set; }
321
322         /// <summary>
323         /// The flag value for "nodisplay".
324         /// </summary>
325         /// <since_tizen> 3 </since_tizen>
326         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
327         public bool IsNoDisplay
328         {
329             get
330             {
331                 if (Interop.WidgetService.GetNoDisplay(Id) != 0)
332                     return true;
333
334                 return false;
335             }
336         }
337
338         /// <summary>
339         ///  The event handler for a created widget instance.
340         /// </summary>
341         /// <since_tizen> 3 </since_tizen>
342         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
343         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
344         public event EventHandler<WidgetLifecycleEventArgs> Created
345         {
346             add
347             {
348                 RegisterLifecycleEvent();
349                 _created += value;
350             }
351             remove
352             {
353                 _created -= value;
354                 UnregisterLifecycleEvent();
355             }
356         }
357
358         /// <summary>
359         /// The event handler for a resumed widget instance.
360         /// </summary>
361         /// <since_tizen> 3 </since_tizen>
362         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
363         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
364         public event EventHandler<WidgetLifecycleEventArgs> Resumed
365         {
366             add
367             {
368                 RegisterLifecycleEvent();
369                 _resumed += value;
370             }
371             remove
372             {
373                 _resumed -= value;
374                 UnregisterLifecycleEvent();
375             }
376         }
377
378         /// <summary>
379         /// The event handler for a paused widget instance.
380         /// </summary>
381         /// <since_tizen> 3 </since_tizen>
382         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
383         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
384         public event EventHandler<WidgetLifecycleEventArgs> Paused
385         {
386             add
387             {
388                 RegisterLifecycleEvent();
389                 _paused += value;
390             }
391             remove
392             {
393                 _paused -= value;
394                 UnregisterLifecycleEvent();
395             }
396         }
397
398         /// <summary>
399         /// The event handler for a destroyed widget instance.
400         /// </summary>
401         /// <since_tizen> 3 </since_tizen>
402         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
403         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
404         public event EventHandler<WidgetLifecycleEventArgs> Destroyed
405         {
406             add
407             {
408                 RegisterLifecycleEvent();
409                 _destroyed += value;
410             }
411             remove
412             {
413                 _destroyed -= value;
414                 UnregisterLifecycleEvent();
415             }
416         }
417
418         /// <summary>
419         /// The constructor of the WidgetControl object.
420         /// </summary>
421         /// <since_tizen> 3 </since_tizen>
422         /// <param name="widgetId">Widget ID.</param>
423         public WidgetControl(string widgetId)
424         {
425             Id = widgetId;
426         }
427
428         /// <summary>
429         /// Finalizer of the WidgetControl class.
430         /// </summary>
431         ~WidgetControl()
432         {
433             Dispose(false);
434         }
435
436         /// <summary>
437         /// Gets the objects for widget instance information.
438         /// </summary>
439         /// <since_tizen> 3 </since_tizen>
440         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
441         /// <exception cref="NotSupportedException">Thrown when the API is not supported in this device.</exception>
442         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
443         public IEnumerable<Instance> GetInstances()
444         {
445             IList<Instance> instances = new List<Instance>();
446             Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetInstances(Id, (widgetId, instanceId, userData) =>
447             {
448                 instances.Add(new Instance(widgetId) { Id = instanceId });
449             }, IntPtr.Zero);
450
451             switch (err)
452             {
453                 case Interop.WidgetService.ErrorCode.InvalidParameter:
454                     throw new InvalidOperationException("Invalid parameter at unmanaged code");
455
456                 case Interop.WidgetService.ErrorCode.NotSupported:
457                     throw new NotSupportedException();
458
459                 case Interop.WidgetService.ErrorCode.PermissionDenied:
460                     throw new UnauthorizedAccessException();
461             }
462
463             return instances;
464         }
465
466         /// <summary>
467         /// Gets the objects for widget scale information.
468         /// </summary>
469         /// <since_tizen> 3 </since_tizen>
470         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
471         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
472         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
473         public IEnumerable<Scale> GetScales()
474         {
475             IntPtr wPtr;
476             IntPtr hPtr;
477             IntPtr typesPtr;
478             int[] w;
479             int[] h;
480             int[] types;
481             int cnt1 = 100;
482             int cnt2 = 100;
483             IList<Scale> scales = new List<Scale>();
484             Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetSupportedSizes(Id, ref cnt1, out wPtr, out hPtr);
485
486             if (cnt1 == 0)
487             {
488                 Log.Error(LogTag, "No supported size :" + Id);
489                 return null;
490             }
491
492             switch (err)
493             {
494                 case Interop.WidgetService.ErrorCode.InvalidParameter:
495                     throw new InvalidOperationException("Invalid parameter at unmanaged code");
496
497                 case Interop.WidgetService.ErrorCode.IoError:
498                     throw new InvalidOperationException("Failed to access DB");
499
500                 case Interop.WidgetService.ErrorCode.PermissionDenied:
501                     throw new UnauthorizedAccessException();
502             }
503             w = new int[cnt1];
504             Marshal.Copy(wPtr, w, 0, cnt1);
505             Interop.Libc.Free(wPtr);
506
507             h = new int[cnt1];
508             Marshal.Copy(hPtr, h, 0, cnt1);
509             Interop.Libc.Free(hPtr);
510
511             err = Interop.WidgetService.GetSupportedSizeTypes(Id, ref cnt2, out typesPtr);
512             switch (err)
513             {
514                 case Interop.WidgetService.ErrorCode.InvalidParameter:
515                     throw new InvalidOperationException("Invalid parameter at unmanaged code");
516
517                 case Interop.WidgetService.ErrorCode.IoError:
518                     throw new InvalidOperationException("Failed to access DB");
519
520                 case Interop.WidgetService.ErrorCode.PermissionDenied:
521                     throw new UnauthorizedAccessException();
522             }
523
524             if (cnt1 != cnt2)
525             {
526                 Log.Error(LogTag, "Count not match cnt1 :" + cnt1 + ", cnt2 :" + cnt2);
527                 return null;
528             }
529
530             types = new int[cnt2];
531             Marshal.Copy(typesPtr, types, 0, cnt2);
532             Interop.Libc.Free(typesPtr);
533
534             for (int i = 0; i < cnt1; i++)
535             {
536                 string prev = Interop.WidgetService.GetPreviewImagePath(Id, types[i]);
537
538                 scales.Add(new Scale()
539                 {
540                     Width = w[i],
541                     Height = h[i],
542                     PreviewImagePath = prev,
543                     Type = (Scale.SizeType)types[i]
544                 });
545             }
546             return scales;
547         }
548
549         /// <summary>
550         /// Gets the widget name.
551         /// </summary>
552         /// <since_tizen> 3 </since_tizen>
553         /// <param name="lang">Language.</param>
554         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
555         /// <exception cref="ArgumentNullException">Thrown when the argument is null.</exception>
556         public string GetName(string lang)
557         {
558             if (lang == null)
559                 throw new ArgumentNullException();
560
561             return Interop.WidgetService.GetName(Id, lang);
562         }
563
564         /// <summary>
565         /// Gets the widget icon path.
566         /// </summary>
567         /// <since_tizen> 3 </since_tizen>
568         /// <param name="lang">Language.</param>
569         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
570         /// <exception cref="ArgumentNullException">Thrown when the argument is null.</exception>
571         public string GetIconPath(string lang)
572         {
573             if (lang == null)
574                 throw new ArgumentNullException();
575
576             string pkgId = Interop.WidgetService.GetPkgId(Id);
577
578             return Interop.WidgetService.GetIcon(pkgId, lang);
579         }
580
581         /// <summary>
582         /// Releases all the resources used by the WidgetControl class.
583         /// </summary>
584         /// <since_tizen> 3 </since_tizen>
585         public void Dispose()
586         {
587             Dispose(true);
588             GC.SuppressFinalize(this);
589         }
590
591         private void Dispose(bool disposing)
592         {
593             if (!_disposedValue)
594             {
595                 if (disposing)
596                 {
597                 }
598
599                 _created = null;
600                 _resumed = null;
601                 _paused = null;
602                 _destroyed = null;
603                 UnregisterLifecycleEvent();
604
605                 _disposedValue = true;
606             }
607         }
608
609         private void RegisterLifecycleEvent()
610         {
611             if (!s_lifecycleEventRefCnt.ContainsKey(Id))
612                 s_lifecycleEventRefCnt[Id] = 0;
613
614             if (_created != null || _paused != null || _resumed != null || _destroyed != null)
615                 return;
616
617             if (s_lifecycleEventRefCnt[Id] == 0)
618             {
619                 Interop.WidgetService.ErrorCode err = Interop.WidgetService.SetLifecycleEvent(Id, OnLifecycleEvent, IntPtr.Zero);
620
621                 switch (err)
622                 {
623                     case Interop.WidgetService.ErrorCode.InvalidParameter:
624                         throw new InvalidOperationException("Invalid parameter at unmanaged code");
625
626                     case Interop.WidgetService.ErrorCode.PermissionDenied:
627                         throw new UnauthorizedAccessException();
628                 }
629             }
630
631             s_lifecycleEventRefCnt[Id]++;
632             s_eventObjects.Add(this);
633         }
634
635         private void UnregisterLifecycleEvent()
636         {
637             if (!s_lifecycleEventRefCnt.ContainsKey(Id))
638                 return;
639
640             if (s_lifecycleEventRefCnt[Id] <= 0)
641                 return;
642
643             if (_created != null || _paused != null || _resumed != null || _destroyed != null)
644                 return;
645
646             if (s_lifecycleEventRefCnt[Id] == 1)
647             {
648                 Interop.WidgetService.ErrorCode err = Interop.WidgetService.UnsetLifecycleEvent(Id, IntPtr.Zero);
649
650                 switch (err)
651                 {
652                     case Interop.WidgetService.ErrorCode.InvalidParameter:
653                         throw new InvalidOperationException("Invalid parameter at unmanaged code");
654
655                     case Interop.WidgetService.ErrorCode.PermissionDenied:
656                         throw new UnauthorizedAccessException();
657
658                     case Interop.WidgetService.ErrorCode.NotExist:
659                         throw new InvalidOperationException("Event handler is not exist");
660                 }
661             }
662
663             s_eventObjects.Remove(this);
664             s_lifecycleEventRefCnt[Id]--;
665         }
666
667         private static void OnLifecycleEvent(string widgetId, Interop.WidgetService.LifecycleEvent e, string instanceId, IntPtr userData)
668         {
669             switch (e)
670             {
671                 case Interop.WidgetService.LifecycleEvent.Created:
672                     foreach (WidgetControl c in s_eventObjects)
673                     {
674                         if (c.Id.CompareTo(widgetId) == 0)
675                         {
676                             c._created?.Invoke(null, new WidgetLifecycleEventArgs()
677                             {
678                                 WidgetId = widgetId,
679                                 InstanceId = instanceId,
680                                 Type = WidgetLifecycleEventArgs.EventType.Created
681                             });
682                         }
683                     }
684                     break;
685
686                 case Interop.WidgetService.LifecycleEvent.Resumed:
687                     foreach (WidgetControl c in s_eventObjects)
688                     {
689                         if (c.Id.CompareTo(widgetId) == 0)
690                         {
691                             c._resumed?.Invoke(null, new WidgetLifecycleEventArgs()
692                             {
693                                 WidgetId = widgetId,
694                                 InstanceId = instanceId,
695                                 Type = WidgetLifecycleEventArgs.EventType.Resumed
696                             });
697                        }
698                     }
699                     break;
700
701                 case Interop.WidgetService.LifecycleEvent.Paused:
702                     foreach (WidgetControl c in s_eventObjects)
703                     {
704                         if (c.Id.CompareTo(widgetId) == 0)
705                         {
706                             c._paused?.Invoke(null, new WidgetLifecycleEventArgs()
707                             {
708                                 WidgetId = widgetId,
709                                 InstanceId = instanceId,
710                                 Type = WidgetLifecycleEventArgs.EventType.Paused
711                             });
712                         }
713                     }
714                     break;
715
716                 case Interop.WidgetService.LifecycleEvent.Destroyed:
717                     foreach (WidgetControl c in s_eventObjects)
718                     {
719                         if (c.Id.CompareTo(widgetId) == 0)
720                         {
721                             c._destroyed?.Invoke(null, new WidgetLifecycleEventArgs()
722                             {
723                                 WidgetId = widgetId,
724                                 InstanceId = instanceId,
725                                 Type = WidgetLifecycleEventArgs.EventType.Destroyed
726                             });
727                         }
728                     }
729                     break;
730             }
731
732         }
733     }
734 }