[Applications.Common] Support UI Thread for Inhouse developers (#4153)
authorhjhun <36876573+hjhun@users.noreply.github.com>
Wed, 8 Jun 2022 04:24:40 +0000 (13:24 +0900)
committerGitHub <noreply@github.com>
Wed, 8 Jun 2022 04:24:40 +0000 (13:24 +0900)
* Support UI Thread

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Initialize TizenSynchronizationContext for UI Thread

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Add TizenUISynchronizationContext class for UI Thread

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Add missing descriptions about '<since_tizen>'

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Fix Post method of CoreApplication and CoreTask

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Fix Post method using glib

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Separate GSourceManager class from TizenSynchronizationContext class

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Use Action delegate instead of custom delegate

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Remove unused delegate

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
* Add a missing description and set EditableBrowsableState.Never

Signed-off-by: Hwankyu Jhun <h.jhun@samsung.com>
12 files changed:
src/Tizen.Applications.Common/Interop/Interop.AppCoreUI.cs [new file with mode: 0755]
src/Tizen.Applications.Common/Interop/Interop.Glib.cs
src/Tizen.Applications.Common/Interop/Interop.Libraries.cs
src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreTask.cs [new file with mode: 0755]
src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreTaskBackend.cs [new file with mode: 0755]
src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs
src/Tizen.Applications.Common/Tizen.Applications/CoreTask.cs [new file with mode: 0755]
src/Tizen.Applications.Common/Tizen.Applications/GSourceManager.cs [new file with mode: 0755]
src/Tizen.Applications.Common/Tizen.Applications/TizenSynchronizationContext.cs
src/Tizen.Applications.Common/Tizen.Applications/TizenUISynchronizationContext.cs [new file with mode: 0755]
src/Tizen.Applications.Common/Tizen.Applications/UIEventArgs.cs [new file with mode: 0755]
src/Tizen.Applications.Common/Tizen.Applications/UIEventStatus.cs [new file with mode: 0755]

diff --git a/src/Tizen.Applications.Common/Interop/Interop.AppCoreUI.cs b/src/Tizen.Applications.Common/Interop/Interop.AppCoreUI.cs
new file mode 100755 (executable)
index 0000000..c0240f9
--- /dev/null
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+internal static partial class Interop
+{
+    internal static partial class AppCoreUI
+    {
+        [DllImport(Libraries.AppCoreUI, EntryPoint = "app_core_ui_base_get_tizen_glib_context", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern IntPtr GetTizenGlibContext();
+    }
+}
index ae64db1..58a8846 100644 (file)
@@ -29,5 +29,20 @@ internal static partial class Interop
 
         [DllImport(Libraries.Glib, EntryPoint = "g_source_remove", CallingConvention = CallingConvention.Cdecl)]
         internal static extern bool RemoveSource(uint source);
+
+        [DllImport(Libraries.Glib, EntryPoint = "g_idle_source_new", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern IntPtr IdleSourceNew();
+
+        [DllImport(Libraries.Glib, EntryPoint = "g_source_set_callback", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void SourceSetCallback(IntPtr source, GSourceFunc func, IntPtr data, IntPtr notify);
+
+        [DllImport(Libraries.Glib, EntryPoint = "g_source_attach", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern uint SourceAttach(IntPtr source, IntPtr context);
+
+        [DllImport(Libraries.Glib, EntryPoint = "g_source_unref", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern void SourceUnref(IntPtr source);
+
+        [DllImport(Libraries.Glib, EntryPoint = "g_main_context_get_thread_default", CallingConvention = CallingConvention.Cdecl)]
+        internal static extern IntPtr MainContextGetThreadDefault();
     }
 }
index 9b1e33f..50b75ec 100755 (executable)
@@ -20,6 +20,7 @@ internal static partial class Interop
     {
         public const string AppCommon = "libcapi-appfw-app-common.so.0";
         public const string AppControl = "libcapi-appfw-app-control.so.0";
+        public const string AppCoreUI = "libapp-core-ui-cpp.so.1";
         public const string AppEvent = "libcapi-appfw-event.so.0";
         public const string AppManager = "libcapi-appfw-app-manager.so.0";
         public const string Bundle = "libbundle.so.0";
diff --git a/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreTask.cs b/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreTask.cs
new file mode 100755 (executable)
index 0000000..f831bc8
--- /dev/null
@@ -0,0 +1,90 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.ComponentModel;
+using System.Threading;
+
+namespace Tizen.Applications
+{
+    /// <summary>
+    /// Represents the CoreTask interface.
+    /// </summary>
+    /// <since_tizen> 10 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public interface ICoreTask
+    {
+        /// <summary>
+        /// This method is to handle behavior when the task of the application is created.
+        /// </summary>
+        /// <since_tizen> 10 </since_tizen>
+        void OnCreate();
+
+        /// <summary>
+        /// This method is to handle behavior when the task of the application is terminated.
+        /// </summary>
+        /// <since_tizen> 10 </since_tizen>
+        void OnTerminate();
+
+        /// <summary>
+        /// This method is to handle behavior when the task of the application receives the appcontrol message.
+        /// </summary>
+        /// <param name="e">The received app control event argument.</param>
+        /// <since_tizen> 10 </since_tizen>
+        void OnAppControlReceived(AppControlReceivedEventArgs e);
+
+        /// <summary>
+        /// This method is to handle behavior when the system memory is low.
+        /// </summary>
+        /// <param name="e">The low memory event argument.</param>
+        /// <since_tizen> 10 </since_tizen>
+        void OnLowMemory(LowMemoryEventArgs e);
+
+        /// <summary>
+        /// This method is to handle behavior when the system battery is low.
+        /// </summary>
+        /// <param name="e">The low battery event argument.</param>
+        /// <since_tizen> 10 </since_tizen>
+        void OnLowBattery(LowBatteryEventArgs e);
+
+        /// <summary>
+        /// This method is to handle behavior when the system language is changed.
+        /// </summary>
+        /// <param name="e">The locale changed event argument.</param>
+        /// <since_tizen> 10 </since_tizen>
+        void OnLocaleChanged(LocaleChangedEventArgs e);
+
+        /// <summary>
+        /// This method is to handle behavior when the region format is changed.
+        /// </summary>
+        /// <param name="e">The region format changed event argument.</param>
+        /// <since_tizen> 10 </since_tizen>
+        void OnRegionFormatChanged(RegionFormatChangedEventArgs e);
+
+        /// <summary>
+        /// This method is to handle behavior when the device orientation is changed.
+        /// </summary>
+        /// <param name="e">The device orientation changed event argument.</param>
+        /// <since_tizen> 10 </since_tizen>
+        void OnDeviceOrientationChanged(DeviceOrientationEventArgs e);
+
+        /// <summary>
+        /// This method is to handle behavior when the application is resumed or paused.
+        /// </summary>
+        /// <param name="e">The UI event argument.</param>
+        /// <since_tizen> 10 </since_tizen>
+        void OnUIEvent(UIEventArgs e);
+    }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreTaskBackend.cs b/src/Tizen.Applications.Common/Tizen.Applications.CoreBackend/ICoreTaskBackend.cs
new file mode 100755 (executable)
index 0000000..08b5824
--- /dev/null
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+
+namespace Tizen.Applications.CoreBackend
+{
+    /// <summary>
+    /// An interface that represents the task backend lifecycles.
+    /// </summary>
+    /// <since_tizen> 10 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public interface ICoreTaskBackend : ICoreBackend
+    {
+        /// <summary>
+        /// Sets the core task.
+        /// </summary>
+        /// <param name="task">The core task interface.</param>
+        /// <since_tizen> 10 </since_tizen>
+        void SetCoreTask(ICoreTask task);
+    }
+}
index 4cbb737..359cce0 100644 (file)
  */
 
 using System;
+using System.Collections.Concurrent;
+using System.ComponentModel;
 using System.Globalization;
 using System.Runtime.InteropServices;
 using System.Text;
+using System.Threading;
 using System.Timers;
 using Tizen.Applications.CoreBackend;
 
@@ -30,9 +33,10 @@ namespace Tizen.Applications
     public class CoreApplication : Application
     {
         private readonly ICoreBackend _backend;
+        private readonly ICoreTask _task;
         private bool _disposedValue = false;
 
-        private static Timer sTimer;
+        private static System.Timers.Timer sTimer;
 
         /// <summary>
         /// Initializes the CoreApplication class.
@@ -42,6 +46,20 @@ namespace Tizen.Applications
         public CoreApplication(ICoreBackend backend)
         {
             _backend = backend;
+            _task = null;
+        }
+
+        /// <summary>
+        /// Initializes the CoreApplication class.
+        /// </summary>
+        /// <param name="backend">The backend instance implementing ICoreBackend interface.</param>
+        /// <param name="task">The backend instance implmenting ICoreTask interface.</param>
+        /// <since_tizen> 10 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public CoreApplication(ICoreBackend backend, ICoreTask task)
+        {
+            _backend = backend;
+            _task = task;
         }
 
         /// <summary>
@@ -96,7 +114,7 @@ namespace Tizen.Applications
         /// The backend instance.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
-        protected ICoreBackend Backend { get { return _backend; } }
+        protected ICoreBackend Backend { get { return _backend; } }      
 
         /// <summary>
         /// Runs the application's main loop.
@@ -116,14 +134,23 @@ namespace Tizen.Applications
             _backend.AddEventHandler<RegionFormatChangedEventArgs>(EventType.RegionFormatChanged, OnRegionFormatChanged);
             _backend.AddEventHandler<DeviceOrientationEventArgs>(EventType.DeviceOrientationChanged, OnDeviceOrientationChanged);
 
-            string[] argsClone = new string[args.Length + 1];
-            if (args.Length > 1)
+            string[] argsClone = new string[args == null ? 1 : args.Length + 1];
+            if (args != null && args.Length > 1)
             {
                 args.CopyTo(argsClone, 1);
             }
             argsClone[0] = string.Empty;
 
-            _backend.Run(argsClone);
+            if (_task != null)
+            {
+                ICoreTaskBackend backend = (ICoreTaskBackend)_backend;
+                backend.SetCoreTask(_task);
+                backend.Run(argsClone);
+            }
+            else
+            {
+                _backend.Run(argsClone);
+            }
         }
 
         /// <summary>
@@ -142,6 +169,11 @@ namespace Tizen.Applications
         /// <since_tizen> 3 </since_tizen>
         protected virtual void OnCreate()
         {
+            if (_task != null)
+            {
+                TizenUISynchronizationContext.Initialize();
+            }            
+
             if (!GlobalizationMode.Invariant)
             {
                 string locale = ULocale.GetDefaultLocale();
@@ -190,7 +222,7 @@ namespace Tizen.Applications
             if (interval <= 0)
                 interval = 10 * 1000;
 
-            sTimer = new Timer(interval);
+            sTimer = new System.Timers.Timer(interval);
             sTimer.Elapsed += OnTimedEvent;
             sTimer.AutoReset = false;
             sTimer.Enabled = true;
@@ -256,6 +288,23 @@ namespace Tizen.Applications
         }
 
         /// <summary>
+        /// Dispatches an asynchronous message to the main loop of the CoreTask.
+        /// </summary>
+        /// <param name="runner">The runner callaback.</param>
+        /// <exception cref="ArgumentNullException">Thrown when the runner is null.</exception>
+        /// <since_tizen> 10 </since_tizen>
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public void Post(Action runner)
+        {
+            if (runner == null)
+            {
+                throw new ArgumentNullException(nameof(runner));
+            }
+
+            GSourceManager.Post(runner);
+        }
+
+        /// <summary>
         /// Releases any unmanaged resources used by this object. Can also dispose any other disposable objects.
         /// </summary>
         /// <param name="disposing">If true, disposes any disposable objects. If false, does not dispose disposable objects.</param>
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/CoreTask.cs b/src/Tizen.Applications.Common/Tizen.Applications/CoreTask.cs
new file mode 100755 (executable)
index 0000000..5a343f1
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Concurrent;
+using System.ComponentModel;
+using System.Threading;
+using static Tizen.Applications.TizenSynchronizationContext;
+
+namespace Tizen.Applications
+{
+    /// <summary>
+    /// Represents the CoreTask interface.
+    /// </summary>
+    /// <since_tizen> 10 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class CoreTask : ICoreTask
+    {
+        /// <summary>
+        /// Initializes the CoreTask class. 
+        /// </summary>
+        /// <since_tizen> 10 </since_tizen>
+        public CoreTask()
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the task of the application is created.
+        /// </summary>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnCreate()
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the task of the application is terminated.
+        /// </summary>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnTerminate()
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the task of the application receives the appcontrol message.
+        /// </summary>
+        /// <param name="e"></param>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnAppControlReceived(AppControlReceivedEventArgs e)
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the system memory is low.
+        /// </summary>
+        /// <param name="e">The low memory event argument</param>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnLowMemory(LowMemoryEventArgs e)
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the system battery is low.
+        /// </summary>
+        /// <param name="e">The low battery event argument</param>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnLowBattery(LowBatteryEventArgs e)
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the system language is changed.
+        /// </summary>
+        /// <param name="e">The locale changed event argument</param>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnLocaleChanged(LocaleChangedEventArgs e)
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the region format is changed.
+        /// </summary>
+        /// <param name="e">The region format changed event argument</param>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnRegionFormatChanged(RegionFormatChangedEventArgs e)
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the device orientation is changed.
+        /// </summary>
+        /// <param name="e">The device orientation changed event argument</param>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnDeviceOrientationChanged(DeviceOrientationEventArgs e)
+        {
+        }
+
+        /// <summary>
+        /// This method is to handle behavior when the application is resumed or paused.
+        /// </summary>
+        /// <param name="e">The UI event argument.</param>
+        /// <since_tizen> 10 </since_tizen>
+        public virtual void OnUIEvent(UIEventArgs e)
+        {
+        }
+
+        /// <summary>
+        /// Dispatches an asynchronous message to the main loop of the CoreApplication.
+        /// </summary>
+        /// <param name="runner">The runner callback.</param>
+        /// /// <exception cref="ArgumentNullException">Thrown when the runner is null.</exception>
+        /// <since_tizen> 10 </since_tizen>
+        public void Post(Action runner)
+        {
+            if (runner == null)
+            {
+                throw new ArgumentNullException(nameof(runner));
+            }
+
+            GSourceManager.Post(runner, true);
+        }
+    }
+}
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/GSourceManager.cs b/src/Tizen.Applications.Common/Tizen.Applications/GSourceManager.cs
new file mode 100755 (executable)
index 0000000..00dc4c9
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Concurrent;
+
+namespace Tizen.Applications
+{
+    internal static class GSourceManager
+    {
+        private static Interop.Glib.GSourceFunc _wrapperHandler;
+        private static Object _transactionLock;
+        private static ConcurrentDictionary<int, Action> _handlerMap;
+        private static int _transactionId;
+
+        static GSourceManager()
+        {
+            _wrapperHandler = new Interop.Glib.GSourceFunc(Handler);
+            _transactionLock = new Object();
+            _handlerMap = new ConcurrentDictionary<int, Action>();
+            _transactionId = 0;
+        }
+
+        public static void Post(Action action, bool useTizenGlibContext = false)
+        {
+            int id = 0;
+            lock (_transactionLock)
+            {
+                id = _transactionId++;
+            }
+            _handlerMap.TryAdd(id, action);
+            IntPtr source = Interop.Glib.IdleSourceNew();
+            Interop.Glib.SourceSetCallback(source, _wrapperHandler, (IntPtr)id, IntPtr.Zero);
+            Interop.Glib.SourceAttach(source, useTizenGlibContext ? Interop.AppCoreUI.GetTizenGlibContext() : IntPtr.Zero);
+            Interop.Glib.SourceUnref(source);
+        }
+
+        private static bool Handler(IntPtr userData)
+        {
+            int key = (int)userData;
+            if (_handlerMap.TryRemove(key, out Action action))
+            {
+                action?.Invoke();
+            }
+            return false;
+        }
+    }
+}
\ No newline at end of file
index ca900a5..ad6e357 100755 (executable)
@@ -90,42 +90,5 @@ namespace Tizen.Applications
                 throw err;
             }
         }
-
-        private static class GSourceManager
-        {
-            private static Interop.Glib.GSourceFunc _wrapperHandler;
-            private static Object _transactionLock;
-            private static ConcurrentDictionary<int, Action> _handlerMap;
-            private static int _transactionId;
-
-            static GSourceManager()
-            {
-                _wrapperHandler = new Interop.Glib.GSourceFunc(Handler);
-                _transactionLock = new Object();
-                _handlerMap = new ConcurrentDictionary<int, Action>();
-                _transactionId = 0;
-            }
-
-            public static void Post(Action action)
-            {
-                int id = 0;
-                lock (_transactionLock)
-                {
-                    id = _transactionId++;
-                }
-                _handlerMap.TryAdd(id, action);
-                Interop.Glib.IdleAdd(_wrapperHandler, (IntPtr)id);
-            }
-
-            private static bool Handler(IntPtr userData)
-            {
-                int key = (int)userData;
-                if (_handlerMap.TryRemove(key, out Action action))
-                {
-                    action?.Invoke();
-                }
-                return false;
-            }
-        }
     }
-}
+}
\ No newline at end of file
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/TizenUISynchronizationContext.cs b/src/Tizen.Applications.Common/Tizen.Applications/TizenUISynchronizationContext.cs
new file mode 100755 (executable)
index 0000000..db003f8
--- /dev/null
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Concurrent;
+using System.ComponentModel;
+using System.Threading;
+
+namespace Tizen.Applications
+{
+    /// <summary>
+    /// Provides a synchronization context for the Tizen thread application model.
+    /// </summary>
+    /// <since_tizen> 10 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class TizenUISynchronizationContext : SynchronizationContext
+    {
+        /// <summary>
+        /// Initilizes a new TizenUISynchronizationContext and install into the current thread.
+        /// </summary>
+        /// <remarks>
+        /// It is equivalent.
+        /// <code>
+        /// SetSynchronizationContext(new TizenUISynchronizationContext());
+        /// </code>
+        /// </remarks>
+        /// <since_tizen> 10 </since_tizen>
+        public static void Initialize()
+        {
+            SetSynchronizationContext(new TizenUISynchronizationContext());
+        }
+
+        /// <summary>
+        /// Dispatches an asynchronous message to a Tizen main loop of the UI thread.
+        /// </summary>
+        /// <param name="d"><see cref="System.Threading.SendOrPostCallback"/>The SendOrPostCallback delegate to call.</param>
+        /// <param name="state"><see cref="System.Object"/>The object passed to the delegate.</param>
+        /// <remarks>
+        /// The post method starts an asynchronous request to post a message.</remarks>
+        /// <since_tizen> 10 </since_tizen>
+        public override void Post(SendOrPostCallback d, object state)
+        {
+            GSourceManager.Post(() =>
+            {
+                d(state);
+            }, true);
+        }
+
+        /// <summary>
+        /// Dispatches a synchronous message to a Tizen main loop of the UI thread.
+        /// </summary>
+        /// <param name="d"><see cref="System.Threading.SendOrPostCallback"/>The SendOrPostCallback delegate to call.</param>
+        /// <param name="state"><see cref="System.Object"/>The object passed to the delegate.</param>
+        /// <remarks>
+        /// The send method starts a synchronous request to send a message.</remarks>
+        /// <since_tizen> 10 </since_tizen>
+        public override void Send(SendOrPostCallback d, object state)
+        {
+            var mre = new ManualResetEvent(false);
+            Exception err = null;
+            GSourceManager.Post(() =>
+            {
+                try
+                {
+                    d(state);
+                }
+                catch (Exception ex)
+                {
+                    err = ex;
+                }
+                finally
+                {
+                    mre.Set();
+                }
+            }, true);
+            mre.WaitOne();
+            if (err != null)
+            {
+                throw err;
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/UIEventArgs.cs b/src/Tizen.Applications.Common/Tizen.Applications/UIEventArgs.cs
new file mode 100755 (executable)
index 0000000..d061386
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.ComponentModel;
+
+namespace Tizen.Applications
+{
+    /// <summary>
+    /// The class for event arguments of the UIEvent.
+    /// </summary>
+    /// <since_tizen> 10 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public class UIEventArgs : EventArgs
+    {
+        /// <summary>
+        /// Initializes the UIEventArgs class.
+        /// </summary>
+        /// <param name="status">The information of the UIEventStatus</param>
+        /// <since_tizen> 10 </since_tizen>
+        public UIEventArgs(UIEventStatus status)
+        {
+            UIEventStatus = status;
+        }
+
+        /// <summary>
+        /// The received UIEventStatus.
+        /// </summary>
+        /// <since_tizen> 10 </since_tizen>
+        public UIEventStatus UIEventStatus { get; private set; }
+    }
+}
\ No newline at end of file
diff --git a/src/Tizen.Applications.Common/Tizen.Applications/UIEventStatus.cs b/src/Tizen.Applications.Common/Tizen.Applications/UIEventStatus.cs
new file mode 100755 (executable)
index 0000000..24b7dde
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System.ComponentModel;
+
+namespace Tizen.Applications
+{
+    /// <summary>
+    /// Enumeration for the UI event status.
+    /// </summary>
+    /// <since_tizen> 10 </since_tizen>
+    [EditorBrowsable(EditorBrowsableState.Never)]
+    public enum UIEventStatus
+    {
+        /// <summary>
+        /// Not initialized status.
+        /// </summary>
+        None = 0,
+
+        /// <summary>
+        /// The application is resumed..
+        /// </summary>
+        Resumed = 1,
+
+        /// <summary>
+        /// The application is paused.
+        /// </summary>
+        Paused = 2,
+    }
+}
\ No newline at end of file