[Preference] CS API implementation with doxygen comments
authorJyothi Kumar Sambolu <s.jyothi@samsung.com>
Thu, 15 Sep 2016 10:44:05 +0000 (16:14 +0530)
committerJyothi Kumar Sambolu <s.jyothi@samsung.com>
Thu, 6 Oct 2016 09:45:21 +0000 (15:15 +0530)
Change-Id: I05013552f5da06055b671e1b97a2c96f5717556c
Signed-off-by: Jyothi Kumar Sambolu <s.jyothi@samsung.com>
Tizen.Applications/Interop/Interop.Libraries.cs
Tizen.Applications/Interop/Interop.Preference.cs [new file with mode: 0644]
Tizen.Applications/Tizen.Applications.Net45.csproj
Tizen.Applications/Tizen.Applications.csproj
Tizen.Applications/Tizen.Applications/Preference.cs [new file with mode: 0644]
Tizen.Applications/Tizen.Applications/PreferenceChangedEventArgs.cs [new file with mode: 0644]

index a306507..ffb57fe 100755 (executable)
@@ -22,6 +22,7 @@ internal static partial class Interop
         public const string Glib = "libglib-2.0.so.0";
         public const string Libc = "libc.so.6";
         public const string Notification = "libnotification.so.0";
+        public const string Preference = "libcapi-appfw-preference.so.0";
         public const string Alarm = "libcapi-appfw-alarm.so.0";
     }
 }
diff --git a/Tizen.Applications/Interop/Interop.Preference.cs b/Tizen.Applications/Interop/Interop.Preference.cs
new file mode 100644 (file)
index 0000000..795911f
--- /dev/null
@@ -0,0 +1,69 @@
+// 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 Tizen.Applications;
+
+/// <summary>
+/// Contains Interop declarations of Preference classes.
+/// </summary>
+internal static partial class Interop
+{
+    /// <summary>
+    /// Contains Interop declarations of Preference device API.
+    /// </summary>
+    internal static partial class Preference
+    {
+        internal delegate void ChangedCallback(string key, IntPtr userData);
+
+        internal delegate bool ItemCallback(string key, IntPtr userData);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_set_int")]
+        internal static extern int SetInt(string key, int value);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_get_int")]
+        internal static extern int GetInt(string key, out int value);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_set_double")]
+        internal static extern int SetDouble(string key, double value);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_get_double")]
+        internal static extern int GetDouble(string key, out double value);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_set_string")]
+        internal static extern int SetString(string key, string value);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_get_string")]
+        internal static extern int GetString(string key, out string value);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_set_boolean")]
+        internal static extern int SetBoolean(string key, bool value);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_get_boolean")]
+        internal static extern int GetBoolean(string key, out bool value);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_remove")]
+        internal static extern int Remove(string key);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_is_existing")]
+        internal static extern int IsExisting(string key, out bool existing);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_remove_all")]
+        internal static extern int RemoveAll();
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_set_changed_cb")]
+        internal static extern int SetChangedCb(string key, ChangedCallback callback, IntPtr userData);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_unset_changed_cb")]
+        internal static extern int UnsetChangedCb(string key);
+
+        [DllImport(Libraries.Preference, EntryPoint = "preference_foreach_item")]
+        internal static extern int ForeachItem(ItemCallback callback, IntPtr userData);
+    }
+}
index 4ce9087..f3af594 100644 (file)
@@ -60,6 +60,7 @@
     <Compile Include="Interop\Interop.Notification.cs" />
     <Compile Include="Interop\Interop.Package.cs" />
     <Compile Include="Interop\Interop.PackageManager.cs" />
+    <Compile Include="Interop\Interop.Preference.cs" />
     <Compile Include="Interop\Interop.Service.cs" />
     <Compile Include="Interop\Interop.Alarm.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -94,6 +95,8 @@
     <Compile Include="Tizen.Applications\PackageManagerEventArgs.cs" />
     <Compile Include="Tizen.Applications\PackageSizeInformation.cs" />
     <Compile Include="Tizen.Applications\PackageType.cs" />
+    <Compile Include="Tizen.Applications\Preference.cs" />
+    <Compile Include="Tizen.Applications\PreferenceChangedEventArgs.cs" />
     <Compile Include="Tizen.Applications\ReceivedAppControl.cs" />
     <Compile Include="Tizen.Applications\RegionFormatChangedEventArgs.cs" />
     <Compile Include="Tizen.Applications\SafeAppControlHandle.cs" />
index 69c820c..d657c80 100644 (file)
@@ -57,6 +57,7 @@
     <Compile Include="Interop\Interop.Notification.cs" />
     <Compile Include="Interop\Interop.Package.cs" />
     <Compile Include="Interop\Interop.PackageManager.cs" />
+    <Compile Include="Interop\Interop.Preference.cs" />
     <Compile Include="Interop\Interop.Service.cs" />
     <Compile Include="Interop\Interop.Alarm.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
@@ -91,6 +92,8 @@
     <Compile Include="Tizen.Applications\PackageManagerEventArgs.cs" />
     <Compile Include="Tizen.Applications\PackageSizeInformation.cs" />
     <Compile Include="Tizen.Applications\PackageType.cs" />
+    <Compile Include="Tizen.Applications\PreferenceChangedEventArgs.cs" />
+    <Compile Include="Tizen.Applications\Preference.cs" />
     <Compile Include="Tizen.Applications\ReceivedAppControl.cs" />
     <Compile Include="Tizen.Applications\RegionFormatChangedEventArgs.cs" />
     <Compile Include="Tizen.Applications\SafeAppControlHandle.cs" />
diff --git a/Tizen.Applications/Tizen.Applications/Preference.cs b/Tizen.Applications/Tizen.Applications/Preference.cs
new file mode 100644 (file)
index 0000000..44cc1a7
--- /dev/null
@@ -0,0 +1,450 @@
+// 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.Collections.Generic;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications
+{
+    /// <summary>
+    /// The Preference class provides APIs to store and retrieve application specific data/preference. A preference is saved in the form of a key-value pair.
+    /// Keys are always text strings and value can be any one of four types: integer, double, string and boolean.
+    /// </summary>
+    public static class Preference
+    {
+        private const string LogTag = "Tizen.Applications";
+        private static Interop.Preference.ChangedCallback s_preferenceChangedCallback;
+        private static IDictionary<string, EventContext> s_eventMap = new Dictionary<string, EventContext>();
+
+        static Preference()
+        {
+            s_preferenceChangedCallback = (string key, IntPtr userData) =>
+            {
+                try
+                {
+                    s_eventMap[key]?.FireEvent();
+                }
+                catch (Exception e)
+                {
+                    Log.Warn(LogTag, e.Message);
+                }
+            };
+        }
+
+        /// <summary>
+        /// Retrieves all keys of the application preferences
+        /// </summary>
+        /// <value>
+        /// The list of keys
+        /// </value>
+        /// <example>
+        /// <code>
+        ///     Preference.Set("Option_enabled", true);
+        ///     Preference.Set("active_user", "Joe");
+        ///     Preference.Set("default_volume", 10);
+        ///     Preference.Set("brightness", "0.6");
+        ///     foreach(string key in Preference.Keys)
+        ///     {
+        ///         Console.WriteLine("key {0}", key);
+        ///     }
+        /// </code>
+        /// </example>
+        public static IEnumerable<string> Keys
+        {
+            get
+            {
+                var collection = new List<string>();
+                Interop.Preference.ItemCallback itemsCallback = (string key, IntPtr userData) =>
+                {
+                    collection.Add(key);
+                    return true;
+                };
+                Interop.Preference.ForeachItem(itemsCallback, IntPtr.Zero);
+                return collection;
+            }
+        }
+
+        /// <summary>
+        /// Gets the event context for the given key.
+        /// </summary>
+        /// <seealso cref="EventContext"/>
+        /// <param name="key">The preference key</param>
+        /// <returns>The event context of respective key</returns>
+        /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
+        /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
+        /// <example>
+        /// <code>
+        ///     private static void Preference_PreferenceChanged(object sender, PreferenceChangedEventArgs e)
+        ///     {
+        ///         Console.WriteLine("key {0}", e.Key);
+        ///     }
+        ///
+        ///     Preference.EventContext context = null;
+        ///     Preference.GetEventContext("active_user").TryGetTarget(out context);
+        ///     if(context != null)
+        ///     {
+        ///         context.Changed += Preference_PreferenceChanged;
+        ///     }
+        ///
+        ///     Preference.Set("active_user", "Poe");
+        ///
+        ///     Preference.GetEventContext("active_user").TryGetTarget(out context);
+        ///     if (context != null)
+        ///     {
+        ///         context.Changed -= Preference_PreferenceChanged;
+        ///     }
+        /// </code>
+        /// </example>
+        public static WeakReference<EventContext> GetEventContext(string key)
+        {
+            if (!s_eventMap.ContainsKey(key))
+            {
+                if (Contains(key))
+                {
+                    s_eventMap[key] = new EventContext(key);
+                }
+                else
+                {
+                    throw PreferenceErrorFactory.GetException((int)ErrorCode.KeyNotAvailable);
+                }
+            }
+
+            return new WeakReference<EventContext>(s_eventMap[key]);
+        }
+
+        /// <summary>
+        /// Checks whether the given key exists in the preference.
+        /// </summary>
+        /// <param name="key">The name of the key to check</param>
+        /// <returns>true if the key exists in the preference, otherwise false</returns>
+        /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
+        /// <exception cref="IOException">Thrown when method failed due to internal IO error.</exception>
+        /// <example>
+        /// <code>
+        ///     Preference.Set("active_user", "Joe");
+        ///     bool exists = Preference.Contains("active_user");
+        ///     if (exists)
+        ///     {
+        ///         string value = Preference.Get<string>("active_user");
+        ///         Console.WriteLine("user {0}", value);
+        ///     }
+        /// </code>
+        /// </example>
+        public static bool Contains(string key)
+        {
+            bool contains;
+            int ret = Interop.Preference.IsExisting(key, out contains);
+            if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+            {
+                Log.Error(LogTag, "Failed to find key");
+                throw PreferenceErrorFactory.GetException(ret);
+            }
+
+            return contains;
+        }
+
+        /// <summary>
+        /// Sets a key-value pair representing the preference.
+        /// </summary>
+        /// <remarks>
+        /// If the key already exists in the Preference, old value will be overwritten with new value.
+        /// Data types supported for value are: integer, double, string and bool.
+        /// </remarks>
+        /// <param name="key">The name of the key to create/modigy</param>
+        /// <param name="value">The value corresponding to the key.</param>
+        /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
+        /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
+        /// <example>
+        /// <code>
+        ///     Preference.Set("Option_enabled", true);
+        ///     Preference.Set("active_user", "Joe");
+        ///     Preference.Set("default_volume", 10);
+        ///     Preference.Set("brightness", "0.6");
+        /// </code>
+        /// </example>
+        public static void Set(string key, object value)
+        {
+            int ret = 0;
+            if (value is int)
+            {
+                ret = Interop.Preference.SetInt(key, (int)value);
+                if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+                {
+                    Log.Error(LogTag, "Failed to find key");
+                    throw PreferenceErrorFactory.GetException(ret);
+                }
+            }
+            else if (value is double)
+            {
+                ret = Interop.Preference.SetDouble(key, (double)value);
+                if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+                {
+                    Log.Error(LogTag, "Failed to find key");
+                    throw PreferenceErrorFactory.GetException(ret);
+                }
+            }
+            else if (value is string)
+            {
+                ret = Interop.Preference.SetString(key, (string)value);
+                if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+                {
+                    Log.Error(LogTag, "Failed to find key");
+                    throw PreferenceErrorFactory.GetException(ret);
+                }
+            }
+            else if (value is bool)
+            {
+                ret = Interop.Preference.SetBoolean(key, (bool)value);
+                if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+                {
+                    Log.Error(LogTag, "Failed to find key");
+                    throw PreferenceErrorFactory.GetException(ret);
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets the value of a preference item with the specified key.
+        /// Note that this is a generic method.
+        /// </summary>
+        /// <typeparam name="T">The generic type to return.</typeparam>
+        /// <param name="key">The key of the preference</param>
+        /// <returns>The value of the preference item if it is of the specified generic type.</returns>
+        /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
+        /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
+        /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
+        /// <example>
+        /// <code>
+        ///     bool exists = Preference.Contains("active_user");
+        ///     if (exists)
+        ///     {
+        ///         string value = Preference.Get<string>("active_user");
+        ///         Console.WriteLine("user {0}", value);
+        ///     }
+        /// </code>
+        /// </example>
+        public static T Get<T>(string key)
+        {
+            object result = null;
+            int ret = (int)PreferenceErrorFactory.PreferenceError.None;
+            if (typeof(T) == typeof(bool))
+            {
+                bool val;
+                ret = Interop.Preference.GetBoolean(key, out val);
+                result = val;
+            }
+            else if (typeof(T) == typeof(int))
+            {
+                int val;
+                ret = Interop.Preference.GetInt(key, out val);
+                result = val;
+            }
+            else if (typeof(T) == typeof(string))
+            {
+                string val;
+                ret = Interop.Preference.GetString(key, out val);
+                result = val;
+            }
+            else if (typeof(T) == typeof(double))
+            {
+                double val;
+                ret = Interop.Preference.GetDouble(key, out val);
+                result = val;
+            }
+            else
+            {
+                Log.Error(LogTag, "Failed to remove key");
+                throw new ArgumentException("Invalid parameter");
+            }
+
+            if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+            {
+                Log.Error(LogTag, "Failed to remove key");
+                throw PreferenceErrorFactory.GetException(ret);
+            }
+
+            return (result != null) ? (T)result : default(T);
+        }
+
+        /// <summary>
+        /// Removes any preference value with the given key.
+        /// </summary>
+        /// <param name="key">The key to remove</param>
+        /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
+        /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
+        /// <example>
+        /// <code>
+        ///     bool exists = Preference.Contains("active_user");
+        ///     if (exists)
+        ///     {
+        ///         string value = Preference.Remove("active_user");
+        ///     }
+        /// </code>
+        /// </example>
+        public static void Remove(string key)
+        {
+            int ret = Interop.Preference.Remove(key);
+            if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+            {
+                Log.Error(LogTag, "Failed to remove key");
+                throw PreferenceErrorFactory.GetException(ret);
+            }
+        }
+
+        /// <summary>
+        /// Removes all key-value pairs from the preference.
+        /// </summary>
+        /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
+        /// <example>
+        /// <code>
+        ///     Preference.Set("Option_enabled", true);
+        ///     Preference.Set("active_user", "Joe");
+        ///     Preference.Set("default_volume", 10);
+        ///     Preference.Set("brightness", "0.6");
+        ///     Preference.RemoveAll();
+        /// </code>
+        /// </example>
+        public static void RemoveAll()
+        {
+            int ret = Interop.Preference.RemoveAll();
+            if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+            {
+                Log.Error(LogTag, "Failed to remove all keys");
+                throw PreferenceErrorFactory.GetException(ret);
+            }
+        }
+
+        private static void AllowChangeNotifications(string key)
+        {
+            int ret = Interop.Preference.SetChangedCb(key, s_preferenceChangedCallback, IntPtr.Zero);
+            if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+            {
+                Log.Error(LogTag, "Failed to set key notification");
+                throw PreferenceErrorFactory.GetException(ret);
+            }
+        }
+
+        private static void DisallowChangeNotifications(string key)
+        {
+            int ret = Interop.Preference.UnsetChangedCb(key);
+            if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
+            {
+                Log.Error(LogTag, "Failed to remove key notification");
+                throw PreferenceErrorFactory.GetException(ret);
+            }
+        }
+
+        /// <summary>
+        /// The class manages event handlers of preference keys. The class enables having event handlers for individual preference keys.
+        /// </summary>
+        public class EventContext
+        {
+            private string _key;
+
+            internal EventContext(string key)
+            {
+                _key = key;
+            }
+
+            /// <summary>
+            /// Occurs whenever there is change in the value of preference key.
+            /// </summary>
+            /// <exception cref="System.ArgumentException">Thrown when the key does not exist or when there is an invalid parameter.</exception>
+            /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
+            /// <example>
+            /// <code>
+            ///     private static void Preference_PreferenceChanged(object sender, PreferenceChangedEventArgs e)
+            ///     {
+            ///         Console.WriteLine("key {0}", e.Key);
+            ///     }
+            ///     Preference.EventContext context = null;
+            ///     Preference.GetEventContext("active_user").TryGetTarget(out context);
+            ///     if(context != null)
+            ///     {
+            ///         context.Changed += Preference_PreferenceChanged;
+            ///     }
+            ///
+            ///     Preference.Set("active_user", "Poe");
+            ///
+            ///     Preference.GetEventContext("active_user").TryGetTarget(out context);
+            ///     if (context != null)
+            ///     {
+            ///         context.Changed -= Preference_PreferenceChanged;
+            ///     }
+            /// </code>
+            /// </example>
+            public event EventHandler<PreferenceChangedEventArgs> Changed
+            {
+                add
+                {
+                    if (_changed == null)
+                    {
+                        AllowChangeNotifications(_key);
+                    }
+
+                    _changed += value;
+                }
+
+                remove
+                {
+                    _changed -= value;
+                    if (_changed == null)
+                    {
+                        DisallowChangeNotifications(_key);
+                        s_eventMap.Remove(_key);
+                    }
+                }
+            }
+
+            private event EventHandler<PreferenceChangedEventArgs> _changed;
+
+            internal void FireEvent()
+            {
+                _changed?.Invoke(null, new PreferenceChangedEventArgs() { Key = _key });
+            }
+        }
+
+    }
+
+    internal static class PreferenceErrorFactory
+    {
+        internal enum PreferenceError
+        {
+            None = ErrorCode.None,
+            OutOfMemory = ErrorCode.OutOfMemory,
+            InvalidParameter = ErrorCode.InvalidParameter,
+            KeyNotAvailable = ErrorCode.KeyNotAvailable,
+            IoError = ErrorCode.IoError
+        }
+
+        static internal Exception GetException(int error)
+        {
+            if ((PreferenceError)error == PreferenceError.OutOfMemory)
+            {
+                return new OutOfMemoryException("Out of memory");
+            }
+            else if ((PreferenceError)error == PreferenceError.InvalidParameter)
+            {
+                return new ArgumentException("Invalid parameter");
+            }
+            else if ((PreferenceError)error == PreferenceError.KeyNotAvailable)
+            {
+                return new KeyNotFoundException("Key does not exist in the bundle");
+            }
+            else if ((PreferenceError)error == PreferenceError.IoError)
+            {
+                return new System.IO.IOException("I/O Error");
+            }
+            else
+            {
+                return new ArgumentException("Unknown error");
+            }
+        }
+    }
+}
diff --git a/Tizen.Applications/Tizen.Applications/PreferenceChangedEventArgs.cs b/Tizen.Applications/Tizen.Applications/PreferenceChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..f01689c
--- /dev/null
@@ -0,0 +1,23 @@
+// 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;
+
+namespace Tizen.Applications
+{
+    /// <summary>
+    /// This class is an event arguments of the PreferenceChanged events.
+    /// </summary>
+    public class PreferenceChangedEventArgs : EventArgs
+    {
+        /// <summary>
+        /// The key of the preference whose value is changed.
+        /// </summary>
+        public string Key { get; internal set; }
+    }
+}