423a78763493ce76ec3b00d752eb099c8123cb78
[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         /// Gets setup app ID of the widget.
440         /// </summary>
441         /// <since_tizen> 8 </since_tizen>
442         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
443         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
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         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
447         public string SetupAppId
448         {
449             get
450             {
451                 string str = Interop.WidgetService.GetSetupAppId(Id);
452                 Interop.WidgetService.ErrorCode err =
453                     (Interop.WidgetService.ErrorCode)Internals.Errors.ErrorFacts.GetLastResult();
454                 switch (err)
455                 {
456                     case Interop.WidgetService.ErrorCode.PermissionDenied:
457                         throw new UnauthorizedAccessException();
458
459                     case Interop.WidgetService.ErrorCode.NotSupported:
460                         throw new NotSupportedException("Not supported");
461
462                     case Interop.WidgetService.ErrorCode.InvalidParameter:
463                         throw new InvalidOperationException("Invalid parameter at unmanaged code");
464
465                     case Interop.WidgetService.ErrorCode.IoError:
466                         throw new InvalidOperationException("Failed to access DB");
467
468                     case Interop.WidgetService.ErrorCode.Fault:
469                         throw new InvalidOperationException("Failed to access DB");
470
471                     case Interop.WidgetService.ErrorCode.NotExist:
472                         throw new InvalidOperationException("Not exist in DB");
473                 }
474
475                 return str;
476             }
477         }
478
479         /// <summary>
480         ///  The event handler for a created widget instance.
481         /// </summary>
482         /// <since_tizen> 3 </since_tizen>
483         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
484         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
485         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
486         /// <exception cref="NotSupportedException">Thrown when the required features are not supported.</exception>
487         public event EventHandler<WidgetLifecycleEventArgs> Created
488         {
489             add
490             {
491                 RegisterLifecycleEvent();
492                 _created += value;
493             }
494             remove
495             {
496                 _created -= value;
497                 UnregisterLifecycleEvent();
498             }
499         }
500
501         /// <summary>
502         /// The event handler for a resumed widget instance.
503         /// </summary>
504         /// <since_tizen> 3 </since_tizen>
505         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
506         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
507         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
508         /// <exception cref="NotSupportedException">Thrown when the required features are not supported.</exception>
509         public event EventHandler<WidgetLifecycleEventArgs> Resumed
510         {
511             add
512             {
513                 RegisterLifecycleEvent();
514                 _resumed += value;
515             }
516             remove
517             {
518                 _resumed -= value;
519                 UnregisterLifecycleEvent();
520             }
521         }
522
523         /// <summary>
524         /// The event handler for a paused widget instance.
525         /// </summary>
526         /// <since_tizen> 3 </since_tizen>
527         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
528         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
529         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
530         /// <exception cref="NotSupportedException">Thrown when the required features are not supported.</exception>
531         public event EventHandler<WidgetLifecycleEventArgs> Paused
532         {
533             add
534             {
535                 RegisterLifecycleEvent();
536                 _paused += value;
537             }
538             remove
539             {
540                 _paused -= value;
541                 UnregisterLifecycleEvent();
542             }
543         }
544
545         /// <summary>
546         /// The event handler for a destroyed widget instance.
547         /// </summary>
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="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
552         /// <exception cref="NotSupportedException">Thrown when the required features are not supported.</exception>
553         public event EventHandler<WidgetLifecycleEventArgs> Destroyed
554         {
555             add
556             {
557                 RegisterLifecycleEvent();
558                 _destroyed += value;
559             }
560             remove
561             {
562                 _destroyed -= value;
563                 UnregisterLifecycleEvent();
564             }
565         }
566
567         /// <summary>
568         /// The constructor of the WidgetControl object.
569         /// </summary>
570         /// <since_tizen> 3 </since_tizen>
571         /// <param name="widgetId">Widget ID.</param>
572         public WidgetControl(string widgetId)
573         {
574             Id = widgetId;
575         }
576
577         /// <summary>
578         /// Finalizer of the WidgetControl class.
579         /// </summary>
580         ~WidgetControl()
581         {
582             Dispose(false);
583         }
584
585         /// <summary>
586         /// Gets the objects for widget instance information.
587         /// </summary>
588         /// <returns>The instances list.</returns>
589         /// <since_tizen> 3 </since_tizen>
590         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
591         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
592         /// <exception cref="NotSupportedException">Thrown when the API is not supported in this device.</exception>
593         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
594         public IEnumerable<Instance> GetInstances()
595         {
596             IList<Instance> instances = new List<Instance>();
597             Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetInstances(Id, (widgetId, instanceId, userData) =>
598             {
599                 instances.Add(new Instance(widgetId) { Id = instanceId });
600             }, IntPtr.Zero);
601
602             switch (err)
603             {
604                 case Interop.WidgetService.ErrorCode.InvalidParameter:
605                     throw new InvalidOperationException("Invalid parameter at unmanaged code");
606
607                 case Interop.WidgetService.ErrorCode.NotSupported:
608                     throw new NotSupportedException();
609
610                 case Interop.WidgetService.ErrorCode.PermissionDenied:
611                     throw new UnauthorizedAccessException();
612             }
613
614             return instances;
615         }
616
617         /// <summary>
618         /// Gets the objects for widget scale information.
619         /// </summary>
620         /// <returns>The scales list.</returns>
621         /// <since_tizen> 3 </since_tizen>
622         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
623         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
624         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
625         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
626         /// <exception cref="NotSupportedException">Thrown when the required features are not supported.</exception>
627         public IEnumerable<Scale> GetScales()
628         {
629             IntPtr wPtr;
630             IntPtr hPtr;
631             IntPtr typesPtr;
632             int[] w;
633             int[] h;
634             int[] types;
635             int cnt1 = 100;
636             int cnt2 = 100;
637             IList<Scale> scales = new List<Scale>();
638             Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetSupportedSizes(Id, ref cnt1, out wPtr, out hPtr);
639
640             if (cnt1 == 0)
641             {
642                 Log.Error(LogTag, "No supported size :" + Id);
643                 return null;
644             }
645
646             switch (err)
647             {
648                 case Interop.WidgetService.ErrorCode.InvalidParameter:
649                     throw new InvalidOperationException("Invalid parameter at unmanaged code");
650
651                 case Interop.WidgetService.ErrorCode.IoError:
652                     throw new InvalidOperationException("Failed to access DB");
653
654                 case Interop.WidgetService.ErrorCode.PermissionDenied:
655                     throw new UnauthorizedAccessException();
656
657                 case Interop.WidgetService.ErrorCode.NotSupported:
658                     throw new NotSupportedException();
659             }
660             w = new int[cnt1];
661             Marshal.Copy(wPtr, w, 0, cnt1);
662             Interop.Libc.Free(wPtr);
663
664             h = new int[cnt1];
665             Marshal.Copy(hPtr, h, 0, cnt1);
666             Interop.Libc.Free(hPtr);
667
668             err = Interop.WidgetService.GetSupportedSizeTypes(Id, ref cnt2, out typesPtr);
669             switch (err)
670             {
671                 case Interop.WidgetService.ErrorCode.InvalidParameter:
672                     throw new InvalidOperationException("Invalid parameter at unmanaged code");
673
674                 case Interop.WidgetService.ErrorCode.IoError:
675                     throw new InvalidOperationException("Failed to access DB");
676
677                 case Interop.WidgetService.ErrorCode.PermissionDenied:
678                     throw new UnauthorizedAccessException();
679             }
680
681             if (cnt1 != cnt2)
682             {
683                 Log.Error(LogTag, "Count not match cnt1 :" + cnt1 + ", cnt2 :" + cnt2);
684                 return null;
685             }
686
687             types = new int[cnt2];
688             Marshal.Copy(typesPtr, types, 0, cnt2);
689             Interop.Libc.Free(typesPtr);
690
691             for (int i = 0; i < cnt1; i++)
692             {
693                 string prev = Interop.WidgetService.GetPreviewImagePath(Id, types[i]);
694
695                 scales.Add(new Scale()
696                 {
697                     Width = w[i],
698                     Height = h[i],
699                     PreviewImagePath = prev,
700                     Type = (Scale.SizeType)types[i]
701                 });
702             }
703             return scales;
704         }
705
706         /// <summary>
707         /// Gets the widget name.
708         /// </summary>
709         /// <since_tizen> 3 </since_tizen>
710         /// <param name="lang">Language.</param>
711         /// <returns>The widget name.</returns>
712         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
713         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
714         /// <exception cref="ArgumentNullException">Thrown when the argument is null.</exception>
715         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
716         /// <exception cref="NotSupportedException">Thrown when the required features are not supported.</exception>
717         public string GetName(string lang)
718         {
719             if (lang == null)
720                 throw new ArgumentNullException();
721
722             string str = Interop.WidgetService.GetName(Id, lang);
723             Interop.WidgetService.ErrorCode err =
724                     (Interop.WidgetService.ErrorCode)Internals.Errors.ErrorFacts.GetLastResult();
725
726             switch (err)
727             {
728                 case Interop.WidgetService.ErrorCode.PermissionDenied:
729                     throw new UnauthorizedAccessException();
730
731                 case Interop.WidgetService.ErrorCode.NotSupported:
732                     throw new NotSupportedException();
733             }
734
735             return str;
736         }
737
738         /// <summary>
739         /// Gets the widget icon path.
740         /// </summary>
741         /// <since_tizen> 3 </since_tizen>
742         /// <param name="lang">Language.</param>
743         /// <returns>The widget icon path.</returns>
744         /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
745         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
746         /// <exception cref="ArgumentNullException">Thrown when the argument is null.</exception>
747         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
748         /// <exception cref="NotSupportedException">Thrown when the required features are not supported.</exception>
749         public string GetIconPath(string lang)
750         {
751             if (lang == null)
752                 throw new ArgumentNullException();
753
754             string pkgId = Interop.WidgetService.GetPkgId(Id);
755             string str = Interop.WidgetService.GetIcon(pkgId, lang);
756             Interop.WidgetService.ErrorCode err =
757                     (Interop.WidgetService.ErrorCode)Internals.Errors.ErrorFacts.GetLastResult();
758
759             switch (err)
760             {
761                 case Interop.WidgetService.ErrorCode.PermissionDenied:
762                     throw new UnauthorizedAccessException();
763
764                 case Interop.WidgetService.ErrorCode.NotSupported:
765                     throw new NotSupportedException();
766             }
767
768             return str;
769         }
770
771         /// <summary>
772         /// Releases all the resources used by the WidgetControl class.
773         /// </summary>
774         /// <since_tizen> 3 </since_tizen>
775         /// <feature>http://tizen.org/feature/shell.appwidget</feature>
776         /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
777         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the required privileges to access this method.</exception>
778         /// <exception cref="NotSupportedException">Thrown when the required features are not supported.</exception>
779         public void Dispose()
780         {
781             Dispose(true);
782             GC.SuppressFinalize(this);
783         }
784
785         private void Dispose(bool disposing)
786         {
787             if (!_disposedValue)
788             {
789                 if (disposing)
790                 {
791                 }
792
793                 _created = null;
794                 _resumed = null;
795                 _paused = null;
796                 _destroyed = null;
797                 UnregisterLifecycleEvent();
798
799                 _disposedValue = true;
800             }
801         }
802
803         private void RegisterLifecycleEvent()
804         {
805             if (!s_lifecycleEventRefCnt.ContainsKey(Id))
806                 s_lifecycleEventRefCnt[Id] = 0;
807
808             if (_created != null || _paused != null || _resumed != null || _destroyed != null)
809                 return;
810
811             if (s_lifecycleEventRefCnt[Id] == 0)
812             {
813                 if (_onLifecycleCallback == null)
814                     _onLifecycleCallback = new Interop.WidgetService.LifecycleCallback(OnLifecycleEvent);
815
816                 Interop.WidgetService.ErrorCode err = Interop.WidgetService.SetLifecycleEvent(Id, _onLifecycleCallback, IntPtr.Zero);
817                 switch (err)
818                 {
819                     case Interop.WidgetService.ErrorCode.InvalidParameter:
820                         throw new InvalidOperationException("Invalid parameter at unmanaged code");
821
822                     case Interop.WidgetService.ErrorCode.PermissionDenied:
823                         throw new UnauthorizedAccessException();
824
825                     case Interop.WidgetService.ErrorCode.NotSupported:
826                         throw new NotSupportedException();
827                 }
828             }
829
830             s_lifecycleEventRefCnt[Id]++;
831             s_eventObjects.Add(this);
832             Log.Debug(LogTag, "register lifecycle cb " + Id + " [" + s_lifecycleEventRefCnt[Id] + "]");
833         }
834
835         private void UnregisterLifecycleEvent()
836         {
837             if (!s_lifecycleEventRefCnt.ContainsKey(Id))
838                 return;
839
840             if (s_lifecycleEventRefCnt[Id] <= 0)
841                 return;
842
843             if (_created != null || _paused != null || _resumed != null || _destroyed != null)
844                 return;
845
846             if (s_lifecycleEventRefCnt[Id] == 1)
847             {
848                 Interop.WidgetService.ErrorCode err = Interop.WidgetService.UnsetLifecycleEvent(Id, IntPtr.Zero);
849
850                 switch (err)
851                 {
852                     case Interop.WidgetService.ErrorCode.InvalidParameter:
853                         throw new InvalidOperationException("Invalid parameter at unmanaged code");
854
855                     case Interop.WidgetService.ErrorCode.PermissionDenied:
856                         throw new UnauthorizedAccessException();
857
858                     case Interop.WidgetService.ErrorCode.NotExist:
859                         throw new InvalidOperationException("Event handler is not exist");
860
861                     case Interop.WidgetService.ErrorCode.NotSupported:
862                         throw new NotSupportedException();
863                 }
864                 _onLifecycleCallback = null;
865             }
866
867             s_eventObjects.Remove(this);
868             s_lifecycleEventRefCnt[Id]--;
869             Log.Debug(LogTag, "unregister lifecycle cb " + Id + " [" + s_lifecycleEventRefCnt[Id] + "]");
870         }
871
872         private static int OnLifecycleEvent(string widgetId, Interop.WidgetService.LifecycleEvent e, string instanceId, IntPtr userData)
873         {
874             Log.Debug(LogTag, "Lifecycle event : " + instanceId + " [" + e + "]");
875             switch (e)
876             {
877                 case Interop.WidgetService.LifecycleEvent.Created:
878                     foreach (WidgetControl c in s_eventObjects)
879                     {
880                         if (c.Id.CompareTo(widgetId) == 0)
881                         {
882                             c._created?.Invoke(null, new WidgetLifecycleEventArgs()
883                             {
884                                 WidgetId = widgetId,
885                                 InstanceId = instanceId,
886                                 Type = WidgetLifecycleEventArgs.EventType.Created
887                             });
888                         }
889                     }
890                     break;
891
892                 case Interop.WidgetService.LifecycleEvent.Resumed:
893                     foreach (WidgetControl c in s_eventObjects)
894                     {
895                         if (c.Id.CompareTo(widgetId) == 0)
896                         {
897                             c._resumed?.Invoke(null, new WidgetLifecycleEventArgs()
898                             {
899                                 WidgetId = widgetId,
900                                 InstanceId = instanceId,
901                                 Type = WidgetLifecycleEventArgs.EventType.Resumed
902                             });
903                        }
904                     }
905                     break;
906
907                 case Interop.WidgetService.LifecycleEvent.Paused:
908                     foreach (WidgetControl c in s_eventObjects)
909                     {
910                         if (c.Id.CompareTo(widgetId) == 0)
911                         {
912                             c._paused?.Invoke(null, new WidgetLifecycleEventArgs()
913                             {
914                                 WidgetId = widgetId,
915                                 InstanceId = instanceId,
916                                 Type = WidgetLifecycleEventArgs.EventType.Paused
917                             });
918                         }
919                     }
920                     break;
921
922                 case Interop.WidgetService.LifecycleEvent.Destroyed:
923                     foreach (WidgetControl c in s_eventObjects)
924                     {
925                         if (c.Id.CompareTo(widgetId) == 0)
926                         {
927                             c._destroyed?.Invoke(null, new WidgetLifecycleEventArgs()
928                             {
929                                 WidgetId = widgetId,
930                                 InstanceId = instanceId,
931                                 Type = WidgetLifecycleEventArgs.EventType.Destroyed
932                             });
933                         }
934                     }
935                     break;
936             }
937             return 0;
938
939         }
940     }
941 }