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)ErrorCode.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);
221 /// Gets the value of a preference item with the specified key.
222 /// Note that this is a generic method.
224 /// <typeparam name="T">The generic type to return.</typeparam>
225 /// <param name="key">The key of the preference</param>
226 /// <returns>The value of the preference item if it is of the specified generic type.</returns>
227 /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
228 /// <exception cref="ArgumentException">Thrown if the key is an invalid parameter.</exception>
229 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
232 /// bool exists = Preference.Contains("active_user");
235 /// string value = Preference.Get<string>("active_user");
236 /// Console.WriteLine("user {0}", value);
240 public static T Get<T>(string key)
242 object result = null;
243 int ret = (int)PreferenceErrorFactory.PreferenceError.None;
244 if (typeof(T) == typeof(bool))
247 ret = Interop.Preference.GetBoolean(key, out val);
250 else if (typeof(T) == typeof(int))
253 ret = Interop.Preference.GetInt(key, out val);
256 else if (typeof(T) == typeof(string))
259 ret = Interop.Preference.GetString(key, out val);
262 else if (typeof(T) == typeof(double))
265 ret = Interop.Preference.GetDouble(key, out val);
270 Log.Error(LogTag, "Failed to remove key");
271 throw new ArgumentException("Invalid parameter");
274 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
276 Log.Error(LogTag, "Failed to remove key");
277 throw PreferenceErrorFactory.GetException(ret);
280 return (result != null) ? (T)result : default(T);
284 /// Removes any preference value with the given key.
286 /// <param name="key">The key to remove</param>
287 /// <exception cref="KeyNotFoundException">Thrown if the key is not found</exception>
288 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
291 /// bool exists = Preference.Contains("active_user");
294 /// string value = Preference.Remove("active_user");
298 public static void Remove(string key)
300 int ret = Interop.Preference.Remove(key);
301 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
303 Log.Error(LogTag, "Failed to remove key");
304 throw PreferenceErrorFactory.GetException(ret);
309 /// Removes all key-value pairs from the preference.
311 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error.</exception>
314 /// Preference.Set("Option_enabled", true);
315 /// Preference.Set("active_user", "Joe");
316 /// Preference.Set("default_volume", 10);
317 /// Preference.Set("brightness", "0.6");
318 /// Preference.RemoveAll();
321 public static void RemoveAll()
323 int ret = Interop.Preference.RemoveAll();
324 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
326 Log.Error(LogTag, "Failed to remove all keys");
327 throw PreferenceErrorFactory.GetException(ret);
331 private static void AllowChangeNotifications(string key)
333 int ret = Interop.Preference.SetChangedCb(key, s_preferenceChangedCallback, IntPtr.Zero);
334 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
336 Log.Error(LogTag, "Failed to set key notification");
337 throw PreferenceErrorFactory.GetException(ret);
341 private static void DisallowChangeNotifications(string key)
343 int ret = Interop.Preference.UnsetChangedCb(key);
344 if (ret != (int)PreferenceErrorFactory.PreferenceError.None)
346 Log.Error(LogTag, "Failed to remove key notification");
347 throw PreferenceErrorFactory.GetException(ret);
352 /// The class manages event handlers of preference keys. The class enables having event handlers for individual preference keys.
354 public class EventContext
358 internal EventContext(string key)
364 /// Occurs whenever there is change in the value of preference key.
366 /// <exception cref="System.ArgumentException">Thrown when the key does not exist or when there is an invalid parameter.</exception>
367 /// <exception cref="System.InvalidOperationException">Thrown when the Bundle instance has been disposed.</exception>
370 /// private static void Preference_PreferenceChanged(object sender, PreferenceChangedEventArgs e)
372 /// Console.WriteLine("key {0}", e.Key);
374 /// Preference.EventContext context = null;
375 /// Preference.GetEventContext("active_user").TryGetTarget(out context);
376 /// if(context != null)
378 /// context.Changed += Preference_PreferenceChanged;
381 /// Preference.Set("active_user", "Poe");
383 /// Preference.GetEventContext("active_user").TryGetTarget(out context);
384 /// if (context != null)
386 /// context.Changed -= Preference_PreferenceChanged;
390 public event EventHandler<PreferenceChangedEventArgs> Changed
394 if (_changed == null)
396 AllowChangeNotifications(_key);
405 if (_changed == null)
407 DisallowChangeNotifications(_key);
408 s_eventMap.Remove(_key);
413 private event EventHandler<PreferenceChangedEventArgs> _changed;
415 internal void FireEvent()
417 _changed?.Invoke(null, new PreferenceChangedEventArgs() { Key = _key });
423 internal static class PreferenceErrorFactory
425 internal enum PreferenceError
427 None = ErrorCode.None,
428 OutOfMemory = ErrorCode.OutOfMemory,
429 InvalidParameter = ErrorCode.InvalidParameter,
430 KeyNotAvailable = -0x01100000 | 0x30,
431 IoError = ErrorCode.IoError
434 static internal Exception GetException(int error)
436 if ((PreferenceError)error == PreferenceError.OutOfMemory)
438 return new OutOfMemoryException("Out of memory");
440 else if ((PreferenceError)error == PreferenceError.InvalidParameter)
442 return new ArgumentException("Invalid parameter");
444 else if ((PreferenceError)error == PreferenceError.KeyNotAvailable)
446 return new KeyNotFoundException("Key does not exist in the bundle");
448 else if ((PreferenceError)error == PreferenceError.IoError)
450 return new System.IO.IOException("I/O Error");
454 return new ArgumentException("Unknown error");