2 * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.Collections.Generic;
19 using Tizen.Internals.Errors;
21 namespace Tizen.Applications
24 /// 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.
25 /// Keys are always text strings and value can be any one of four types: integer, double, string and boolean.
27 public static class Preference
29 private const string LogTag = "Tizen.Applications";
30 private static Interop.Preference.ChangedCallback s_preferenceChangedCallback;
31 private static IDictionary<string, EventContext> s_eventMap = new Dictionary<string, EventContext>();
35 s_preferenceChangedCallback = (string key, IntPtr userData) =>
39 s_eventMap[key]?.FireEvent();
43 Log.Warn(LogTag, e.Message);
49 /// Retrieves all keys of the application preferences
56 /// Preference.Set("Option_enabled", true);
57 /// Preference.Set("active_user", "Joe");
58 /// Preference.Set("default_volume", 10);
59 /// Preference.Set("brightness", "0.6");
60 /// foreach(string key in Preference.Keys)
62 /// Console.WriteLine("key {0}", key);
66 public static IEnumerable<string> Keys
70 var collection = new List<string>();
71 Interop.Preference.ItemCallback itemsCallback = (string key, IntPtr userData) =>
76 Interop.Preference.ForeachItem(itemsCallback, IntPtr.Zero);
82 /// Gets the event context for the given key.
84 /// <seealso cref="EventContext"/>
85 /// <param name="key">The preference key</param>
86 /// <returns>The event context of respective key</returns>
87 /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
88 /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
91 /// private static void Preference_PreferenceChanged(object sender, PreferenceChangedEventArgs e)
93 /// Console.WriteLine("key {0}", e.Key);
96 /// Preference.EventContext context = null;
97 /// Preference.GetEventContext("active_user").TryGetTarget(out context);
98 /// if(context != null)
100 /// context.Changed += Preference_PreferenceChanged;
103 /// Preference.Set("active_user", "Poe");
105 /// Preference.GetEventContext("active_user").TryGetTarget(out context);
106 /// if (context != null)
108 /// context.Changed -= Preference_PreferenceChanged;
112 public static WeakReference<EventContext> GetEventContext(string key)
114 if (!s_eventMap.ContainsKey(key))
118 s_eventMap[key] = new EventContext(key);
122 throw PreferenceErrorFactory.GetException((int)PreferenceErrorFactory.PreferenceError.KeyNotAvailable);
126 return new WeakReference<EventContext>(s_eventMap[key]);
130 /// Checks whether the given key exists in the preference.
132 /// <param name="key">The name of the key to check</param>
133 /// <returns>true if the key exists in the preference, otherwise false</returns>
134 /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
135 /// <exception cref="IOException">Thrown when method failed due to internal IO error.</exception>
138 /// Preference.Set("active_user", "Joe");
139 /// bool exists = Preference.Contains("active_user");
142 /// string value = Preference.Get<string>("active_user");
143 /// Console.WriteLine("user {0}", value);
147 public static bool Contains(string key)
150 int ret = Interop.Preference.IsExisting(key, out contains);
151 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
153 Log.Error(LogTag, "Failed to find key");
154 throw PreferenceErrorFactory.GetException(ret);
161 /// Sets a key-value pair representing the preference.
164 /// If the key already exists in the Preference, old value will be overwritten with new value.
165 /// Data types supported for value are: integer, double, string and bool.
167 /// <param name="key">The name of the key to create/modigy</param>
168 /// <param name="value">The value corresponding to the key.</param>
169 /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
170 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
173 /// Preference.Set("Option_enabled", true);
174 /// Preference.Set("active_user", "Joe");
175 /// Preference.Set("default_volume", 10);
176 /// Preference.Set("brightness", "0.6");
179 public static void Set(string key, object value)
184 ret = Interop.Preference.SetInt(key, (int)value);
185 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
187 Log.Error(LogTag, "Failed to find key");
188 throw PreferenceErrorFactory.GetException(ret);
191 else if (value is double)
193 ret = Interop.Preference.SetDouble(key, (double)value);
194 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
196 Log.Error(LogTag, "Failed to find key");
197 throw PreferenceErrorFactory.GetException(ret);
200 else if (value is string)
202 ret = Interop.Preference.SetString(key, (string)value);
203 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
205 Log.Error(LogTag, "Failed to find key");
206 throw PreferenceErrorFactory.GetException(ret);
209 else if (value is bool)
211 ret = Interop.Preference.SetBoolean(key, (bool)value);
212 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
214 Log.Error(LogTag, "Failed to find key");
215 throw PreferenceErrorFactory.GetException(ret);
220 Log.Error(LogTag, "Failed to Set");
221 throw new ArgumentException("Invalid parameter");
226 /// Gets the value of a preference item with the specified key.
227 /// Note that this is a generic method.
229 /// <typeparam name="T">The generic type to return.</typeparam>
230 /// <param name="key">The key of the preference</param>
231 /// <returns>The value of the preference item if it is of the specified generic type.</returns>
232 /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
233 /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
234 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
237 /// bool exists = Preference.Contains("active_user");
240 /// string value = Preference.Get<string>("active_user");
241 /// Console.WriteLine("user {0}", value);
245 public static T Get<T>(string key)
247 object result = null;
248 int ret = (int)PreferenceErrorFactory.PreferenceError.None;
249 if (typeof(T) == typeof(bool))
252 ret = Interop.Preference.GetBoolean(key, out val);
255 else if (typeof(T) == typeof(int))
258 ret = Interop.Preference.GetInt(key, out val);
261 else if (typeof(T) == typeof(string))
264 ret = Interop.Preference.GetString(key, out val);
267 else if (typeof(T) == typeof(double))
270 ret = Interop.Preference.GetDouble(key, out val);
275 Log.Error(LogTag, "Failed to remove key");
276 throw new ArgumentException("Invalid parameter");
279 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
281 Log.Error(LogTag, "Failed to remove key");
282 throw PreferenceErrorFactory.GetException(ret);
285 return (result != null) ? (T)result : default(T);
289 /// Removes any preference value with the given key.
291 /// <param name="key">The key to remove</param>
292 /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
293 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
296 /// bool exists = Preference.Contains("active_user");
299 /// string value = Preference.Remove("active_user");
303 public static void Remove(string key)
305 int ret = Interop.Preference.Remove(key);
306 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
308 Log.Error(LogTag, "Failed to remove key");
309 throw PreferenceErrorFactory.GetException(ret);
314 /// Removes all key-value pairs from the preference.
316 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
319 /// Preference.Set("Option_enabled", true);
320 /// Preference.Set("active_user", "Joe");
321 /// Preference.Set("default_volume", 10);
322 /// Preference.Set("brightness", "0.6");
323 /// Preference.RemoveAll();
326 public static void RemoveAll()
328 int ret = Interop.Preference.RemoveAll();
329 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
331 Log.Error(LogTag, "Failed to remove all keys");
332 throw PreferenceErrorFactory.GetException(ret);
336 private static void AllowChangeNotifications(string key)
338 int ret = Interop.Preference.SetChangedCb(key, s_preferenceChangedCallback, IntPtr.Zero);
339 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
341 Log.Error(LogTag, "Failed to set key notification");
342 throw PreferenceErrorFactory.GetException(ret);
346 private static void DisallowChangeNotifications(string key)
348 int ret = Interop.Preference.UnsetChangedCb(key);
349 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
351 Log.Error(LogTag, "Failed to remove key notification");
352 throw PreferenceErrorFactory.GetException(ret);
357 /// The class manages event handlers of preference keys. The class enables having event handlers for individual preference keys.
359 public class EventContext
363 internal EventContext(string key)
369 /// Occurs whenever there is change in the value of preference key.
371 /// <exception cref="System.ArgumentException">Thrown when the key does not exist or when there is an invalid parameter.</exception>
372 /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
375 /// private static void Preference_PreferenceChanged(object sender, PreferenceChangedEventArgs e)
377 /// Console.WriteLine("key {0}", e.Key);
379 /// Preference.EventContext context = null;
380 /// Preference.GetEventContext("active_user").TryGetTarget(out context);
381 /// if(context != null)
383 /// context.Changed += Preference_PreferenceChanged;
386 /// Preference.Set("active_user", "Poe");
388 /// Preference.GetEventContext("active_user").TryGetTarget(out context);
389 /// if (context != null)
391 /// context.Changed -= Preference_PreferenceChanged;
395 public event EventHandler<PreferenceChangedEventArgs> Changed
399 if (_changed == null)
401 AllowChangeNotifications(_key);
410 if (_changed == null)
412 DisallowChangeNotifications(_key);
413 s_eventMap.Remove(_key);
418 private event EventHandler<PreferenceChangedEventArgs> _changed;
420 internal void FireEvent()
422 _changed?.Invoke(null, new PreferenceChangedEventArgs() { Key = _key });
428 internal static class PreferenceErrorFactory
430 internal enum PreferenceError
432 None = ErrorCode.None,
433 OutOfMemory = ErrorCode.OutOfMemory,
434 InvalidParameter = ErrorCode.InvalidParameter,
435 KeyNotAvailable = -0x01100000 | 0x30,
436 IoError = ErrorCode.IoError
439 static internal Exception GetException(int error)
441 if ((PreferenceError)error == PreferenceError.OutOfMemory)
443 return new OutOfMemoryException("Out of memory");
445 else if ((PreferenceError)error == PreferenceError.InvalidParameter)
447 return new ArgumentException("Invalid parameter");
449 else if ((PreferenceError)error == PreferenceError.KeyNotAvailable)
451 return new KeyNotFoundException("Key does not exist in the bundle");
453 else if ((PreferenceError)error == PreferenceError.IoError)
455 return new System.IO.IOException("I/O Error");
459 return new ArgumentException("Unknown error");