From: WonYoung Choi Date: Mon, 22 Feb 2016 06:39:14 +0000 (+0900) Subject: Add Tizen.Application namespace X-Git-Tag: submit/trunk/20170823.075128~121^2~234 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=1d14a3e8ce610ead7ebe7d752887e4fb7981467e;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git Add Tizen.Application namespace Change-Id: Icfdee0aa2bd5a8a3bacf5193af91e0cbffd75adb --- diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs new file mode 100755 index 0000000..2279397 --- /dev/null +++ b/Properties/AssemblyInfo.cs @@ -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 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 index 0000000..a2c6b5d --- /dev/null +++ b/Tizen.Application/Actor.cs @@ -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 index 0000000..3f24576 --- /dev/null +++ b/Tizen.Application/AppControl.cs @@ -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 _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 index 0000000..53dd61f --- /dev/null +++ b/Tizen.Application/AppControlFilter.cs @@ -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 index 0000000..406a86e --- /dev/null +++ b/Tizen.Application/Application.cs @@ -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 _actorMap = new Dictionary(); + private static Dictionary _filterMap = new Dictionary(); + private static List _contextList = new List(); + + 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 index 0000000..d9864e4 --- /dev/null +++ b/Tizen.Application/ApplicationContext.cs @@ -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 _actorList; + + internal Actor TopActor { get { return _actorList.LastOrDefault(null); } } + + internal ApplicationContext() + { + _actorList = new List(); + } + + 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 index 0000000..7761e07 --- /dev/null +++ b/Tizen.Application/CodeExample.cs @@ -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 index 0000000..c567521 --- /dev/null +++ b/Tizen.Application/Interop/Interop.AppControl.cs @@ -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 index 0000000..0f36da9 --- /dev/null +++ b/Tizen.Application/Interop/Interop.Application.cs @@ -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 index 0000000..23584f7 --- /dev/null +++ b/Tizen.Application/Interop/Interop.Libraries.cs @@ -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 index 0000000..5ed2636 --- /dev/null +++ b/Tizen.Application/Interop/Interop.Sys.cs @@ -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 index 0000000..afbed07 --- /dev/null +++ b/Tizen.Application/Page.cs @@ -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 index 0000000..64793e5 --- /dev/null +++ b/Tizen.Application/TizenSynchronizationContext.cs @@ -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 handlerMap = new Dictionary(); + + 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 index 0000000..0da2d40 --- /dev/null +++ b/application.csproj @@ -0,0 +1,74 @@ + + + + + Debug + AnyCPU + {D2D1A3CE-000E-4AB3-81C4-A8A44A008989} + Library + Properties + Tizen.Application + Tizen.Application + v4.5.2 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + Tizen.Application.snk + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/packaging/csapi-application.manifest b/packaging/csapi-application.manifest new file mode 100644 index 0000000..75b0fa5 --- /dev/null +++ b/packaging/csapi-application.manifest @@ -0,0 +1,5 @@ + + + + + diff --git a/packaging/csapi-application.pc.in b/packaging/csapi-application.pc.in new file mode 100644 index 0000000..c023e59 --- /dev/null +++ b/packaging/csapi-application.pc.in @@ -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 index 0000000..a725794 --- /dev/null +++ b/packaging/csapi-application.spec @@ -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