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