2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using Tizen.Applications;
20 using System.Runtime.InteropServices;
22 namespace Tizen.Applications
25 /// The class for receiving widget events and sending data to the widget.
27 public class WidgetControl : IDisposable
29 protected static readonly string LogTag = "WidgetControl";
31 /// Class for the widget instance.
35 private string _widgetId;
37 internal Instance(string widgetId)
45 /// <since_tizen> 3 </since_tizen>
46 public string Id { get; internal set; }
49 /// Gets the widget content.
51 /// <since_tizen> 3 </since_tizen>
52 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
53 public Bundle GetContent()
57 Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetContent(_widgetId, Id, out h);
61 case Interop.WidgetService.ErrorCode.InvalidParameter:
62 throw new InvalidOperationException("Invalid parameter at unmanaged code");
64 case Interop.WidgetService.ErrorCode.IoError:
65 throw new InvalidOperationException("Failed to access DB");
68 return new Bundle(new SafeBundleHandle(h, true));
72 /// Changes the content for the widget instance.
74 /// <since_tizen> 3 </since_tizen>
75 /// <param name="content">Content to be changed.</param>
76 /// <param name="force"> True if you want to update your widget even if the provider is paused, otherwise false.</param>
77 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
78 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
79 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
80 public void ChangeContent(Bundle content, bool force)
82 Interop.WidgetService.ErrorCode err = Interop.WidgetService.UpdateContent(_widgetId, Id, content.SafeBundleHandle, force ? 1 : 0);
86 case Interop.WidgetService.ErrorCode.InvalidParameter:
87 throw new ArgumentException("Invalid parameter");
89 case Interop.WidgetService.ErrorCode.Canceled:
90 throw new InvalidOperationException("Provider is paused, so this update request is canceld");
92 case Interop.WidgetService.ErrorCode.OutOfMemory:
93 throw new InvalidOperationException("Out-of-memory at unmanaged code");
95 case Interop.WidgetService.ErrorCode.Fault:
96 throw new InvalidOperationException("Failed to create a request packet");
98 case Interop.WidgetService.ErrorCode.PermissionDenied:
99 throw new UnauthorizedAccessException();
104 /// Changes the update period for the widget instance.
106 /// <since_tizen> 3 </since_tizen>
107 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
108 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
109 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
110 public void ChangePeriod(double period)
112 Interop.WidgetService.ErrorCode err = Interop.WidgetService.ChangePeriod(_widgetId, Id, period);
116 case Interop.WidgetService.ErrorCode.InvalidParameter:
117 throw new ArgumentException("Invalid parameter");
119 case Interop.WidgetService.ErrorCode.OutOfMemory:
120 throw new InvalidOperationException("Out-of-memory at unmanaged code");
122 case Interop.WidgetService.ErrorCode.Fault:
123 throw new InvalidOperationException("Failed to create a request packet");
125 case Interop.WidgetService.ErrorCode.PermissionDenied:
126 throw new UnauthorizedAccessException();
132 /// The class for the widget size information.
142 /// Enumeration for the types of widget size.
144 /// <since_tizen> 3 </since_tizen>
145 public enum SizeType : int
148 /// 175x175 based on 720x1280 resolution.
153 /// 354x175 based on 720x1280 resolution.
158 /// 354x354 based on 720x1280 resolution.
163 /// 712x175 based on 720x1280 resolution.
168 /// 712x354 based on 720x1280 resolution.
173 /// 712x533 based on 720x1280 resolution.
178 /// 712x712 based on 720x1280 resolution.
183 /// 712x891 based on 720x1280 resolution.
188 /// 712x1070 based on 720x1280 resolution.
194 /// 224x215 based on 720x1280 resolution.
199 /// 680x215 based on 720x1280 resolution.
204 /// 680x653 based on 720x1280 resolution.
209 /// 720x1280 based on 720x1280 resolution.
217 /// <since_tizen> 3 </since_tizen>
218 public int Width { get; internal set; }
223 /// <since_tizen> 3 </since_tizen>
224 public int Height { get; internal set; }
227 /// The path for the widget preview image file.
229 /// <since_tizen> 3 </since_tizen>
230 public string PreviewImagePath { get; internal set; }
233 /// The size type of the widget.
235 /// <since_tizen> 3 </since_tizen>
236 public SizeType Type { get; internal set; }
239 private event EventHandler<WidgetLifecycleEventArgs> _created;
240 private event EventHandler<WidgetLifecycleEventArgs> _resumed;
241 private event EventHandler<WidgetLifecycleEventArgs> _paused;
242 private event EventHandler<WidgetLifecycleEventArgs> _destroyed;
243 private bool _disposedValue = false;
244 private static IDictionary<string, int> s_lifecycleEventRefCnt = new Dictionary<string, int>();
245 private static IList<WidgetControl> s_eventObjects = new List<WidgetControl>();
248 /// Factory method for the WidgetControl.
249 /// It will create all the objects of WidgetControl based on the package ID.
251 /// <since_tizen> 3 </since_tizen>
252 /// <param name="pkgId">Package ID.</param>
253 /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
254 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
255 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
256 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
257 public static WidgetControl[] CreateAll(string pkgId)
259 List<WidgetControl> list = new List<WidgetControl>();
261 Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetWidgetListByPkgId(pkgId, (widgetId, isPrime, userData) =>
263 list.Add(new WidgetControl(widgetId));
268 case Interop.WidgetService.ErrorCode.InvalidParameter:
269 throw new ArgumentException("Invalid parameter");
271 case Interop.WidgetService.ErrorCode.IoError:
272 throw new InvalidOperationException("Failed to access DB");
274 case Interop.WidgetService.ErrorCode.PermissionDenied:
275 throw new UnauthorizedAccessException();
278 return list.ToArray();
282 /// Gets all the widget IDs by the package ID.
284 /// <since_tizen> 3 </since_tizen>
285 /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
286 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
287 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
288 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
289 public static string[] GetWidgetIds(string pkgId)
291 List<string> list = new List<string>();
293 Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetWidgetListByPkgId(pkgId, (widgetId, isPrime, userData) =>
300 case Interop.WidgetService.ErrorCode.InvalidParameter:
301 throw new ArgumentException("Invalid parameter");
303 case Interop.WidgetService.ErrorCode.IoError:
304 throw new InvalidOperationException("Failed to access DB");
306 case Interop.WidgetService.ErrorCode.PermissionDenied:
307 throw new UnauthorizedAccessException();
310 return list.ToArray();
316 /// <since_tizen> 3 </since_tizen>
317 public string Id { get; internal set; }
320 /// The flag value for "nodisplay".
322 /// <since_tizen> 3 </since_tizen>
323 /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
324 public bool IsNoDisplay
328 if (Interop.WidgetService.GetNoDisplay(Id) != 0)
336 /// The event handler for a created widget instance.
338 /// <since_tizen> 3 </since_tizen>
339 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
340 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
341 public event EventHandler<WidgetLifecycleEventArgs> Created
345 RegisterLifecycleEvent();
351 UnregisterLifecycleEvent();
356 /// The event handler for a resumed widget instance.
358 /// <since_tizen> 3 </since_tizen>
359 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
360 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
361 public event EventHandler<WidgetLifecycleEventArgs> Resumed
365 RegisterLifecycleEvent();
371 UnregisterLifecycleEvent();
376 /// The event handler for a paused widget instance.
378 /// <since_tizen> 3 </since_tizen>
379 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
380 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
381 public event EventHandler<WidgetLifecycleEventArgs> Paused
385 RegisterLifecycleEvent();
391 UnregisterLifecycleEvent();
396 /// The event handler for a destroyed widget instance.
398 /// <since_tizen> 3 </since_tizen>
399 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
400 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
401 public event EventHandler<WidgetLifecycleEventArgs> Destroyed
405 RegisterLifecycleEvent();
411 UnregisterLifecycleEvent();
416 /// The constructor of the WidgetControl object.
418 /// <since_tizen> 3 </since_tizen>
419 /// <param name="widgetId">Widget ID.</param>
420 public WidgetControl(string widgetId)
426 /// Finalizer of the WidgetControl class.
434 /// Gets the objects for widget instance information.
436 /// <since_tizen> 3 </since_tizen>
437 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
438 /// <exception cref="NotSupportedException">Thrown when the API is not supported in this device.</exception>
439 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
440 public IEnumerable<Instance> GetInstances()
442 IList<Instance> instances = new List<Instance>();
443 Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetInstances(Id, (widgetId, instanceId, userData) =>
445 instances.Add(new Instance(widgetId) { Id = instanceId });
450 case Interop.WidgetService.ErrorCode.InvalidParameter:
451 throw new InvalidOperationException("Invalid parameter at unmanaged code");
453 case Interop.WidgetService.ErrorCode.NotSupported:
454 throw new NotSupportedException();
456 case Interop.WidgetService.ErrorCode.PermissionDenied:
457 throw new UnauthorizedAccessException();
464 /// Gets the objects for widget scale information.
466 /// <since_tizen> 3 </since_tizen>
467 /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
468 /// <exception cref="InvalidOperationException">Thrown in case of failed conditions.</exception>
469 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
470 public IEnumerable<Scale> GetScales()
480 IList<Scale> scales = new List<Scale>();
481 Interop.WidgetService.ErrorCode err = Interop.WidgetService.GetSupportedSizes(Id, ref cnt1, out wPtr, out hPtr);
485 Log.Error(LogTag, "No supported size :" + Id);
491 case Interop.WidgetService.ErrorCode.InvalidParameter:
492 throw new InvalidOperationException("Invalid parameter at unmanaged code");
494 case Interop.WidgetService.ErrorCode.IoError:
495 throw new InvalidOperationException("Failed to access DB");
497 case Interop.WidgetService.ErrorCode.PermissionDenied:
498 throw new UnauthorizedAccessException();
501 Marshal.Copy(wPtr, w, 0, cnt1);
502 Interop.Libc.Free(wPtr);
505 Marshal.Copy(hPtr, h, 0, cnt1);
506 Interop.Libc.Free(hPtr);
508 err = Interop.WidgetService.GetSupportedSizeTypes(Id, ref cnt2, out typesPtr);
511 case Interop.WidgetService.ErrorCode.InvalidParameter:
512 throw new InvalidOperationException("Invalid parameter at unmanaged code");
514 case Interop.WidgetService.ErrorCode.IoError:
515 throw new InvalidOperationException("Failed to access DB");
517 case Interop.WidgetService.ErrorCode.PermissionDenied:
518 throw new UnauthorizedAccessException();
523 Log.Error(LogTag, "Count not match cnt1 :" + cnt1 + ", cnt2 :" + cnt2);
527 types = new int[cnt2];
528 Marshal.Copy(typesPtr, types, 0, cnt2);
529 Interop.Libc.Free(typesPtr);
531 for (int i = 0; i < cnt1; i++)
533 string prev = Interop.WidgetService.GetPreviewImagePath(Id, types[i]);
535 scales.Add(new Scale()
539 PreviewImagePath = prev,
540 Type = (Scale.SizeType)types[i]
547 /// Gets the widget name.
549 /// <since_tizen> 3 </since_tizen>
550 /// <param name="lang">Language.</param>
551 /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
552 /// <exception cref="ArgumentNullException">Thrown when the argument is null.</exception>
553 public string GetName(string lang)
556 throw new ArgumentNullException();
558 return Interop.WidgetService.GetName(Id, lang);
562 /// Gets the widget icon path.
564 /// <since_tizen> 3 </since_tizen>
565 /// <param name="lang">Language.</param>
566 /// <privilege>http://tizen.org/privilege/widget.viewer</privilege>
567 /// <exception cref="ArgumentNullException">Thrown when the argument is null.</exception>
568 public string GetIconPath(string lang)
571 throw new ArgumentNullException();
573 string pkgId = Interop.WidgetService.GetPkgId(Id);
575 return Interop.WidgetService.GetIcon(pkgId, lang);
579 /// Releases all the resources used by the WidgetControl class.
581 /// <since_tizen> 3 </since_tizen>
582 public void Dispose()
585 GC.SuppressFinalize(this);
588 private void Dispose(bool disposing)
600 UnregisterLifecycleEvent();
602 _disposedValue = true;
606 private void RegisterLifecycleEvent()
608 if (!s_lifecycleEventRefCnt.ContainsKey(Id))
609 s_lifecycleEventRefCnt[Id] = 0;
611 if (_created != null || _paused != null || _resumed != null || _destroyed != null)
614 if (s_lifecycleEventRefCnt[Id] == 0)
616 Interop.WidgetService.ErrorCode err = Interop.WidgetService.SetLifecycleEvent(Id, OnLifecycleEvent, IntPtr.Zero);
620 case Interop.WidgetService.ErrorCode.InvalidParameter:
621 throw new InvalidOperationException("Invalid parameter at unmanaged code");
623 case Interop.WidgetService.ErrorCode.PermissionDenied:
624 throw new UnauthorizedAccessException();
628 s_lifecycleEventRefCnt[Id]++;
629 s_eventObjects.Add(this);
632 private void UnregisterLifecycleEvent()
634 if (!s_lifecycleEventRefCnt.ContainsKey(Id))
637 if (s_lifecycleEventRefCnt[Id] <= 0)
640 if (_created != null || _paused != null || _resumed != null || _destroyed != null)
643 if (s_lifecycleEventRefCnt[Id] == 1)
645 Interop.WidgetService.ErrorCode err = Interop.WidgetService.UnsetLifecycleEvent(Id, IntPtr.Zero);
649 case Interop.WidgetService.ErrorCode.InvalidParameter:
650 throw new InvalidOperationException("Invalid parameter at unmanaged code");
652 case Interop.WidgetService.ErrorCode.PermissionDenied:
653 throw new UnauthorizedAccessException();
655 case Interop.WidgetService.ErrorCode.NotExist:
656 throw new InvalidOperationException("Event handler is not exist");
660 s_eventObjects.Remove(this);
661 s_lifecycleEventRefCnt[Id]--;
664 private static void OnLifecycleEvent(string widgetId, Interop.WidgetService.LifecycleEvent e, string instanceId, IntPtr userData)
668 case Interop.WidgetService.LifecycleEvent.Created:
669 foreach (WidgetControl c in s_eventObjects)
671 if (c.Id.CompareTo(widgetId) == 0)
673 c._created?.Invoke(null, new WidgetLifecycleEventArgs()
676 InstanceId = instanceId,
677 Type = WidgetLifecycleEventArgs.EventType.Created
683 case Interop.WidgetService.LifecycleEvent.Resumed:
684 foreach (WidgetControl c in s_eventObjects)
686 if (c.Id.CompareTo(widgetId) == 0)
688 c._resumed?.Invoke(null, new WidgetLifecycleEventArgs()
691 InstanceId = instanceId,
692 Type = WidgetLifecycleEventArgs.EventType.Resumed
698 case Interop.WidgetService.LifecycleEvent.Paused:
699 foreach (WidgetControl c in s_eventObjects)
701 if (c.Id.CompareTo(widgetId) == 0)
703 c._paused?.Invoke(null, new WidgetLifecycleEventArgs()
706 InstanceId = instanceId,
707 Type = WidgetLifecycleEventArgs.EventType.Paused
713 case Interop.WidgetService.LifecycleEvent.Destroyed:
714 foreach (WidgetControl c in s_eventObjects)
716 if (c.Id.CompareTo(widgetId) == 0)
718 c._destroyed?.Invoke(null, new WidgetLifecycleEventArgs()
721 InstanceId = instanceId,
722 Type = WidgetLifecycleEventArgs.EventType.Destroyed