--- /dev/null
+// 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);
+ }
+}
--- /dev/null
+// 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");
+ }
+ }
+ }
+}