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