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