From 3b813ee5345a706b311f4683c09059edf27e7ff4 Mon Sep 17 00:00:00 2001 From: WonYoung Choi Date: Sat, 12 Mar 2016 20:39:41 +0900 Subject: [PATCH] Fix lifecycles Change-Id: Ice898bd13ccd7dc08bb4c6127f28110ce6dd999d --- Tizen.Applications/Interop/Interop.AppControl.cs | 12 +- Tizen.Applications/Interop/Interop.Application.cs | 12 +- Tizen.Applications/Interop/Interop.Aul.cs | 12 +- Tizen.Applications/Interop/Interop.Bundle.cs | 4 +- Tizen.Applications/Interop/Interop.Glib.cs | 1 - Tizen.Applications/Tizen.Applications/Actor.cs | 105 +++---- .../Tizen.Applications/AppControl.cs | 312 ++++++++++----------- .../Tizen.Applications/AppControlFilter.cs | 44 +-- .../Tizen.Applications/Application.cs | 303 +++++++++++++------- Tizen.Applications/Tizen.Applications/Bundle.cs | 138 ++++----- Tizen.Applications/Tizen.Applications/Context.cs | 37 ++- Tizen.Applications/Tizen.Applications/Service.cs | 46 ++- .../TizenSynchronizationContext.cs | 15 +- 13 files changed, 578 insertions(+), 463 deletions(-) diff --git a/Tizen.Applications/Interop/Interop.AppControl.cs b/Tizen.Applications/Interop/Interop.AppControl.cs index 2f3ac14..69f10d0 100755 --- a/Tizen.Applications/Interop/Interop.AppControl.cs +++ b/Tizen.Applications/Interop/Interop.AppControl.cs @@ -17,9 +17,6 @@ internal static partial class Interop [DllImport(Libraries.Application, EntryPoint = "app_control_create", CallingConvention = CallingConvention.Cdecl)] internal static extern int Create(out SafeAppControlHandle handle); - [DllImport(Libraries.Application, EntryPoint = "app_control_destroy", CallingConvention = CallingConvention.Cdecl)] - private static extern int DangerousDestroy(IntPtr handle); - [DllImport(Libraries.Application, EntryPoint = "app_control_get_app_id", CallingConvention = CallingConvention.Cdecl)] internal static extern int GetAppId(IntPtr app_control, out IntPtr app_id); @@ -32,6 +29,9 @@ internal static partial class Interop [DllImport(Libraries.Application, EntryPoint = "app_control_get_mime", CallingConvention = CallingConvention.Cdecl)] internal static extern int GetMime(SafeAppControlHandle handle, out string mime); + [DllImport(Libraries.Application, EntryPoint = "app_control_destroy", CallingConvention = CallingConvention.Cdecl)] + private static extern int DangerousDestroy(IntPtr handle); + internal sealed class SafeAppControlHandle : SafeHandle { public SafeAppControlHandle() : base(IntPtr.Zero, true) @@ -44,13 +44,13 @@ internal static partial class Interop public override bool IsInvalid { - get { return handle == IntPtr.Zero; } + get { return this.handle == IntPtr.Zero; } } protected override bool ReleaseHandle() { - DangerousDestroy(handle); - SetHandle(IntPtr.Zero); + AppControl.DangerousDestroy(this.handle); + this.SetHandle(IntPtr.Zero); return true; } } diff --git a/Tizen.Applications/Interop/Interop.Application.cs b/Tizen.Applications/Interop/Interop.Application.cs index 31e5304..bbb04fe 100755 --- a/Tizen.Applications/Interop/Interop.Application.cs +++ b/Tizen.Applications/Interop/Interop.Application.cs @@ -29,6 +29,12 @@ internal static partial class Interop [UnmanagedFunctionPointer(CallingConvention.Cdecl)] internal delegate void AppControlCallback(IntPtr appControl, IntPtr userData); + [DllImport(Libraries.Application, EntryPoint = "ui_app_main", CallingConvention = CallingConvention.Cdecl)] + internal static extern int UIAppMain(int argc, string[] argv, ref UIAppLifecycleCallbacks callback, IntPtr userData); + + [DllImport(Libraries.Application, EntryPoint = "ui_app_exit", CallingConvention = CallingConvention.Cdecl)] + internal static extern void UIAppExit(); + [StructLayoutAttribute(LayoutKind.Sequential)] internal struct UIAppLifecycleCallbacks { @@ -38,11 +44,5 @@ internal static partial class Interop public AppResumeCallback OnResume; public AppControlCallback OnAppControl; } - - [DllImport(Libraries.Application, EntryPoint = "ui_app_main", CallingConvention = CallingConvention.Cdecl)] - internal static extern int UIAppMain(int argc, string[] argv, ref UIAppLifecycleCallbacks callback, IntPtr userData); - - [DllImport(Libraries.Application, EntryPoint = "ui_app_exit", CallingConvention = CallingConvention.Cdecl)] - internal static extern void UIAppExit(); } } diff --git a/Tizen.Applications/Interop/Interop.Aul.cs b/Tizen.Applications/Interop/Interop.Aul.cs index 439a35a..0100d72 100755 --- a/Tizen.Applications/Interop/Interop.Aul.cs +++ b/Tizen.Applications/Interop/Interop.Aul.cs @@ -7,8 +7,8 @@ /// you entered into with Samsung. -using System.Text; using System.Runtime.InteropServices; +using System.Text; internal static partial class Interop { @@ -17,15 +17,10 @@ internal static partial class Interop private const int MaxMimeLength = 128; private const string FileSchemaPrefix = "file://"; - [DllImport(Libraries.Aul, CallingConvention = CallingConvention.Cdecl)] - private static extern int aul_get_mime_from_file(string filename, StringBuilder mimetype, int len); - internal static string GetMimeFromUri(string uri) { StringBuilder sb = new StringBuilder(MaxMimeLength); - int err = aul_get_mime_from_file( - uri.StartsWith(FileSchemaPrefix) ? uri.Substring(FileSchemaPrefix.Length) : uri, - sb, MaxMimeLength); + int err = aul_get_mime_from_file(uri.StartsWith(FileSchemaPrefix) ? uri.Substring(FileSchemaPrefix.Length) : uri, sb, MaxMimeLength); if (err == 0) { return sb.ToString(); @@ -35,5 +30,8 @@ internal static partial class Interop return null; } } + + [DllImport(Libraries.Aul, CallingConvention = CallingConvention.Cdecl)] + private static extern int aul_get_mime_from_file(string filename, StringBuilder mimetype, int len); } } diff --git a/Tizen.Applications/Interop/Interop.Bundle.cs b/Tizen.Applications/Interop/Interop.Bundle.cs index 11097f9..eccd3c8 100755 --- a/Tizen.Applications/Interop/Interop.Bundle.cs +++ b/Tizen.Applications/Interop/Interop.Bundle.cs @@ -36,7 +36,7 @@ internal static partial class Interop internal static extern int GetString(IntPtr handle, string key, out IntPtr value); [DllImport(Libraries.Bundle, EntryPoint = "bundle_add_byte", CallingConvention = CallingConvention.Cdecl)] - unsafe internal static extern int AddByte(IntPtr handle, string key, byte* value, int size); + internal static extern unsafe int AddByte(IntPtr handle, string key, byte* value, int size); [DllImport(Libraries.Bundle, EntryPoint = "bundle_get_byte", CallingConvention = CallingConvention.Cdecl)] internal static extern int GetByte(IntPtr handle, string key, out IntPtr value, out int size); @@ -49,7 +49,7 @@ internal static partial class Interop internal static class UnsafeCode { - unsafe internal static void AddItem(IntPtr handle, string key, byte[] value, int offset, int count) + internal static unsafe void AddItem(IntPtr handle, string key, byte[] value, int offset, int count) { fixed (byte* pointer = value) { diff --git a/Tizen.Applications/Interop/Interop.Glib.cs b/Tizen.Applications/Interop/Interop.Glib.cs index 57c6e85..b2e3f5c 100755 --- a/Tizen.Applications/Interop/Interop.Glib.cs +++ b/Tizen.Applications/Interop/Interop.Glib.cs @@ -8,7 +8,6 @@ using System; -using System.Text; using System.Runtime.InteropServices; internal static partial class Interop diff --git a/Tizen.Applications/Tizen.Applications/Actor.cs b/Tizen.Applications/Tizen.Applications/Actor.cs index 000df9b..fe4b8a1 100755 --- a/Tizen.Applications/Tizen.Applications/Actor.cs +++ b/Tizen.Applications/Tizen.Applications/Actor.cs @@ -8,7 +8,6 @@ using System; - using Tizen.UI; namespace Tizen.Applications @@ -18,123 +17,111 @@ namespace Tizen.Applications /// public abstract class Actor : Context { - internal Guid TaskId { get; set; } - - private enum ActorState - { - None = 0, - Created = 1, - Started = 2, - Resumed = 3, - Pasued = 4 - } - private ActorState _state = ActorState.None; /// /// /// - internal protected Page MainPage { get; set; } + public event EventHandler Created; /// /// /// - protected virtual void OnCreate() { } + public event EventHandler Started; /// /// /// - protected virtual void OnStart() { } + public event EventHandler Resumed; - /// + /// /// /// - protected virtual void OnPause() { } + public event EventHandler Paused; /// /// /// - protected virtual void OnResume() { } + public event EventHandler Destroyed; + + private enum ActorState + { + None = 0, + Created = 1, + Started = 2, + Resumed = 3, + Pasued = 4 + } + + internal Guid TaskId { get; set; } /// /// /// - protected virtual void OnDestroy() { } - - internal void Create() + internal protected Page MainPage { get; set; } + + internal void OnCreate(Guid taskId, AppControl control) { if (_state != ActorState.Created) { - OnCreate(); + TaskId = taskId; + _control = control; _state = ActorState.Created; + if (Created != null) + { + Created(this, EventArgs.Empty); + } } } - internal void Start() + internal void OnStart() { if (_state != ActorState.Started) { - OnStart(); _state = ActorState.Started; + if (Started != null) + { + Started(this, EventArgs.Empty); + } } } - internal void Pause() + internal void OnPause() { if (_state != ActorState.Pasued) { - OnPause(); _state = ActorState.Pasued; + if (Paused != null) + { + Paused(this, EventArgs.Empty); + } } } - internal void Resume() + internal void OnResume() { if (_state != ActorState.Resumed) { - OnResume(); _state = ActorState.Resumed; + if (Resumed != null) + { + Resumed(this, EventArgs.Empty); + } MainPage.Show(); } } - internal void Destroy() + internal void OnDestroy() { if (_state != ActorState.None) { - OnDestroy(); _state = ActorState.None; + if (Destroyed != null) + { + Destroyed(this, EventArgs.Empty); + } } } - - /// - /// - /// - /// - /// - protected void StartActor(Actor actor, AppControl control) - { - throw new NotImplementedException(); - } - - /// - /// - /// - /// - /// - protected override void StartActor(Type actorType, AppControl control) - { - - Application.StartActor(TaskId, actorType, control); - } - - /// - /// - /// - protected override void Finish() - { - Application.StopActor(this); - } } } diff --git a/Tizen.Applications/Tizen.Applications/AppControl.cs b/Tizen.Applications/Tizen.Applications/AppControl.cs index 7629eed..7420000 100755 --- a/Tizen.Applications/Tizen.Applications/AppControl.cs +++ b/Tizen.Applications/Tizen.Applications/AppControl.cs @@ -23,142 +23,22 @@ namespace Tizen.Applications /// /// /// - public static class Operations + /// + /// + /// + public AppControl(string operation, string mime, string uri) + { + _operation = operation; + _mime = mime; + _uri = uri; + } + + internal AppControl(IntPtr appControlHandle) { - /// - /// An explicit launch for a homescreen application. - /// - public const string Main = "http://tizen.org/appcontrol/operation/main"; - - /// - /// An explicit launch for an application that excludes a homescreen application. - /// - public const string Default = "http://tizen.org/appcontrol/operation/default"; - - /// - /// Provides an editable access to the given data. - /// - public const string Edit = "http://tizen.org/appcontrol/operation/edit"; - - /// - /// Displays the data. - /// - public const string View = "http://tizen.org/appcontrol/operation/view"; - - /// - /// Picks items. - /// - public const string Pick = "http://tizen.org/appcontrol/operation/pick"; - - /// - /// Creates contents. - /// - public const string CreateContent = "http://tizen.org/appcontrol/operation/create_content"; - - /// - /// Performs a call to someone. - /// - public const string Call = "http://tizen.org/appcontrol/operation/call"; - - /// - /// Delivers some data to someone else. - /// - public const string Send = "http://tizen.org/appcontrol/operation/send"; - - /// - /// Delivers text data to someone else. - /// - public const string SendText = "http://tizen.org/appcontrol/operation/send_text"; - - /// - /// Shares an item with someone else. - /// - public const string Share = "http://tizen.org/appcontrol/operation/share"; - - /// - /// Shares multiple items with someone else. - /// - public const string MultiShare = "http://tizen.org/appcontrol/operation/multi_share"; - - /// - /// Shares text data with someone else. - /// - public const string ShareText = "http://tizen.org/appcontrol/operation/share_text"; - - /// - /// Dials a number. This shows a UI with the number to be dialed, allowing the user to explicitly initiate the call. - /// - public const string Dial = "http://tizen.org/appcontrol/operation/dial"; - - /// - /// Performs a search. - /// - public const string Search = "http://tizen.org/appcontrol/operation/search"; - - /// - /// Downloads items. - /// - public const string Download = "http://tizen.org/appcontrol/operation/download"; - - /// - /// Prints contents. - /// - public const string Print = "http://tizen.org/appcontrol/operation/print"; - - /// - /// Composes a message. - /// - public const string Compose = "http://tizen.org/appcontrol/operation/compose"; - - /// - /// Can be launched by interested System-Event. - /// - public const string LaunchOnEvent = "http://tizen.org/appcontrol/operation/launch_on_event"; - - /// - /// Adds an item. - /// - public const string Add = "http://tizen.org/appcontrol/operation/add"; - - /// - /// Captures images by camera applications. - /// - public const string ImageCapture = "http://tizen.org/appcontrol/operation/image_capture"; - - /// - /// Captures videos by camera applications. - /// - public const string VideoCapture = "http://tizen.org/appcontrol/operation/video_capture"; - - /// - /// Shows system settings. - /// - public const string Setting = "http://tizen.org/appcontrol/operation/setting"; - - /// - /// Shows settings to enable Bluetooth. - /// - public const string SettingBluetoothEnable = "http://tizen.org/appcontrol/operation/setting/bt_enable"; - - /// - /// Shows settings to configure Bluetooth visibility. - /// - public const string SettingBluetoothVisibility = "http://tizen.org/appcontrol/operation/setting/bt_visibility"; - - /// - /// Shows settings to allow configuration of current location sources. - /// - public const string SettingLocation = "http://tizen.org/appcontrol/operation/setting/location"; - - /// - /// Shows NFC settings. - /// - public const string SettingNfc = "http://tizen.org/appcontrol/operation/setting/nfc"; - - /// - /// Shows settings to allow configuration of Wi-Fi. - /// - public const string SettingWifi = "http://tizen.org/appcontrol/operation/setting/wifi"; + var handle = new Interop.AppControl.SafeAppControlHandle(appControlHandle); + Interop.AppControl.GetOperation(handle, out _operation); + Interop.AppControl.GetMime(handle, out _mime); + Interop.AppControl.GetUri(handle, out _uri); } /// @@ -176,27 +56,6 @@ namespace Tizen.Applications /// public string Uri { get { return _uri; } } - internal AppControl(IntPtr appControlHandle) - { - var handle = new Interop.AppControl.SafeAppControlHandle(appControlHandle); - Interop.AppControl.GetOperation(handle, out _operation); - Interop.AppControl.GetMime(handle, out _mime); - Interop.AppControl.GetUri(handle, out _uri); - } - - /// - /// - /// - /// - /// - /// - public AppControl(string operation, string mime, string uri) - { - _operation = operation; - _mime = mime; - _uri = uri; - } - internal bool IsLaunchOperation() { if (_operation == null) return false; @@ -208,4 +67,145 @@ namespace Tizen.Applications get { return false; } } } + + /// + /// + /// + public static class Operations + { + /// + /// An explicit launch for a homescreen application. + /// + public const string Main = "http://tizen.org/appcontrol/operation/main"; + + /// + /// An explicit launch for an application that excludes a homescreen application. + /// + public const string Default = "http://tizen.org/appcontrol/operation/default"; + + /// + /// Provides an editable access to the given data. + /// + public const string Edit = "http://tizen.org/appcontrol/operation/edit"; + + /// + /// Displays the data. + /// + public const string View = "http://tizen.org/appcontrol/operation/view"; + + /// + /// Picks items. + /// + public const string Pick = "http://tizen.org/appcontrol/operation/pick"; + + /// + /// Creates contents. + /// + public const string CreateContent = "http://tizen.org/appcontrol/operation/create_content"; + + /// + /// Performs a call to someone. + /// + public const string Call = "http://tizen.org/appcontrol/operation/call"; + + /// + /// Delivers some data to someone else. + /// + public const string Send = "http://tizen.org/appcontrol/operation/send"; + + /// + /// Delivers text data to someone else. + /// + public const string SendText = "http://tizen.org/appcontrol/operation/send_text"; + + /// + /// Shares an item with someone else. + /// + public const string Share = "http://tizen.org/appcontrol/operation/share"; + + /// + /// Shares multiple items with someone else. + /// + public const string MultiShare = "http://tizen.org/appcontrol/operation/multi_share"; + + /// + /// Shares text data with someone else. + /// + public const string ShareText = "http://tizen.org/appcontrol/operation/share_text"; + + /// + /// Dials a number. This shows a UI with the number to be dialed, allowing the user to explicitly initiate the call. + /// + public const string Dial = "http://tizen.org/appcontrol/operation/dial"; + + /// + /// Performs a search. + /// + public const string Search = "http://tizen.org/appcontrol/operation/search"; + + /// + /// Downloads items. + /// + public const string Download = "http://tizen.org/appcontrol/operation/download"; + + /// + /// Prints contents. + /// + public const string Print = "http://tizen.org/appcontrol/operation/print"; + + /// + /// Composes a message. + /// + public const string Compose = "http://tizen.org/appcontrol/operation/compose"; + + /// + /// Can be launched by interested System-Event. + /// + public const string LaunchOnEvent = "http://tizen.org/appcontrol/operation/launch_on_event"; + + /// + /// Adds an item. + /// + public const string Add = "http://tizen.org/appcontrol/operation/add"; + + /// + /// Captures images by camera applications. + /// + public const string ImageCapture = "http://tizen.org/appcontrol/operation/image_capture"; + + /// + /// Captures videos by camera applications. + /// + public const string VideoCapture = "http://tizen.org/appcontrol/operation/video_capture"; + + /// + /// Shows system settings. + /// + public const string Setting = "http://tizen.org/appcontrol/operation/setting"; + + /// + /// Shows settings to enable Bluetooth. + /// + public const string SettingBluetoothEnable = "http://tizen.org/appcontrol/operation/setting/bt_enable"; + + /// + /// Shows settings to configure Bluetooth visibility. + /// + public const string SettingBluetoothVisibility = "http://tizen.org/appcontrol/operation/setting/bt_visibility"; + + /// + /// Shows settings to allow configuration of current location sources. + /// + public const string SettingLocation = "http://tizen.org/appcontrol/operation/setting/location"; + + /// + /// Shows NFC settings. + /// + public const string SettingNfc = "http://tizen.org/appcontrol/operation/setting/nfc"; + + /// + /// Shows settings to allow configuration of Wi-Fi. + /// + public const string SettingWifi = "http://tizen.org/appcontrol/operation/setting/wifi"; + } } diff --git a/Tizen.Applications/Tizen.Applications/AppControlFilter.cs b/Tizen.Applications/Tizen.Applications/AppControlFilter.cs index 2896c60..3b2ded9 100755 --- a/Tizen.Applications/Tizen.Applications/AppControlFilter.cs +++ b/Tizen.Applications/Tizen.Applications/AppControlFilter.cs @@ -25,30 +25,30 @@ namespace Tizen.Applications /// /// /// - public string Operation { get { return _operation; } } + /// + /// + /// + public AppControlFilter(string operation, string mime = null, string uri = null) + { + _operation = operation; + _mime = mime; + _uri = uri; + } /// /// /// - public string Mime { get { return _mime; } } + public string Operation { get { return _operation; } } /// /// /// - public string Uri { get { return _uri; } } + public string Mime { get { return _mime; } } /// /// /// - /// - /// - /// - public AppControlFilter(string operation, string mime = null, string uri = null) - { - _operation = operation; - _mime = mime; - _uri = uri; - } + public string Uri { get { return _uri; } } /// /// @@ -85,6 +85,16 @@ namespace Tizen.Applications return hash; } + internal bool IsMatch(AppControl e) + { + string mime = e.Mime; + if (String.IsNullOrEmpty(mime) && !String.IsNullOrEmpty(e.Uri)) + { + mime = Interop.Aul.GetMimeFromUri(e.Uri); + } + return _operation == e.Operation && IsMimeMatched(mime) && IsUriMatched(e.Uri); + } + private bool IsMimeMatched(string mime) { if (_mime == "*" || _mime == "*/*") @@ -120,15 +130,5 @@ namespace Tizen.Applications } return _uri == uri; } - - internal bool IsMatch(AppControl e) - { - string mime = e.Mime; - if (String.IsNullOrEmpty(mime) && !String.IsNullOrEmpty(e.Uri)) - { - mime = Interop.Aul.GetMimeFromUri(e.Uri); - } - return _operation == e.Operation && IsMimeMatched(mime) && IsUriMatched(e.Uri); - } } } diff --git a/Tizen.Applications/Tizen.Applications/Application.cs b/Tizen.Applications/Tizen.Applications/Application.cs index e997b1b..1cfe98f 100755 --- a/Tizen.Applications/Tizen.Applications/Application.cs +++ b/Tizen.Applications/Tizen.Applications/Application.cs @@ -23,17 +23,8 @@ namespace Tizen.Applications { private static readonly Dictionary s_filterMap = new Dictionary(); private static readonly List s_serviceList = new List(); - private static readonly List s_actorList = new List(); - - private static Actor ForegroundActor - { - get - { - return s_actorList.LastOrDefault(null); - } - } - - private static readonly Window s_window = null; + private static readonly ActorStack s_actorStack = new ActorStack(); + private static Window s_window = null; /// /// Occurs when the application starts. @@ -45,6 +36,14 @@ namespace Tizen.Applications /// public static event EventHandler Exited = delegate { }; + private static Actor ForegroundActor + { + get + { + return s_actorStack.Peek(); + } + } + /// /// Runs the application's main loop. /// @@ -61,14 +60,14 @@ namespace Tizen.Applications { if (ForegroundActor != null) { - ForegroundActor.Pause(); + ForegroundActor.OnPause(); } }; ops.OnResume = (userData) => { if (ForegroundActor != null) { - ForegroundActor.Resume(); + ForegroundActor.OnResume(); } }; ops.OnAppControl = (appControlHandle, userData) => @@ -76,27 +75,18 @@ namespace Tizen.Applications AppControl appControl = new AppControl(appControlHandle); if (appControl.IsService) { - foreach (var item in s_filterMap) + Type found = FindServiceInFilters(appControl); + if (found != null) { - if (item.Key.IsMatch(appControl) && item.Value.IsSubclassOf(typeof(Service))) - { - StartService(item.Value, appControl); - break; - } + //StartService(found, appControl); } } else { - foreach (var item in s_filterMap) + Type found = FindActorInFilters(appControl); + if (found != null) { - if (item.Key.IsMatch(appControl) && item.Value.IsSubclassOf(typeof(Actor))) - { - if (ForegroundActor == null || !appControl.IsLaunchOperation()) - { - StartActor(Guid.Empty, item.Value, appControl); - } - break; - } + //StartActor(null, ) } } }; @@ -112,15 +102,6 @@ namespace Tizen.Applications } /// - /// Hides the application. - /// - public static void Hide() - { - if (s_window != null) - s_window.InActive(); - } - - /// /// Exits the main loop of application. /// public static void Exit() @@ -194,110 +175,104 @@ namespace Tizen.Applications RegisterContext(serviceType, filters); } - private static void RegisterContext(Type contextType, AppControlFilter[] filters) + internal static void StartActor(Context caller, Type actorType, Context.ActorFlags flags, AppControl control) { - foreach (var prop in contextType.GetProperties()) + if (caller == null && actorType == null) { - foreach (var attr in prop.GetCustomAttributes(false)) - { - var filter = attr as AppControlFilter; - if (filter != null) - { - s_filterMap.Add(filter, contextType); - } - } + throw new ArgumentNullException("actorType"); } - if (filters != null) + + Actor targetActor = null; + + Actor callerActor = caller as Actor; + if (callerActor != null && ForegroundActor != callerActor) { - foreach (var filter in filters) - { - s_filterMap.Add(filter, contextType); - } + throw new InvalidOperationException("StartActor() should be called from the foreground Actor."); } - } - internal static void StartActor(Guid taskId, Type actorType, AppControl control) - { - if (!actorType.IsSubclassOf(typeof(Actor))) + if (actorType == null) { - throw new ArgumentException(actorType.FullName + " is not a subclass of Actor."); + actorType = FindActorInFilters(control); + if (actorType == null) + { + throw new ArgumentException("Could not find the matched Actor.", "control"); + } } - if (taskId != Guid.Empty && ForegroundActor != null && taskId != ForegroundActor.TaskId) + if (callerActor != null && !IsFlagSet(flags, Context.ActorFlags.NewInstance)) { - throw new InvalidOperationException("StartActor() should be called from the foreground task."); + targetActor = s_actorStack.FindInForegroundTask(actorType); } - Actor actor = (Actor)Activator.CreateInstance(actorType); - actor.TaskId = taskId == Guid.Empty ? Guid.NewGuid() : taskId; - actor._control = control; - actor.Create(); - - if (ForegroundActor != null) + if (s_window == null) { - ForegroundActor.Pause(); + s_window = new Window(); } - s_actorList.Add(actor); - actor.Start(); - if (!s_window.Visible) { s_window.Active(); s_window.Show(); } - actor.Resume(); - } - - internal static void StartActor(Actor actor, AppControl control) - { - if (ForegroundActor == null) - { - throw new ArgumentNullException("ForegroundActor", "The Actor stack is empty."); - } - if (actor.TaskId != ForegroundActor.TaskId) + if (targetActor == null) { - throw new InvalidOperationException("StartActor() should be called from the foreground task."); + targetActor = (Actor)Activator.CreateInstance(actorType); + targetActor.OnCreate(callerActor != null ? callerActor.TaskId : Guid.NewGuid(), control); + s_actorStack.Push(targetActor); } - - while (actor != ForegroundActor) + else { - Actor popped = ForegroundActor; - s_actorList.Remove(popped); - popped.Pause(); - popped.Destroy(); + if (IsFlagSet(flags, Context.ActorFlags.ClearTop)) + { + while (targetActor != ForegroundActor) + { + Actor popped = s_actorStack.Pop(); + popped.OnPause(); + popped.OnDestroy(); + } + } + else if (IsFlagSet(flags, Context.ActorFlags.MoveToTop)) + { + if (ForegroundActor != targetActor) + { + ForegroundActor.OnPause(); + s_actorStack.MoveToTop(targetActor); + } + } } - actor.Resume(); + ForegroundActor.OnStart(); + ForegroundActor.OnResume(); } internal static void StopActor(Actor actor) { if (ForegroundActor == null) { - throw new ArgumentNullException("ForegroundActor", "The Actor stack is empty."); + throw new InvalidOperationException("The Actor stack is empty."); } Guid prevForegroundTaskId = ForegroundActor.TaskId; - s_actorList.Remove(actor); - actor.Pause(); - actor.Destroy(); + s_actorStack.Remove(actor); + actor.OnPause(); + actor.OnDestroy(); if (actor.TaskId == prevForegroundTaskId) { if (ForegroundActor.TaskId == actor.TaskId) { - ForegroundActor.Resume(); + ForegroundActor.OnResume(); } else { - if (s_actorList.Count == 0 && s_serviceList.Count == 0) + if (s_actorStack.Count == 0 && s_serviceList.Count == 0) { Exit(); } - else { - Hide(); + else + { + s_window.Hide(); } } } @@ -305,9 +280,20 @@ namespace Tizen.Applications internal static void StartService(Type serviceType, AppControl control) { - if (!serviceType.IsSubclassOf(typeof(Service))) + if (serviceType == null) { - throw new ArgumentException(serviceType.FullName + " is not a subclass of Service."); + serviceType = FindServiceInFilters(control); + if (serviceType == null) + { + throw new ArgumentException("Could not find the matched Service.", "control"); + } + } + else + { + if (!serviceType.IsSubclassOf(typeof(Service))) + { + throw new ArgumentException(serviceType.FullName + " is not a subclass of Service.", "serviceType"); + } } Service svc = s_serviceList.Find(s => s.GetType() == serviceType); @@ -315,10 +301,9 @@ namespace Tizen.Applications { svc = (Service)Activator.CreateInstance(serviceType); s_serviceList.Add(svc); - svc.Create(); + svc.OnCreate(control); } - svc._control = control; - svc.Start(); + svc.OnStart(); } internal static void StopService(Type serviceType) @@ -331,7 +316,7 @@ namespace Tizen.Applications Service svc = s_serviceList.Find(s => s.GetType() == serviceType); if (svc != null) { - svc.Destroy(); + svc.OnDestroy(); s_serviceList.Remove(svc); if (ForegroundActor == null && s_serviceList.Count == 0) { @@ -339,5 +324,121 @@ namespace Tizen.Applications } } } + + internal static void Finish(Context caller) + { + if (caller is Actor) + { + StopActor(caller as Actor); + } + else if (caller is Service) + { + // TODO: check the value of GetType() + StopService(caller.GetType()); + } + } + + private static Type FindActorInFilters(AppControl control) + { + foreach (var item in s_filterMap) + { + if (item.Key.IsMatch(control) && item.Value.IsSubclassOf(typeof(Actor))) + { + return item.Value; + } + } + return null; + } + + private static Type FindServiceInFilters(AppControl control) + { + foreach (var item in s_filterMap) + { + if (item.Key.IsMatch(control) && item.Value.IsSubclassOf(typeof(Service))) + { + return item.Value; + } + } + return null; + } + + private static void RegisterContext(Type contextType, AppControlFilter[] filters) + { + foreach (var prop in contextType.GetProperties()) + { + foreach (var attr in prop.GetCustomAttributes(false)) + { + var filter = attr as AppControlFilter; + if (filter != null) + { + s_filterMap.Add(filter, contextType); + } + } + } + if (filters != null) + { + foreach (var filter in filters) + { + s_filterMap.Add(filter, contextType); + } + } + } + + private static bool IsFlagSet(Context.ActorFlags flags, Context.ActorFlags values) + { + return (values & flags) == values; + } + + + private class ActorStack + { + private readonly List _actorList; + + public int Count + { + get + { + return _actorList.Count; + } + } + + public ActorStack() + { + _actorList = new List(); + } + + public Actor Peek() + { + return _actorList.LastOrDefault(null); + } + + public void Push(Actor item) + { + _actorList.Add(item); + } + + public Actor Pop() + { + Actor last = Peek(); + _actorList.Remove(last); + return last; + } + + public void Remove(Actor actor) + { + _actorList.Remove(actor); + } + + public Actor FindInForegroundTask(Type actorType) + { + return _actorList.Find(s => s.GetType() == actorType && s.TaskId == Peek().TaskId); + } + + public void MoveToTop(Actor actor) + { + _actorList.Remove(actor); + _actorList.Add(actor); + } + } } } diff --git a/Tizen.Applications/Tizen.Applications/Bundle.cs b/Tizen.Applications/Tizen.Applications/Bundle.cs index ab09285..f8d7dea 100755 --- a/Tizen.Applications/Tizen.Applications/Bundle.cs +++ b/Tizen.Applications/Tizen.Applications/Bundle.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; @@ -17,6 +17,15 @@ namespace Tizen.Applications private bool _disposed = false; private readonly List _keys; + /// + /// The Bundle constructor. + /// + public Bundle() + { + _keys = new List(); + _handle = Interop.Bundle.Create(); + } + private enum BundleTypeProperty { Array = 0x0100, @@ -55,39 +64,7 @@ namespace Tizen.Applications return _keys; } } - - /// - /// The Bundle constructor. - /// - public Bundle() - { - _keys = new List(); - _handle = Interop.Bundle.Create(); - } - - protected virtual void Dispose(bool disposing) - { - if (!_disposed) - { - if (disposing) - { - // to be used if there are any other disposable objects - } - if (_handle != IntPtr.Zero) - { - Interop.Bundle.Free(_handle); - _handle = IntPtr.Zero; - } - - _disposed = true; - } - } - - ~Bundle() - { - Dispose(false); - } - + /// /// Releases any unmanaged resources used by this object. /// @@ -166,19 +143,6 @@ namespace Tizen.Applications } } - private void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray) - { - managedArray = new string[size]; - IntPtr[] IntPtrArray = new IntPtr[size]; - - Marshal.Copy(unmanagedArray, IntPtrArray, 0, size); - - for (int iterator = 0; iterator < size; iterator++) - { - managedArray[iterator] = Marshal.PtrToStringAuto(IntPtrArray[iterator]); - } - } - /// /// Gets the value of a bundle item with a specified key. /// @@ -192,33 +156,33 @@ namespace Tizen.Applications switch (type) { case (int)BundleType.String: - // get string - IntPtr stringPtr; - Interop.Bundle.GetString(_handle, key, out stringPtr); - string stringResult = Marshal.PtrToStringAuto(stringPtr); - return stringResult; + // get string + IntPtr stringPtr; + Interop.Bundle.GetString(_handle, key, out stringPtr); + string stringResult = Marshal.PtrToStringAuto(stringPtr); + return stringResult; case (int)BundleType.StringArray: - // get string array - IntPtr stringArrayPtr; - int stringArraySize; - stringArrayPtr = Interop.Bundle.GetStringArray(_handle, key, out stringArraySize); - string[] stringArray; - IntPtrToStringArray(stringArrayPtr, stringArraySize, out stringArray); - return stringArray; + // get string array + IntPtr stringArrayPtr; + int stringArraySize; + stringArrayPtr = Interop.Bundle.GetStringArray(_handle, key, out stringArraySize); + string[] stringArray; + IntPtrToStringArray(stringArrayPtr, stringArraySize, out stringArray); + return stringArray; case (int)BundleType.Byte: case (int)BundleType.ByteArray: - // get byte array - IntPtr byteArrayPtr; - int byteArraySize; - Interop.Bundle.GetByte(_handle, key, out byteArrayPtr, out byteArraySize); - byte[] byteArray = new byte[byteArraySize]; - Marshal.Copy(byteArrayPtr, byteArray, 0, byteArraySize); - return byteArray; + // get byte array + IntPtr byteArrayPtr; + int byteArraySize; + Interop.Bundle.GetByte(_handle, key, out byteArrayPtr, out byteArraySize); + byte[] byteArray = new byte[byteArraySize]; + Marshal.Copy(byteArrayPtr, byteArray, 0, byteArraySize); + return byteArray; default: - return "PROBLEM"; // TODO: Handle this + return "PROBLEM"; // TODO: Handle this } } else @@ -243,5 +207,45 @@ namespace Tizen.Applications // TODO: handle when key does not exist } } + + /// + /// + /// + /// + protected virtual void Dispose(bool disposing) + { + if (!_disposed) + { + if (disposing) + { + // to be used if there are any other disposable objects + } + if (_handle != IntPtr.Zero) + { + Interop.Bundle.Free(_handle); + _handle = IntPtr.Zero; + } + + _disposed = true; + } + } + + ~Bundle() + { + Dispose(false); + } + + private void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray) + { + managedArray = new string[size]; + IntPtr[] IntPtrArray = new IntPtr[size]; + + Marshal.Copy(unmanagedArray, IntPtrArray, 0, size); + + for (int iterator = 0; iterator < size; iterator++) + { + managedArray[iterator] = Marshal.PtrToStringAuto(IntPtrArray[iterator]); + } + } } } diff --git a/Tizen.Applications/Tizen.Applications/Context.cs b/Tizen.Applications/Tizen.Applications/Context.cs index 016d8a8..7e0a786 100755 --- a/Tizen.Applications/Tizen.Applications/Context.cs +++ b/Tizen.Applications/Tizen.Applications/Context.cs @@ -17,6 +17,14 @@ namespace Tizen.Applications public abstract class Context { internal AppControl _control; + + [Flags] + public enum ActorFlags + { + NewInstance = 1, + ClearTop = 2, + MoveToTop = 4, + } /// /// @@ -34,7 +42,20 @@ namespace Tizen.Applications /// /// /// - protected abstract void StartActor(Type actorType, AppControl control); + protected void StartActor(Type actorType, AppControl control, ActorFlags flags = ActorFlags.NewInstance) + { + Application.StartActor(this, actorType, ActorFlags.NewInstance, control); + } + + /// + /// + /// + /// + /// + protected void StartActor(AppControl control, ActorFlags flags = ActorFlags.NewInstance) + { + Application.StartActor(this, null, ActorFlags.NewInstance, control); + } /// /// @@ -49,6 +70,15 @@ namespace Tizen.Applications /// /// /// + /// + protected void StartService(AppControl control) + { + Application.StartService(null, control); + } + + /// + /// + /// /// protected void StopService(Type serviceType) { @@ -58,7 +88,10 @@ namespace Tizen.Applications /// /// /// - protected abstract void Finish(); + protected void Finish() + { + Application.Finish(this); + } /// /// diff --git a/Tizen.Applications/Tizen.Applications/Service.cs b/Tizen.Applications/Tizen.Applications/Service.cs index d6a9e8a..de274c8 100755 --- a/Tizen.Applications/Tizen.Applications/Service.cs +++ b/Tizen.Applications/Tizen.Applications/Service.cs @@ -19,49 +19,41 @@ namespace Tizen.Applications /// /// /// - protected virtual void OnCreate() { } + public event EventHandler Created; /// /// /// - protected virtual void OnStart() { } + public event EventHandler Started; /// /// /// - protected virtual void OnDestroy() { } + public event EventHandler Destroyed; - internal void Create() + internal void OnCreate(AppControl control) { - OnCreate(); + _control = control; + if (Created != null) + { + Created(this, EventArgs.Empty); + } } - internal void Start() + internal void OnStart() { - OnStart(); + if (Started != null) + { + Started(this, EventArgs.Empty); + } } - internal void Destroy() + internal void OnDestroy() { - OnDestroy(); - } - - /// - /// - /// - /// - /// - protected override void StartActor(Type actorType, AppControl control) - { - Application.StartActor(Guid.Empty, actorType, control); - } - - /// - /// - /// - protected override void Finish() - { - Application.StopService(GetType()); + if (Destroyed != null) + { + Destroyed(this, EventArgs.Empty); + } } } } diff --git a/Tizen.Applications/Tizen.Applications/TizenSynchronizationContext.cs b/Tizen.Applications/Tizen.Applications/TizenSynchronizationContext.cs index 26da27f..1fc54fb 100755 --- a/Tizen.Applications/Tizen.Applications/TizenSynchronizationContext.cs +++ b/Tizen.Applications/Tizen.Applications/TizenSynchronizationContext.cs @@ -15,20 +15,21 @@ namespace Tizen.Applications { internal class TizenSynchronizationContext : SynchronizationContext { - public static void Initialize() - { - SetSynchronizationContext(new TizenSynchronizationContext()); - } - private Interop.Glib.GSourceFunc _wrapperHandler; - private Object _transactionLock = new Object(); + private readonly Interop.Glib.GSourceFunc _wrapperHandler; + private readonly Object _transactionLock = new Object(); + private readonly Dictionary _handlerMap = new Dictionary(); private int _transactionID = 0; - private Dictionary _handlerMap = new Dictionary(); private TizenSynchronizationContext() { _wrapperHandler = new Interop.Glib.GSourceFunc(Handler); } + public static void Initialize() + { + SetSynchronizationContext(new TizenSynchronizationContext()); + } + public override void Post(SendOrPostCallback d, object state) { Post(() => -- 2.7.4