Add Tizen.Application namespace
authorWonYoung Choi <wy80.choi@samsung.com>
Mon, 22 Feb 2016 06:39:14 +0000 (15:39 +0900)
committerWonYoung Choi <wy80.choi@samsung.com>
Tue, 1 Mar 2016 09:39:52 +0000 (18:39 +0900)
Change-Id: Icfdee0aa2bd5a8a3bacf5193af91e0cbffd75adb

18 files changed:
Properties/AssemblyInfo.cs [new file with mode: 0755]
Tizen.Application.snk [new file with mode: 0755]
Tizen.Application/Actor.cs [new file with mode: 0755]
Tizen.Application/AppControl.cs [new file with mode: 0755]
Tizen.Application/AppControlFilter.cs [new file with mode: 0755]
Tizen.Application/Application.cs [new file with mode: 0755]
Tizen.Application/ApplicationContext.cs [new file with mode: 0755]
Tizen.Application/CodeExample.cs [new file with mode: 0755]
Tizen.Application/Interop/Interop.AppControl.cs [new file with mode: 0755]
Tizen.Application/Interop/Interop.Application.cs [new file with mode: 0755]
Tizen.Application/Interop/Interop.Libraries.cs [new file with mode: 0755]
Tizen.Application/Interop/Interop.Sys.cs [new file with mode: 0755]
Tizen.Application/Page.cs [new file with mode: 0755]
Tizen.Application/TizenSynchronizationContext.cs [new file with mode: 0755]
application.csproj [new file with mode: 0755]
packaging/csapi-application.manifest [new file with mode: 0644]
packaging/csapi-application.pc.in [new file with mode: 0644]
packaging/csapi-application.spec [new file with mode: 0644]

diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs
new file mode 100755 (executable)
index 0000000..2279397
--- /dev/null
@@ -0,0 +1,19 @@
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+[assembly: AssemblyTitle("Tizen.Application")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("Samsung Electronics")]
+[assembly: AssemblyProduct("Tizen.Application")]
+[assembly: AssemblyCopyright("Copyright (c) 2015 Samsung Electronics Co., Ltd")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+[assembly: ComVisible(false)]
+
+[assembly: Guid("d2d1a3ce-000e-4ab3-81c4-a8a44a008989")]
+
+[assembly: AssemblyVersion("1.0.0.0")]
+[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/Tizen.Application.snk b/Tizen.Application.snk
new file mode 100755 (executable)
index 0000000..7ac1b00
Binary files /dev/null and b/Tizen.Application.snk differ
diff --git a/Tizen.Application/Actor.cs b/Tizen.Application/Actor.cs
new file mode 100755 (executable)
index 0000000..a2c6b5d
--- /dev/null
@@ -0,0 +1,83 @@
+using System;
+
+namespace Tizen.Application
+{
+    public abstract class Actor
+    {
+        private enum State
+        {
+            Unknown,
+            Created,
+            Started,
+            Resumed,
+            Pasued
+        }
+
+        private ApplicationContext _context;
+        private State _state = State.Unknown;
+        private AppControl _appcontrol;
+
+        protected Page MainPage { get; set; }
+        protected AppControl ReceivedAppControl { get { return _appcontrol; } }
+
+        protected virtual void OnCreate() { }
+        protected virtual void OnStart() { }
+        protected virtual void OnPause() { }
+        protected virtual void OnResume() { }
+        protected virtual void OnTerminate() { }
+
+        internal void Create(ApplicationContext context)
+        {
+            if (_state != State.Created)
+            {
+                _context = context;
+                OnCreate();
+                _state = State.Created;
+            }
+        }
+
+        internal void Start(AppControl appControl)
+        {
+            if (_state != State.Started)
+            {
+                _appcontrol = appControl;
+                OnStart();
+                _state = State.Started;
+            }
+        }
+
+        internal void Pause()
+        {
+            if (_state != State.Pasued)
+            {
+                OnPause();
+                _state = State.Pasued;
+            }
+        }
+
+        internal void Resume()
+        {
+            if (_state != State.Resumed)
+            {
+                OnResume();
+                _state = State.Resumed;
+            }
+        }
+
+        protected void StartActor(Type actorType, AppControl appControl)
+        {
+            _context.StartActor(actorType, appControl);
+
+        }
+
+        protected void StartActor(Actor actor, AppControl appControl)
+        {
+            _context.StartActor(actor, appControl);
+        }
+
+        public void Finish()
+        {
+            throw new NotImplementedException();
+        }
+    }
+}
diff --git a/Tizen.Application/AppControl.cs b/Tizen.Application/AppControl.cs
new file mode 100755 (executable)
index 0000000..3f24576
--- /dev/null
@@ -0,0 +1,72 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Application
+{
+    // TODO To be implemented
+    public class AppControl
+    {
+        private string _operation;
+        private string _mime;
+        private string _scheme;
+        private Dictionary<string, object> _data;
+
+        public static class Operations
+        {
+            public const string Main = "http://tizen.org/appcontrol/operation/main";
+            public const string Default = "http://tizen.org/appcontrol/operation/default";
+            public const string Edit = "http://tizen.org/appcontrol/operation/edit";
+            public const string View = "http://tizen.org/appcontrol/operation/view";
+            public const string Pick = "http://tizen.org/appcontrol/operation/pick";
+            public const string CreateContent = "http://tizen.org/appcontrol/operation/create_content";
+            public const string Call = "http://tizen.org/appcontrol/operation/call";
+            public const string Send = "http://tizen.org/appcontrol/operation/send";
+            public const string SendText = "http://tizen.org/appcontrol/operation/send_text";
+            public const string Share = "http://tizen.org/appcontrol/operation/share";
+            public const string MultiShare = "http://tizen.org/appcontrol/operation/multi_share";
+            public const string ShareText = "http://tizen.org/appcontrol/operation/share_text";
+            public const string Dial = "http://tizen.org/appcontrol/operation/dial";
+            public const string Search = "http://tizen.org/appcontrol/operation/search";
+            public const string Download = "http://tizen.org/appcontrol/operation/download";
+            public const string Print = "http://tizen.org/appcontrol/operation/print";
+            public const string Compose = "http://tizen.org/appcontrol/operation/compose";
+            public const string LaunchOnEvent = "http://tizen.org/appcontrol/operation/launch_on_event";
+            public const string Add = "http://tizen.org/appcontrol/operation/add";
+            public const string ImageCapture = "http://tizen.org/appcontrol/operation/image_capture";
+            public const string VideoCapture = "http://tizen.org/appcontrol/operation/video_capture";
+            public const string Setting = "http://tizen.org/appcontrol/operation/setting";
+            public const string SettingBtEnable = "http://tizen.org/appcontrol/operation/setting/bt_enable";
+            public const string SettingBtVisibility = "http://tizen.org/appcontrol/operation/setting/bt_visibility";
+            public const string SettingLocation = "http://tizen.org/appcontrol/operation/setting/location";
+            public const string SettingNfc = "http://tizen.org/appcontrol/operation/setting/nfc";
+            public const string SettingWifi = "http://tizen.org/appcontrol/operation/setting/wifi";
+        }
+
+        public string Operation { get { return _operation; } }
+        public string Mime { get { return _mime; } }
+        public string Scheme { get { return _scheme; } }
+
+        internal AppControl(IntPtr appControlHandle)
+        {
+            var handle = new Interop.AppControl.SafeAppControlHandle(appControlHandle);
+            _operation = Interop.AppControl.GetOperation(handle);
+            _mime = Interop.AppControl.GetMime(handle);
+            _scheme = Interop.AppControl.GetScheme(handle);
+        }
+
+        public AppControl(string operation, string mime, string scheme)
+        {
+            _operation = operation;
+            _mime = mime;
+            _scheme = scheme;
+        }
+
+        public bool IsLaunchOperation()
+        {
+            if (_operation == null) return false;
+            return (_operation == Operations.Main) || (_operation == Operations.Default);
+        }
+
+    }
+}
diff --git a/Tizen.Application/AppControlFilter.cs b/Tizen.Application/AppControlFilter.cs
new file mode 100755 (executable)
index 0000000..53dd61f
--- /dev/null
@@ -0,0 +1,55 @@
+using System;
+
+namespace Tizen.Application
+{
+    [AttributeUsage(AttributeTargets.Class)]
+    public class AppControlFilter : Attribute
+    {
+        private readonly string _operation;
+        private readonly string _mime;
+        private readonly string _scheme;
+
+        public string Operation { get { return _operation; } }
+        public string Mime { get { return _mime; } }
+        public string Scheme { get { return _scheme; } }
+
+        public AppControlFilter(string operation, string mime = null, string scheme = null)
+        {
+            _operation = operation;
+            _mime = mime;
+            _scheme = scheme;
+        }
+
+        public override bool Equals(object obj)
+        {
+            AppControlFilter f = obj as AppControlFilter;
+            if (f == null) return false;
+
+            return (_operation == f._operation) & (_mime == f._mime) & (_scheme == f._scheme);
+        }
+
+        public override int GetHashCode()
+        {
+            int hash = 0;
+            if (_operation != null)
+            {
+                hash ^= _operation.GetHashCode();
+            }
+            if (_mime != null)
+            {
+                hash ^= _mime.GetHashCode();
+            }
+            if (_scheme != null)
+            {
+                hash ^= _scheme.GetHashCode();
+            }
+            return hash;
+        }
+
+        public bool IsMatched(AppControl e)
+        {
+            throw new NotImplementedException();            
+        }
+    }
+
+}
diff --git a/Tizen.Application/Application.cs b/Tizen.Application/Application.cs
new file mode 100755 (executable)
index 0000000..406a86e
--- /dev/null
@@ -0,0 +1,125 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Runtime.InteropServices;
+
+namespace Tizen.Application
+{
+    public static class Application
+    {
+        private static Dictionary<string, Type> _actorMap = new Dictionary<string, Type>();
+        private static Dictionary<AppControlFilter, Type> _filterMap = new Dictionary<AppControlFilter, Type>();
+        private static List<ApplicationContext> _contextList = new List<ApplicationContext>();
+
+        public static event EventHandler ApplicationInit;
+        public static event EventHandler ApplicationExit;
+
+        public static ApplicationContext CurrentContext { get { return _contextList.LastOrDefault(null); } }
+
+        public static int Run(string[] args)
+        {
+            Interop.Application.UIAppLifecycleCallbacks ops;
+            ops.OnCreate = (userData) =>
+            {
+                _contextList.Add(new ApplicationContext());
+                ApplicationInit(null, null);
+                return true;
+            };
+            ops.OnPause = (userData) =>
+            {
+                if (CurrentContext != null)
+                {
+                    CurrentContext.Pause();
+                }
+            };
+            ops.OnResume = (userData) =>
+            {
+                if (CurrentContext != null)
+                {
+                    CurrentContext.Resume();
+                }
+            };
+            ops.OnAppControl = (appControlHandle, userData) =>
+            {
+                AppControl appControl = new AppControl(appControlHandle);
+                foreach (var item in _filterMap)
+                {
+                    if (item.Key.IsMatched(appControl))
+                    {
+                        // Relaunch?
+                        if (appControl.IsLaunchOperation() && CurrentContext != null && !CurrentContext.Empty())
+                        {
+                            // TODO: Resume should be called by windows event
+                            CurrentContext.Resume();
+                        }
+                        // Create new context and new actor when launching first or receiving appcontrol except launch.
+                        else
+                        {
+                            ApplicationContext ctx = new ApplicationContext();
+                            _contextList.Add(ctx);
+                            Actor actor = ctx.StartActor(item.Value, appControl);
+                            // TODO: Resume should be called by windows event
+                            actor.Resume();
+                        }
+                        break;
+                    }
+                }
+            };
+            ops.OnTerminate = (userData) =>
+            {
+                // TODO: Remove context and actors
+                ApplicationExit(null, null);
+            };
+
+            TizenSynchronizationContext.Initialize();
+
+            int ret = Interop.Application.UIAppMain(args.Length, args, ref ops, IntPtr.Zero);
+
+            return ret;
+        }
+
+
+
+        public static void AddActor(Type clazz)
+        {
+            AddActor(clazz, new AppControlFilter[0] { });
+        }
+
+        public static void AddActor(Type clazz, AppControlFilter filter)
+        {
+            AddActor(clazz, new AppControlFilter[] { filter });
+        }
+
+        public static void AddActor(Type clazz, AppControlFilter[] filters)
+        {
+            if (!clazz.IsSubclassOf(typeof(Actor)))
+                throw new ArgumentException(clazz.FullName + " is not a subclass of Actor.");
+
+            _actorMap[clazz.FullName] = clazz;
+
+            foreach (var prop in clazz.GetProperties())
+            {
+                foreach (var attr in prop.GetCustomAttributes(false))
+                {
+                    var filter = attr as AppControlFilter;
+                    if (filter != null)
+                    {
+                        _filterMap.Add(filter, clazz);
+                    }
+                }
+            }
+            if (filters != null)
+            {
+                foreach (var filter in filters)
+                {
+                    _filterMap.Add(filter, clazz);
+                }
+            }
+        }
+
+    }
+
+
+}
diff --git a/Tizen.Application/ApplicationContext.cs b/Tizen.Application/ApplicationContext.cs
new file mode 100755 (executable)
index 0000000..d9864e4
--- /dev/null
@@ -0,0 +1,63 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.Application
+{
+    public class ApplicationContext
+    {
+        private List<Actor> _actorList;
+
+        internal Actor TopActor { get { return _actorList.LastOrDefault(null); } }
+
+        internal ApplicationContext()
+        {
+            _actorList = new List<Actor>();
+        }
+
+        internal Actor StartActor(Type actorType, AppControl appControl)
+        {
+            Actor newActor = (Actor)Activator.CreateInstance(actorType);
+            _actorList.Add(newActor);
+            newActor.Create(this);
+            newActor.Start(appControl);
+            return newActor;
+        }
+
+        internal Actor StartActor(Actor actor, AppControl appControl)
+        {
+            Actor found = _actorList.Find(s => s == actor);
+            if (found == null)
+            {
+                throw new ArgumentException("Could not found the actor in current context.");
+            }
+            _actorList.Remove(found);
+            _actorList.Add(found);
+            found.Start(appControl);
+            return found;
+        }
+
+        internal void Pause()
+        {
+            if (TopActor != null)
+            {
+                TopActor.Pause();
+            }
+        }
+
+        internal void Resume()
+        {
+            if (TopActor != null)
+            {
+                TopActor.Resume();
+            }
+        }
+
+        internal bool Empty()
+        {
+            return _actorList.Count == 0;
+        }
+    }
+}
diff --git a/Tizen.Application/CodeExample.cs b/Tizen.Application/CodeExample.cs
new file mode 100755 (executable)
index 0000000..7761e07
--- /dev/null
@@ -0,0 +1,66 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.Application
+{
+    public class ViewActor : Actor
+    {
+        public string Type { get; set; }
+        protected override void OnCreate()
+        {
+            Console.WriteLine();
+        }
+
+        protected override void OnStart()
+        {
+        }
+
+        private void DoSomething()
+        {
+        }
+    }
+
+    [AppControlFilter("http://tizen.org/appcontrol/operation/default")]
+    public class DefaultActor : Actor
+    {
+        protected override void OnCreate()
+        {
+        }
+
+        protected override void OnStart()
+        {
+        }
+    }
+
+    public class Test
+    {
+        static void test(string[] args) // main
+        {
+            Application.ApplicationInit += Application_Create;
+            Application.ApplicationExit += Application_Terminate;
+            Application.AddActor(typeof(DefaultActor));
+            Application.AddActor(typeof(ViewActor), new AppControlFilter[] {
+                new AppControlFilter("http://tizen.org/appcontrol/view", "image/*"),
+                new AppControlFilter("http://tizen.org/appcontrol/view", "text/*")
+            });
+
+            Application.Run(args);
+        }
+
+        private static void Application_Create(object sender, EventArgs e)
+        {
+            Console.WriteLine("Hello Application!");
+        }
+
+        private static void Application_Terminate(object sender, EventArgs e)
+        {
+            Console.WriteLine("Goodbye Application!");
+        }
+    }
+
+
+}
diff --git a/Tizen.Application/Interop/Interop.AppControl.cs b/Tizen.Application/Interop/Interop.AppControl.cs
new file mode 100755 (executable)
index 0000000..c567521
--- /dev/null
@@ -0,0 +1,139 @@
+/// Copyright 2016 by Samsung Electronics, Inc.,
+///
+/// This software is the confidential and proprietary information
+/// of Samsung Electronics, Inc. ("Confidential Information"). You
+/// shall not disclose such Confidential Information and shall use
+/// it only in accordance with the terms of the license agreement
+/// you entered into with Samsung.
+
+using System;
+using System.Runtime.InteropServices;
+using System.Diagnostics;
+
+internal static partial class Interop
+{
+    internal static partial class AppControl
+    {
+        [DllImport(Libraries.Application, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int app_control_create(out SafeAppControlHandle handle);
+
+        [DllImport(Libraries.Application, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int app_control_destroy(IntPtr handle);
+
+        [DllImport(Libraries.Application, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int app_control_clone(out IntPtr clone, IntPtr handle);
+
+        [DllImport(Libraries.Application, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int app_control_get_app_id(IntPtr app_control, out IntPtr app_id);
+
+        [DllImport(Libraries.Application, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int app_control_get_operation(SafeAppControlHandle handle, out IntPtr operation);
+
+        [DllImport(Libraries.Application, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int app_control_get_uri(SafeAppControlHandle handle, out IntPtr uri);
+
+        [DllImport(Libraries.Application, CallingConvention = CallingConvention.Cdecl)]
+        private static extern int app_control_get_mime(SafeAppControlHandle handle, out IntPtr mime);
+
+        internal static SafeAppControlHandle CreateHandle()
+        {
+            SafeAppControlHandle handle;
+            int err = app_control_create(out handle);
+            if (err == 0)
+            {
+                return handle;
+            }
+            else
+            {
+                Debug.WriteLine("Failed to create app_control handle. err = {0}", err);
+                return null;
+            }
+        }
+
+        internal static string GetOperation(SafeAppControlHandle handle)
+        {
+            IntPtr value = IntPtr.Zero;
+            try
+            {
+                int err = app_control_get_operation(handle, out value);
+                if (err == 0)
+                {
+                    return Marshal.PtrToStringAuto(value);
+                }
+            }
+            finally
+            {
+                if (value != IntPtr.Zero)
+                {
+                    Sys.Free(value);
+                }
+            }
+            return null;
+        }
+
+        internal static string GetMime(SafeAppControlHandle handle)
+        {
+            IntPtr value = IntPtr.Zero;
+            try
+            {
+                int err = app_control_get_mime(handle, out value);
+                if (err == 0)
+                {
+                    return Marshal.PtrToStringAuto(value);
+                }
+            }
+            finally
+            {
+                if (value != IntPtr.Zero)
+                {
+                    Sys.Free(value);
+                }
+            }
+            return null;
+        }
+
+        internal static string GetScheme(SafeAppControlHandle handle)
+        {
+            IntPtr value = IntPtr.Zero;
+            try
+            {
+                int err = app_control_get_uri(handle, out value);
+                if (err == 0)
+                {
+                    return Marshal.PtrToStringAuto(value);
+                }
+            }
+            finally
+            {
+                if (value != IntPtr.Zero)
+                {
+                    Sys.Free(value);
+                }
+            }
+            return null;
+        }
+
+        internal sealed class SafeAppControlHandle : SafeHandle
+        {
+            public SafeAppControlHandle() : base(IntPtr.Zero, true)
+            {
+            }
+
+            public SafeAppControlHandle(IntPtr handle) : base(handle, false)
+            {
+            }
+
+            public override bool IsInvalid
+            {
+                get { return handle == IntPtr.Zero; }
+            }
+
+            protected override bool ReleaseHandle()
+            {
+                app_control_destroy(handle);
+                SetHandle(IntPtr.Zero);
+                return true;
+            }
+        }
+    }
+}
diff --git a/Tizen.Application/Interop/Interop.Application.cs b/Tizen.Application/Interop/Interop.Application.cs
new file mode 100755 (executable)
index 0000000..0f36da9
--- /dev/null
@@ -0,0 +1,36 @@
+/// Copyright 2016 by Samsung Electronics, Inc.,
+///
+/// This software is the confidential and proprietary information
+/// of Samsung Electronics, Inc. ("Confidential Information"). You
+/// shall not disclose such Confidential Information and shall use
+/// it only in accordance with the terms of the license agreement
+/// you entered into with Samsung.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Application
+    {
+        internal delegate bool AppCreateCallback(IntPtr userData);
+        internal delegate void AppPauseCallback(IntPtr userData);
+        internal delegate void AppResumeCallback(IntPtr userData);
+        internal delegate void AppTerminateCallback(IntPtr userData);
+        internal delegate void AppControlCallback(IntPtr appControl, IntPtr userData);
+
+        [StructLayoutAttribute(LayoutKind.Sequential)]
+        internal struct UIAppLifecycleCallbacks
+        {
+            public AppCreateCallback OnCreate;
+            public AppTerminateCallback OnTerminate;
+            public AppPauseCallback OnPause;
+            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);
+
+    }
+}
diff --git a/Tizen.Application/Interop/Interop.Libraries.cs b/Tizen.Application/Interop/Interop.Libraries.cs
new file mode 100755 (executable)
index 0000000..23584f7
--- /dev/null
@@ -0,0 +1,16 @@
+/// Copyright 2016 by Samsung Electronics, Inc.,
+///
+/// This software is the confidential and proprietary information
+/// of Samsung Electronics, Inc. ("Confidential Information"). You
+/// shall not disclose such Confidential Information and shall use
+/// it only in accordance with the terms of the license agreement
+/// you entered into with Samsung.
+
+internal static partial class Interop
+{
+    internal static partial class Libraries
+    {
+        public const string Libc = "libc.so.6";
+        public const string Application = "libcapi-appfw-application.so.0";
+    }
+}
diff --git a/Tizen.Application/Interop/Interop.Sys.cs b/Tizen.Application/Interop/Interop.Sys.cs
new file mode 100755 (executable)
index 0000000..5ed2636
--- /dev/null
@@ -0,0 +1,19 @@
+/// Copyright 2016 by Samsung Electronics, Inc.,
+///
+/// This software is the confidential and proprietary information
+/// of Samsung Electronics, Inc. ("Confidential Information"). You
+/// shall not disclose such Confidential Information and shall use
+/// it only in accordance with the terms of the license agreement
+/// you entered into with Samsung.
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class Sys
+    {
+        [DllImport(Libraries.Libc, EntryPoint = "free", CallingConvention = CallingConvention.Cdecl)]
+        public static extern void Free(IntPtr ptr);
+    }
+}
diff --git a/Tizen.Application/Page.cs b/Tizen.Application/Page.cs
new file mode 100755 (executable)
index 0000000..afbed07
--- /dev/null
@@ -0,0 +1,12 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tizen.Application
+{
+    public class Page
+    {
+    }
+}
diff --git a/Tizen.Application/TizenSynchronizationContext.cs b/Tizen.Application/TizenSynchronizationContext.cs
new file mode 100755 (executable)
index 0000000..64793e5
--- /dev/null
@@ -0,0 +1,69 @@
+using System;
+using System.Collections.Generic;
+using System.Runtime.InteropServices;
+using System.Threading;
+
+namespace Tizen.Application {
+    public class TizenSynchronizationContext : SynchronizationContext {
+        [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+        delegate bool GSourceFunc(IntPtr userData);
+
+        [DllImport("libglib-2.0.so.0 ", CallingConvention = CallingConvention.Cdecl)]
+        static extern uint g_idle_add(GSourceFunc d, IntPtr data);
+
+        public static void Initialize() {
+            SynchronizationContext.SetSynchronizationContext(new TizenSynchronizationContext());
+        }
+        private GSourceFunc wrapperHandler;
+        private Object transactionLock = new Object();
+        private int transactionID = 0;
+        private Dictionary<int, Action> handlerMap = new Dictionary<int, Action>();
+
+        TizenSynchronizationContext() {
+            wrapperHandler = new GSourceFunc(Handler);
+        }
+
+        public override void Post(SendOrPostCallback d, object state) {
+            Post(() => {
+                d(state);
+            });
+        }
+
+        public override void Send(SendOrPostCallback d, object state) {
+            var mre = new ManualResetEvent(false);
+            Exception err = null;
+            Post(() => {
+                try {
+                    d(state);
+                } catch (Exception ex) {
+                    err = ex;
+                } finally {
+                    mre.Set();
+                }
+            });
+            mre.WaitOne();
+            if (err != null) {
+                throw err;
+            }
+        }
+
+        public void Post(Action action) {
+            int id = 0;
+            lock (transactionLock) {
+                id = transactionID++;
+            }
+            handlerMap.Add(id, action);
+            g_idle_add(wrapperHandler, (IntPtr)id);
+        }
+
+        public bool Handler(IntPtr userData) {
+            int key = (int)userData;
+            if (handlerMap.ContainsKey(key)) {
+                handlerMap[key]();
+                handlerMap.Remove(key);
+            }
+            return false;
+        }
+
+    }
+}
diff --git a/application.csproj b/application.csproj
new file mode 100755 (executable)
index 0000000..0da2d40
--- /dev/null
@@ -0,0 +1,74 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
+  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />\r
+  <PropertyGroup>\r
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>\r
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>\r
+    <ProjectGuid>{D2D1A3CE-000E-4AB3-81C4-A8A44A008989}</ProjectGuid>\r
+    <OutputType>Library</OutputType>\r
+    <AppDesignerFolder>Properties</AppDesignerFolder>\r
+    <RootNamespace>Tizen.Application</RootNamespace>\r
+    <AssemblyName>Tizen.Application</AssemblyName>\r
+    <TargetFrameworkVersion>v4.5.2</TargetFrameworkVersion>\r
+    <FileAlignment>512</FileAlignment>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">\r
+    <DebugSymbols>true</DebugSymbols>\r
+    <DebugType>full</DebugType>\r
+    <Optimize>false</Optimize>\r
+    <OutputPath>bin\Debug\</OutputPath>\r
+    <DefineConstants>DEBUG;TRACE</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">\r
+    <DebugType>pdbonly</DebugType>\r
+    <Optimize>true</Optimize>\r
+    <OutputPath>bin\Release\</OutputPath>\r
+    <DefineConstants>TRACE</DefineConstants>\r
+    <ErrorReport>prompt</ErrorReport>\r
+    <WarningLevel>4</WarningLevel>\r
+  </PropertyGroup>\r
+  <PropertyGroup>\r
+    <SignAssembly>true</SignAssembly>\r
+  </PropertyGroup>\r
+  <PropertyGroup>\r
+    <AssemblyOriginatorKeyFile>Tizen.Application.snk</AssemblyOriginatorKeyFile>\r
+  </PropertyGroup>\r
+  <ItemGroup>\r
+    <Reference Include="System" />\r
+    <Reference Include="System.Core" />\r
+    <Reference Include="System.Xml.Linq" />\r
+    <Reference Include="System.Data.DataSetExtensions" />\r
+    <Reference Include="Microsoft.CSharp" />\r
+    <Reference Include="System.Data" />\r
+    <Reference Include="System.Net.Http" />\r
+    <Reference Include="System.Xml" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <Compile Include="Tizen.Application\Actor.cs" />\r
+    <Compile Include="Tizen.Application\AppControl.cs" />\r
+    <Compile Include="Tizen.Application\AppControlFilter.cs" />\r
+    <Compile Include="Tizen.Application\Application.cs" />\r
+    <Compile Include="Properties\AssemblyInfo.cs" />\r
+    <Compile Include="Tizen.Application\CodeExample.cs" />\r
+    <Compile Include="Tizen.Application\ApplicationContext.cs" />\r
+    <Compile Include="Tizen.Application\Interop\Interop.AppControl.cs" />\r
+    <Compile Include="Tizen.Application\Interop\Interop.Libraries.cs" />\r
+    <Compile Include="Tizen.Application\Interop\Interop.Application.cs" />\r
+    <Compile Include="Tizen.Application\Interop\Interop.Sys.cs" />\r
+    <Compile Include="Tizen.Application\Page.cs" />\r
+    <Compile Include="Tizen.Application\TizenSynchronizationContext.cs" />\r
+  </ItemGroup>\r
+  <ItemGroup>\r
+    <None Include="Tizen.Application.snk" />\r
+  </ItemGroup>\r
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />\r
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->\r
+</Project>
diff --git a/packaging/csapi-application.manifest b/packaging/csapi-application.manifest
new file mode 100644 (file)
index 0000000..75b0fa5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_"/>
+    </request>
+</manifest>
diff --git a/packaging/csapi-application.pc.in b/packaging/csapi-application.pc.in
new file mode 100644 (file)
index 0000000..c023e59
--- /dev/null
@@ -0,0 +1,5 @@
+Name: csapi-application
+Description: Tizen Application API for C#
+Version: @version@
+Libs: -r:@dllpath@/@dllname@
+Requires:
\ No newline at end of file
diff --git a/packaging/csapi-application.spec b/packaging/csapi-application.spec
new file mode 100644 (file)
index 0000000..a725794
--- /dev/null
@@ -0,0 +1,83 @@
+%define dllpath %{_libdir}/mono/tizen
+%define dllname Tizen.Application.dll
+
+Name:       csapi-application
+Summary:    Tizen Application API for C#
+Version:    1.0.0
+Release:    1
+Group:      Development/Libraries
+License:    Apache-2.0
+URL:        https://www.tizen.org
+Source0:    %{name}-%{version}.tar.gz
+Source1:    %{name}.manifest
+Source2:    %{name}.pc.in
+
+# TODO: replace mono-compiler, mono-devel to mcs, mono-shlib-cop
+BuildRequires: mono-compiler
+BuildRequires: mono-devel
+# TODO: replace mono-core to gacutil.
+#       mono-core should provide the symbol 'gacutil'
+Requires(post): mono-core
+Requires(postun): mono-core
+
+# P/Invoke Dependencies
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(capi-appfw-application)
+
+# P/Invoke Runtime Dependencies
+# TODO: It should be removed after fix tizen-rpm-config
+Requires: glib-2.0
+Requires: capi-appfw-application
+# DLL Dependencies
+#BuildRequires: ...
+
+%description
+Tizen API for C#
+
+%package devel
+Summary:    Development package for %{name}
+Group:      Development/Libraries
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+Development package for %{name}
+
+%prep
+%setup -q
+
+cp %{SOURCE1} .
+
+%build
+# build dll
+mcs -target:library -out:%{dllname} -keyfile:Tizen.Application.snk \
+  Properties/AssemblyInfo.cs \
+  Tizen.Application/*.cs \
+  Tizen.Application/Interop/*.cs
+
+# check p/invoke
+if [ -x %{dllname} ]; then
+  RET=`mono-shlib-cop %{dllname}`; \
+  CNT=`echo $RET | grep -E "^error:" | wc -l`; \
+  if [ $CNT -gt 0 ]; then exit 1; fi
+fi
+
+%install
+# copy dll
+mkdir -p %{buildroot}%{dllpath}
+install -p -m 644 %{dllname} %{buildroot}%{dllpath}
+
+# generate pkgconfig
+mkdir -p %{buildroot}%{_libdir}/pkgconfig
+sed -e "s#@version@#%{version}#g" \
+    -e "s#@dllpath@#%{dllpath}#g" \
+    -e "s#@dllname@#%{dllname}#g" \
+    %{SOURCE2} > %{buildroot}%{_libdir}/pkgconfig/%{name}.pc
+
+%post
+gacutil -i %{dllpath}/%{dllname}
+
+%files
+%{dllpath}/%{dllname}
+
+%files devel
+%{_libdir}/pkgconfig/%{name}.pc