1 /// Copyright 2016 by Samsung Electronics, Inc.,
3 /// This software is the confidential and proprietary information
4 /// of Samsung Electronics, Inc. ("Confidential Information"). You
5 /// shall not disclose such Confidential Information and shall use
6 /// it only in accordance with the terms of the license agreement
7 /// you entered into with Samsung.
11 using System.Collections.Generic;
16 namespace Tizen.Applications
19 /// Provides static methods and properties to manage an application, such as methods to register Actors and Services,
20 /// to start an application.
22 public static class Application
24 private static readonly Dictionary<AppControlFilter, Type> s_filterMap = new Dictionary<AppControlFilter, Type>();
25 private static readonly List<ServiceController> s_serviceControllerList = new List<ServiceController>();
26 private static readonly UIControllerStack s_uiControllerStack = new UIControllerStack();
27 private static Window s_defaultWindow = null;
30 /// Occurs when the application starts.
32 public static event EventHandler Created = delegate { };
35 /// Occurs when the application's main loop exits.
37 public static event EventHandler Exited = delegate { };
39 private static UIController Foreground
43 return s_uiControllerStack.Peek();
48 /// Runs the application's main loop.
50 /// <param name="args">The command-line arguments</param>
51 public static void Run(string[] args)
53 Interop.Application.UIAppLifecycleCallbacks ops;
54 ops.OnCreate = (userData) =>
56 Created(null, EventArgs.Empty);
59 ops.OnPause = (userData) =>
61 if (Foreground != null)
63 Foreground.SendPause();
66 ops.OnResume = (userData) =>
68 if (Foreground != null)
70 Foreground.SendResume();
73 ops.OnAppControl = (appControlHandle, userData) =>
75 AppControl control = new AppControl(appControlHandle);
76 StartController(null, null, control, Controller.ControlFlags.NewInstance);
78 ops.OnTerminate = (userData) =>
83 TizenSynchronizationContext.Initialize();
85 // TODO: check ret of UIAppMain and throw exceptions when errors are returned.
86 Interop.Application.UIAppMain(args.Length, args, ref ops, IntPtr.Zero);
90 /// Exits the main loop of application.
92 public static void Exit()
95 // TODO: clear context and group
96 Interop.Application.UIAppExit();
102 /// <param name="controllerType"></param>
103 public static void RegisterController(Type controllerType)
105 RegisterController(controllerType, new AppControlFilter[0] { });
111 /// <param name="controllerType"></param>
112 /// <param name="filter"></param>
113 public static void RegisterController(Type controllerType, AppControlFilter filter)
115 RegisterController(controllerType, new AppControlFilter[] { filter });
121 /// <param name="controllerType"></param>
122 /// <param name="filters"></param>
123 public static void RegisterController(Type controllerType, AppControlFilter[] filters)
125 if (controllerType == null)
127 throw new ArgumentNullException("controllerType");
130 if (!controllerType.IsSubclassOf(typeof(UIController)) || !controllerType.IsSubclassOf(typeof(ServiceController)))
132 throw new ArgumentException(controllerType.FullName + " is not a sub class of UIController or ServiceController.", "controllerType");
135 foreach (var prop in controllerType.GetProperties())
137 foreach (var attr in prop.GetCustomAttributes(false))
139 var filter = attr as AppControlFilter;
142 s_filterMap.Add(filter, controllerType);
148 foreach (var filter in filters)
150 s_filterMap.Add(filter, controllerType);
155 internal static void StartController(Controller caller, Type controllerType, AppControl control, Controller.ControlFlags flags)
159 throw new ArgumentNullException("control");
162 if (controllerType == null)
164 controllerType = FindControllerInFilterMap(control);
165 if (controllerType == null)
167 throw new ArgumentException("Could not find any matched controller.", "controllerType");
171 if (controllerType.IsSubclassOf(typeof(UIController)))
173 UIController target = null;
174 UIController uiCaller = caller as UIController;
175 if (uiCaller != null && uiCaller != Foreground)
177 throw new InvalidOperationException("Starting UIController should be called from the foreground.");
179 if (uiCaller != null && !IsFlagSet(flags, Controller.ControlFlags.NewInstance))
181 target = s_uiControllerStack.FindInForegroundTask(controllerType);
185 if (s_defaultWindow == null)
187 s_defaultWindow = new Window();
190 if (!s_defaultWindow.Visible)
192 s_defaultWindow.Active();
193 s_defaultWindow.Show();
198 target = (UIController)Activator.CreateInstance(controllerType);
199 target.TaskId = uiCaller == null ? Guid.NewGuid() : uiCaller.TaskId;
200 target.Window = s_defaultWindow;
202 s_uiControllerStack.Push(target);
206 if (IsFlagSet(flags, Controller.ControlFlags.ClearTop))
208 while (target != Foreground)
210 UIController popped = s_uiControllerStack.Pop();
212 popped.SendDestroy();
215 else if (IsFlagSet(flags, Controller.ControlFlags.MoveToTop))
217 if (Foreground != target)
219 Foreground.SendPause();
220 s_uiControllerStack.MoveToTop(target);
224 Foreground.SendStart(control);
225 Foreground.SendResume();
227 else if (controllerType.IsSubclassOf(typeof(ServiceController)))
229 ServiceController svc = s_serviceControllerList.Find(s => s.GetType() == controllerType);
232 svc = (ServiceController)Activator.CreateInstance(controllerType);
233 s_serviceControllerList.Add(svc);
236 svc.SendStart(control);
240 throw new ArgumentException("Invalid controller type.", "controllerType");
244 internal static void StopController(UIController target)
246 if (Foreground == null)
248 throw new InvalidOperationException("The UIController stack is empty.");
251 Guid prevForegroundTaskId = Foreground.TaskId;
253 s_uiControllerStack.Remove(target);
255 target.SendDestroy();
256 if (target.TaskId == prevForegroundTaskId)
258 if (Foreground.TaskId == target.TaskId)
260 Foreground.SendResume();
264 if (s_uiControllerStack.Count == 0 && s_serviceControllerList.Count == 0)
270 s_defaultWindow.Hide();
276 internal static void StopController(Type controllerType)
278 if (controllerType.IsSubclassOf(typeof(UIController)))
280 UIController target = s_uiControllerStack.Find(controllerType);
283 throw new InvalidOperationException("Could not find the UIController to stop.");
285 StopController(target);
287 else if (controllerType.IsSubclassOf(typeof(ServiceController)))
289 ServiceController svc = s_serviceControllerList.Find(s => s.GetType() == controllerType);
293 s_serviceControllerList.Remove(svc);
294 if (s_uiControllerStack.Count == 0 && s_serviceControllerList.Count == 0)
302 private static Type FindControllerInFilterMap(AppControl control)
304 foreach (var item in s_filterMap)
306 if (item.Key.IsMatch(control))
314 private static bool IsFlagSet(Controller.ControlFlags flags, Controller.ControlFlags values)
316 return (values & flags) == values;
320 private class UIControllerStack
322 private readonly List<UIController> _uiControllerList;
328 return _uiControllerList.Count;
332 public UIControllerStack()
334 _uiControllerList = new List<UIController>();
337 public UIController Peek()
339 return _uiControllerList.LastOrDefault(null);
342 public void Push(UIController item)
344 _uiControllerList.Add(item);
347 public UIController Pop()
349 UIController last = Peek();
350 _uiControllerList.Remove(last);
354 public void Remove(UIController actor)
356 _uiControllerList.Remove(actor);
359 public UIController Find(Type controllerType)
361 return _uiControllerList.Find(s => s.GetType() == controllerType);
364 public UIController FindInForegroundTask(Type controllerType)
366 return _uiControllerList.Find(s => s.GetType() == controllerType && s.TaskId == Peek().TaskId);
369 public void MoveToTop(UIController actor)
371 _uiControllerList.Remove(actor);
372 _uiControllerList.Add(actor);