Fix lifecycles
authorWonYoung Choi <wy80.choi@samsung.com>
Sat, 12 Mar 2016 11:39:41 +0000 (20:39 +0900)
committerWonYoung Choi <wy80.choi@samsung.com>
Sat, 12 Mar 2016 11:39:41 +0000 (20:39 +0900)
Change-Id: Ice898bd13ccd7dc08bb4c6127f28110ce6dd999d

13 files changed:
Tizen.Applications/Interop/Interop.AppControl.cs
Tizen.Applications/Interop/Interop.Application.cs
Tizen.Applications/Interop/Interop.Aul.cs
Tizen.Applications/Interop/Interop.Bundle.cs
Tizen.Applications/Interop/Interop.Glib.cs
Tizen.Applications/Tizen.Applications/Actor.cs
Tizen.Applications/Tizen.Applications/AppControl.cs
Tizen.Applications/Tizen.Applications/AppControlFilter.cs
Tizen.Applications/Tizen.Applications/Application.cs
Tizen.Applications/Tizen.Applications/Bundle.cs
Tizen.Applications/Tizen.Applications/Context.cs
Tizen.Applications/Tizen.Applications/Service.cs
Tizen.Applications/Tizen.Applications/TizenSynchronizationContext.cs

index 2f3ac14..69f10d0 100755 (executable)
@@ -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;
             }
         }
index 31e5304..bbb04fe 100755 (executable)
@@ -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();
     }
 }
index 439a35a..0100d72 100755 (executable)
@@ -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);
     }
 }
index 11097f9..eccd3c8 100755 (executable)
@@ -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)
                 {
index 57c6e85..b2e3f5c 100755 (executable)
@@ -8,7 +8,6 @@
 
 
 using System;
-using System.Text;
 using System.Runtime.InteropServices;
 
 internal static partial class Interop
index 000df9b..fe4b8a1 100755 (executable)
@@ -8,7 +8,6 @@
 
 
 using System;
-
 using Tizen.UI;
 
 namespace Tizen.Applications
@@ -18,123 +17,111 @@ namespace Tizen.Applications
     /// </summary>
     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;
 
         /// <summary>
         /// 
         /// </summary>
-        internal protected Page MainPage { get; set; }
+        public event EventHandler Created;
 
         /// <summary>
         /// 
         /// </summary>
-        protected virtual void OnCreate() { }
+        public event EventHandler Started;
 
         /// <summary>
         /// 
         /// </summary>
-        protected virtual void OnStart() { }
+        public event EventHandler Resumed;
 
-         /// <summary>
+        /// <summary>
         /// 
         /// </summary>
-        protected virtual void OnPause() { }
+        public event EventHandler Paused;
 
         /// <summary>
         /// 
         /// </summary>
-        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; }
 
         /// <summary>
         /// 
         /// </summary>
-        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);
+                }
             }
         }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="actor"></param>
-        /// <param name="control"></param>
-        protected void StartActor(Actor actor, AppControl control)
-        {
-            throw new NotImplementedException();
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="actorType"></param>
-        /// <param name="control"></param>
-        protected override void StartActor(Type actorType, AppControl control)
-        {
-
-            Application.StartActor(TaskId, actorType, control);
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        protected override void Finish()
-        {
-            Application.StopActor(this);
-        }
     }
 }
 
index 7629eed..7420000 100755 (executable)
@@ -23,142 +23,22 @@ namespace Tizen.Applications
         /// <summary>
         /// 
         /// </summary>
-        public static class Operations
+        /// <param name="operation"></param>
+        /// <param name="mime"></param>
+        /// <param name="uri"></param>
+        public AppControl(string operation, string mime, string uri)
+        {
+            _operation = operation;
+            _mime = mime;
+            _uri = uri;
+        }
+
+        internal AppControl(IntPtr appControlHandle)
         {
-            /// <summary>
-            /// An explicit launch for a homescreen application. 
-            /// </summary>
-            public const string Main = "http://tizen.org/appcontrol/operation/main";
-
-            /// <summary>
-            /// An explicit launch for an application that excludes a homescreen application. 
-            /// </summary>
-            public const string Default = "http://tizen.org/appcontrol/operation/default";
-
-            /// <summary>
-            /// Provides an editable access to the given data. 
-            /// </summary>
-            public const string Edit = "http://tizen.org/appcontrol/operation/edit";
-
-            /// <summary>
-            /// Displays the data. 
-            /// </summary>
-            public const string View = "http://tizen.org/appcontrol/operation/view";
-
-            /// <summary>
-            /// Picks items. 
-            /// </summary>
-            public const string Pick = "http://tizen.org/appcontrol/operation/pick";
-
-            /// <summary>
-            /// Creates contents. 
-            /// </summary>
-            public const string CreateContent = "http://tizen.org/appcontrol/operation/create_content";
-
-            /// <summary>
-            /// Performs a call to someone. 
-            /// </summary>
-            public const string Call = "http://tizen.org/appcontrol/operation/call";
-
-            /// <summary>
-            /// Delivers some data to someone else. 
-            /// </summary>
-            public const string Send = "http://tizen.org/appcontrol/operation/send";
-
-            /// <summary>
-            /// Delivers text data to someone else. 
-            /// </summary>
-            public const string SendText = "http://tizen.org/appcontrol/operation/send_text";
-
-            /// <summary>
-            /// Shares an item with someone else. 
-            /// </summary>
-            public const string Share = "http://tizen.org/appcontrol/operation/share";
-
-            /// <summary>
-            /// Shares multiple items with someone else. 
-            /// </summary>
-            public const string MultiShare = "http://tizen.org/appcontrol/operation/multi_share";
-
-            /// <summary>
-            /// Shares text data with someone else. 
-            /// </summary>
-            public const string ShareText = "http://tizen.org/appcontrol/operation/share_text";
-
-            /// <summary>
-            /// Dials a number. This shows a UI with the number to be dialed, allowing the user to explicitly initiate the call. 
-            /// </summary>
-            public const string Dial = "http://tizen.org/appcontrol/operation/dial";
-
-            /// <summary>
-            /// Performs a search. 
-            /// </summary>
-            public const string Search = "http://tizen.org/appcontrol/operation/search";
-
-            /// <summary>
-            /// Downloads items. 
-            /// </summary>
-            public const string Download = "http://tizen.org/appcontrol/operation/download";
-
-            /// <summary>
-            /// Prints contents. 
-            /// </summary>
-            public const string Print = "http://tizen.org/appcontrol/operation/print";
-
-            /// <summary>
-            /// Composes a message. 
-            /// </summary>
-            public const string Compose = "http://tizen.org/appcontrol/operation/compose";
-
-            /// <summary>
-            /// Can be launched by interested System-Event. 
-            /// </summary>
-            public const string LaunchOnEvent = "http://tizen.org/appcontrol/operation/launch_on_event";
-
-            /// <summary>
-            /// Adds an item. 
-            /// </summary>
-            public const string Add = "http://tizen.org/appcontrol/operation/add";
-
-            /// <summary>
-            /// Captures images by camera applications. 
-            /// </summary>
-            public const string ImageCapture = "http://tizen.org/appcontrol/operation/image_capture";
-
-            /// <summary>
-            /// Captures videos by camera applications. 
-            /// </summary>
-            public const string VideoCapture = "http://tizen.org/appcontrol/operation/video_capture";
-
-            /// <summary>
-            /// Shows system settings. 
-            /// </summary>
-            public const string Setting = "http://tizen.org/appcontrol/operation/setting";
-
-            /// <summary>
-            /// Shows settings to enable Bluetooth. 
-            /// </summary>
-            public const string SettingBluetoothEnable = "http://tizen.org/appcontrol/operation/setting/bt_enable";
-
-            /// <summary>
-            /// Shows settings to configure Bluetooth visibility. 
-            /// </summary>
-            public const string SettingBluetoothVisibility = "http://tizen.org/appcontrol/operation/setting/bt_visibility";
-
-            /// <summary>
-            /// Shows settings to allow configuration of current location sources. 
-            /// </summary>
-            public const string SettingLocation = "http://tizen.org/appcontrol/operation/setting/location";
-
-            /// <summary>
-            /// Shows NFC settings. 
-            /// </summary>
-            public const string SettingNfc = "http://tizen.org/appcontrol/operation/setting/nfc";
-
-            /// <summary>
-            /// Shows settings to allow configuration of Wi-Fi. 
-            /// </summary>
-            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);
         }
 
         /// <summary>
@@ -176,27 +56,6 @@ namespace Tizen.Applications
         /// </summary>
         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);
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="operation"></param>
-        /// <param name="mime"></param>
-        /// <param name="uri"></param>
-        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; }
         }
     }
+
+    /// <summary>
+    /// 
+    /// </summary>
+    public static class Operations
+    {
+        /// <summary>
+        /// An explicit launch for a homescreen application. 
+        /// </summary>
+        public const string Main = "http://tizen.org/appcontrol/operation/main";
+
+        /// <summary>
+        /// An explicit launch for an application that excludes a homescreen application. 
+        /// </summary>
+        public const string Default = "http://tizen.org/appcontrol/operation/default";
+
+        /// <summary>
+        /// Provides an editable access to the given data. 
+        /// </summary>
+        public const string Edit = "http://tizen.org/appcontrol/operation/edit";
+
+        /// <summary>
+        /// Displays the data. 
+        /// </summary>
+        public const string View = "http://tizen.org/appcontrol/operation/view";
+
+        /// <summary>
+        /// Picks items. 
+        /// </summary>
+        public const string Pick = "http://tizen.org/appcontrol/operation/pick";
+
+        /// <summary>
+        /// Creates contents. 
+        /// </summary>
+        public const string CreateContent = "http://tizen.org/appcontrol/operation/create_content";
+
+        /// <summary>
+        /// Performs a call to someone. 
+        /// </summary>
+        public const string Call = "http://tizen.org/appcontrol/operation/call";
+
+        /// <summary>
+        /// Delivers some data to someone else. 
+        /// </summary>
+        public const string Send = "http://tizen.org/appcontrol/operation/send";
+
+        /// <summary>
+        /// Delivers text data to someone else. 
+        /// </summary>
+        public const string SendText = "http://tizen.org/appcontrol/operation/send_text";
+
+        /// <summary>
+        /// Shares an item with someone else. 
+        /// </summary>
+        public const string Share = "http://tizen.org/appcontrol/operation/share";
+
+        /// <summary>
+        /// Shares multiple items with someone else. 
+        /// </summary>
+        public const string MultiShare = "http://tizen.org/appcontrol/operation/multi_share";
+
+        /// <summary>
+        /// Shares text data with someone else. 
+        /// </summary>
+        public const string ShareText = "http://tizen.org/appcontrol/operation/share_text";
+
+        /// <summary>
+        /// Dials a number. This shows a UI with the number to be dialed, allowing the user to explicitly initiate the call. 
+        /// </summary>
+        public const string Dial = "http://tizen.org/appcontrol/operation/dial";
+
+        /// <summary>
+        /// Performs a search. 
+        /// </summary>
+        public const string Search = "http://tizen.org/appcontrol/operation/search";
+
+        /// <summary>
+        /// Downloads items. 
+        /// </summary>
+        public const string Download = "http://tizen.org/appcontrol/operation/download";
+
+        /// <summary>
+        /// Prints contents. 
+        /// </summary>
+        public const string Print = "http://tizen.org/appcontrol/operation/print";
+
+        /// <summary>
+        /// Composes a message. 
+        /// </summary>
+        public const string Compose = "http://tizen.org/appcontrol/operation/compose";
+
+        /// <summary>
+        /// Can be launched by interested System-Event. 
+        /// </summary>
+        public const string LaunchOnEvent = "http://tizen.org/appcontrol/operation/launch_on_event";
+
+        /// <summary>
+        /// Adds an item. 
+        /// </summary>
+        public const string Add = "http://tizen.org/appcontrol/operation/add";
+
+        /// <summary>
+        /// Captures images by camera applications. 
+        /// </summary>
+        public const string ImageCapture = "http://tizen.org/appcontrol/operation/image_capture";
+
+        /// <summary>
+        /// Captures videos by camera applications. 
+        /// </summary>
+        public const string VideoCapture = "http://tizen.org/appcontrol/operation/video_capture";
+
+        /// <summary>
+        /// Shows system settings. 
+        /// </summary>
+        public const string Setting = "http://tizen.org/appcontrol/operation/setting";
+
+        /// <summary>
+        /// Shows settings to enable Bluetooth. 
+        /// </summary>
+        public const string SettingBluetoothEnable = "http://tizen.org/appcontrol/operation/setting/bt_enable";
+
+        /// <summary>
+        /// Shows settings to configure Bluetooth visibility. 
+        /// </summary>
+        public const string SettingBluetoothVisibility = "http://tizen.org/appcontrol/operation/setting/bt_visibility";
+
+        /// <summary>
+        /// Shows settings to allow configuration of current location sources. 
+        /// </summary>
+        public const string SettingLocation = "http://tizen.org/appcontrol/operation/setting/location";
+
+        /// <summary>
+        /// Shows NFC settings. 
+        /// </summary>
+        public const string SettingNfc = "http://tizen.org/appcontrol/operation/setting/nfc";
+
+        /// <summary>
+        /// Shows settings to allow configuration of Wi-Fi. 
+        /// </summary>
+        public const string SettingWifi = "http://tizen.org/appcontrol/operation/setting/wifi";
+    }
 }
index 2896c60..3b2ded9 100755 (executable)
@@ -25,30 +25,30 @@ namespace Tizen.Applications
         /// <summary>
         /// 
         /// </summary>
-        public string Operation { get { return _operation; } }
+        /// <param name="operation"></param>
+        /// <param name="mime"></param>
+        /// <param name="uri"></param>
+        public AppControlFilter(string operation, string mime = null, string uri = null)
+        {
+            _operation = operation;
+            _mime = mime;
+            _uri = uri;
+        }
 
         /// <summary>
         /// 
         /// </summary>
-        public string Mime { get { return _mime; } }
+        public string Operation { get { return _operation; } }
 
         /// <summary>
         /// 
         /// </summary>
-        public string Uri { get { return _uri; } }
+        public string Mime { get { return _mime; } }
 
         /// <summary>
         /// 
         /// </summary>
-        /// <param name="operation"></param>
-        /// <param name="mime"></param>
-        /// <param name="uri"></param>
-        public AppControlFilter(string operation, string mime = null, string uri = null)
-        {
-            _operation = operation;
-            _mime = mime;
-            _uri = uri;
-        }
+        public string Uri { get { return _uri; } }
 
         /// <summary>
         /// 
@@ -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);
-        }
     }
 }
index e997b1b..1cfe98f 100755 (executable)
@@ -23,17 +23,8 @@ namespace Tizen.Applications
     {
         private static readonly Dictionary<AppControlFilter, Type> s_filterMap = new Dictionary<AppControlFilter, Type>();
         private static readonly List<Service> s_serviceList = new List<Service>();
-        private static readonly List<Actor> s_actorList = new List<Actor>();
-
-        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;
 
         /// <summary>
         /// Occurs when the application starts.
@@ -45,6 +36,14 @@ namespace Tizen.Applications
         /// </summary>
         public static event EventHandler Exited = delegate { };
 
+        private static Actor ForegroundActor
+        {
+            get
+            {
+                return s_actorStack.Peek();
+            }
+        }
+
         /// <summary>
         /// Runs the application's main loop.
         /// </summary>
@@ -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
         }
 
         /// <summary>
-        /// Hides the application.
-        /// </summary>
-        public static void Hide()
-        {
-            if (s_window != null)
-                s_window.InActive();
-        }
-
-        /// <summary>
         /// Exits the main loop of application.
         /// </summary>
         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<Actor> _actorList;
+
+            public int Count
+            {
+                get
+                {
+                    return _actorList.Count;
+                }
+            }
+
+            public ActorStack()
+            {
+                _actorList = new List<Actor>();
+            }
+
+            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);
+            }
+        }
     }
 }
index ab09285..f8d7dea 100755 (executable)
@@ -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<string> _keys;
 
+        /// <summary>
+        /// The Bundle constructor.
+        /// </summary>
+        public Bundle()
+        {
+            _keys = new List<string>();
+            _handle = Interop.Bundle.Create();
+        }
+
         private enum BundleTypeProperty
         {
             Array = 0x0100,
@@ -55,39 +64,7 @@ namespace Tizen.Applications
                 return _keys;
             }
         }
-
-        /// <summary>
-        /// The Bundle constructor.
-        /// </summary>
-        public Bundle()
-        {
-            _keys = new List<string>();
-            _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);
-        }
-
+        
         /// <summary>
         /// Releases any unmanaged resources used by this object.
         /// </summary>
@@ -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]);
-            }
-        }
-
         /// <summary>
         /// Gets the value of a bundle item with a specified key.
         /// </summary>
@@ -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
             }
         }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="disposing"></param>
+        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]);
+            }
+        }
     }
 }
index 016d8a8..7e0a786 100755 (executable)
@@ -17,6 +17,14 @@ namespace Tizen.Applications
     public abstract class Context
     {
         internal AppControl _control;
+        
+        [Flags]
+        public enum ActorFlags
+        {
+            NewInstance = 1,
+            ClearTop = 2,
+            MoveToTop = 4,
+        }
 
         /// <summary>
         /// 
@@ -34,7 +42,20 @@ namespace Tizen.Applications
         /// </summary>
         /// <param name="actorType"></param>
         /// <param name="control"></param>
-        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);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
+        /// <param name="control"></param>
+        /// <param name="flags"></param>
+        protected void StartActor(AppControl control, ActorFlags flags = ActorFlags.NewInstance)
+        {
+            Application.StartActor(this, null, ActorFlags.NewInstance, control);
+        }
 
         /// <summary>
         /// 
@@ -49,6 +70,15 @@ namespace Tizen.Applications
         /// <summary>
         /// 
         /// </summary>
+        /// <param name="control"></param>
+        protected void StartService(AppControl control)
+        {
+            Application.StartService(null, control);
+        }
+
+        /// <summary>
+        /// 
+        /// </summary>
         /// <param name="serviceType"></param>
         protected void StopService(Type serviceType)
         {
@@ -58,7 +88,10 @@ namespace Tizen.Applications
         /// <summary>
         /// 
         /// </summary>
-        protected abstract void Finish();
+        protected void Finish()
+        {
+            Application.Finish(this);
+        }
 
         /// <summary>
         /// 
index d6a9e8a..de274c8 100755 (executable)
@@ -19,49 +19,41 @@ namespace Tizen.Applications
         /// <summary>
         /// 
         /// </summary>
-        protected virtual void OnCreate() { }
+        public event EventHandler Created;
 
         /// <summary>
         /// 
         /// </summary>
-        protected virtual void OnStart() { }
+        public event EventHandler Started;
 
         /// <summary>
         /// 
         /// </summary>
-        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();
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        /// <param name="actorType"></param>
-        /// <param name="control"></param>
-        protected override void StartActor(Type actorType, AppControl control)
-        {
-            Application.StartActor(Guid.Empty, actorType, control);
-        }
-
-        /// <summary>
-        /// 
-        /// </summary>
-        protected override void Finish()
-        {
-            Application.StopService(GetType());
+            if (Destroyed != null)
+            {
+                Destroyed(this, EventArgs.Empty);
+            }
         }
     }
 }
index 26da27f..1fc54fb 100755 (executable)
@@ -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<int, Action> _handlerMap = new Dictionary<int, Action>();
         private int _transactionID = 0;
-        private Dictionary<int, Action> _handlerMap = new Dictionary<int, Action>();
 
         private TizenSynchronizationContext()
         {
             _wrapperHandler = new Interop.Glib.GSourceFunc(Handler);
         }
 
+        public static void Initialize()
+        {
+            SetSynchronizationContext(new TizenSynchronizationContext());
+        }
+
         public override void Post(SendOrPostCallback d, object state)
         {
             Post(() =>