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