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;
20 using System.Runtime.InteropServices;
22 namespace Tizen.Applications
25 /// Represents the control message to exchange between applications.
29 /// public class AppControlExample : UIApplication
32 /// protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
34 /// AppControl appControl = new AppControl();
35 /// appControl.ApplicationId = "org.tizen.calculator";
36 /// AppControl.SendLaunchRequest(appControl, (launchRequest, replyRequest, result) => {
43 /// <since_tizen> 3 </since_tizen>
44 public class AppControl
46 private const string LogTag = "Tizen.Applications";
48 private static Dictionary<int, Interop.AppControl.ReplyCallback> s_replyNativeCallbackMaps = new Dictionary<int, Interop.AppControl.ReplyCallback>();
49 private static int s_replyNativeCallbackId = 0;
51 private readonly SafeAppControlHandle _handle;
53 private string _operation = null;
54 private string _mime = null;
55 private string _uri = null;
56 private string _category = null;
57 private string _applicationId = null;
58 private ExtraDataCollection _extraData = null;
61 /// Initializes the instance of the AppControl class.
63 /// <exception cref="InvalidOperationException">Thrown when failed to create the AppControl handle.</exception>
64 /// <since_tizen> 3 </since_tizen>
67 Interop.AppControl.ErrorCode err = Interop.AppControl.Create(out _handle);
68 if (err != Interop.AppControl.ErrorCode.None)
70 throw new InvalidOperationException("Failed to create the appcontrol handle. Err = " + err);
75 /// Initializes the instance of the AppControl class with a parameter.
77 /// <param name="enableAppStartedResultEvent">The flag value to receive an additional launch result event on the launch request.</param>
78 /// <exception cref="InvalidOperationException">Thrown when failed to create the AppControl handle.</exception>
79 /// <since_tizen> 3 </since_tizen>
80 public AppControl(bool enableAppStartedResultEvent)
82 Interop.AppControl.ErrorCode err = Interop.AppControl.Create(out _handle);
83 if (err != Interop.AppControl.ErrorCode.None)
85 throw new InvalidOperationException("Failed to create the appcontrol handle. Err = " + err);
88 if (enableAppStartedResultEvent)
90 err = Interop.AppControl.EnableAppStartedResultEvent(_handle);
91 if (err != Interop.AppControl.ErrorCode.None)
93 throw new InvalidOperationException("Failed to set EnableAppStartedResultEvent");
99 /// Initializes the instance of the AppControl class with the SafeAppControlHandle.
101 /// <param name="handle"></param>
102 /// <since_tizen> 3 </since_tizen>
103 public AppControl(SafeAppControlHandle handle)
107 throw new ArgumentNullException("handle");
110 Interop.AppControl.ErrorCode err = Interop.AppControl.DangerousClone(out _handle, handle.DangerousGetHandle());
111 if (err != Interop.AppControl.ErrorCode.None)
113 throw new InvalidOperationException("Failed to clone the appcontrol handle. Err = " + err);
117 private AppControl(IntPtr handle)
119 Interop.AppControl.ErrorCode err = Interop.AppControl.DangerousClone(out _handle, handle);
120 if (err != Interop.AppControl.ErrorCode.None)
122 throw new InvalidOperationException("Failed to clone the appcontrol handle. Err = " + err);
126 #region Public Properties
129 /// Gets the SafeAppControlHandle instance.
131 /// <since_tizen> 3 </since_tizen>
132 public SafeAppControlHandle SafeAppControlHandle
141 /// Gets and sets the operation to be performed.
144 /// The operation is the mandatory information for the launch request. If the operation is not specified,
145 /// AppControlOperations.Default is used for the launch request. If the operation is AppControlOperations.Default,
146 /// the package information is mandatory to explicitly launch the application.
147 /// (if the operation is null for setter, it clears the previous value.)
151 /// AppControl appControl = new AppControl();
152 /// appControl.Operation = AppControlOperations.Default;
153 /// Log.Debug(LogTag, "Operation: " + appControl.Operation);
156 /// <since_tizen> 3 </since_tizen>
157 public string Operation
161 if (String.IsNullOrEmpty(_operation))
163 Interop.AppControl.ErrorCode err = Interop.AppControl.GetOperation(_handle, out _operation);
164 if (err != Interop.AppControl.ErrorCode.None)
166 Log.Warn(LogTag, "Failed to get the operation from the appcontrol. Err = " + err);
173 Interop.AppControl.ErrorCode err = Interop.AppControl.SetOperation(_handle, value);
174 if (err == Interop.AppControl.ErrorCode.None)
180 Log.Warn(LogTag, "Failed to set the operation to the appcontrol. Err = " + err);
186 /// Gets and sets the explicit MIME type of the data.
189 /// (if the mime is null for setter, it clears the previous value.)
193 /// AppControl appControl = new AppControl();
194 /// appControl.Mime = "image/jpg";
195 /// Log.Debug(LogTag, "Mime: " + appControl.Mime);
198 /// <since_tizen> 3 </since_tizen>
203 if (String.IsNullOrEmpty(_mime))
205 Interop.AppControl.ErrorCode err = Interop.AppControl.GetMime(_handle, out _mime);
206 if (err != Interop.AppControl.ErrorCode.None)
208 Log.Warn(LogTag, "Failed to get the mime from the appcontrol. Err = " + err);
215 Interop.AppControl.ErrorCode err = Interop.AppControl.SetMime(_handle, value);
216 if (err == Interop.AppControl.ErrorCode.None)
222 Log.Warn(LogTag, "Failed to set the mime to the appcontrol. Err = " + err);
228 /// Gets and sets the URI of the data.
231 /// Since Tizen 2.4, if the parameter 'uri' is started with 'file://' and
232 /// it is a regular file in this application's data path, which can be obtained
233 /// by property DataPath in ApplicationInfo class,
234 /// it will be shared to the callee application.
235 /// Framework will grant a temporary permission to the callee application for this file and
236 /// revoke it when the callee application is terminated.
237 /// The callee application can just read it.
238 /// (if the uri is null for setter, it clears the previous value.)
242 /// public class AppControlExample : UIApplication
245 /// protected override void OnAppControlReceived(AppControlReceivedEventArgs e)
248 /// AppControl appControl = new AppControl();
249 /// appContrl.Uri = this.ApplicationInfo.DataPath + "image.jpg";
250 /// Log.Debug(LogTag, "Set Uri: " + appControl.Uri);
255 /// <since_tizen> 3 </since_tizen>
260 if (String.IsNullOrEmpty(_uri))
262 Interop.AppControl.ErrorCode err = Interop.AppControl.GetUri(_handle, out _uri);
263 if (err != Interop.AppControl.ErrorCode.None)
265 Log.Warn(LogTag, "Failed to get the uri from the appcontrol. Err = " + err);
272 Interop.AppControl.ErrorCode err = Interop.AppControl.SetUri(_handle, value);
273 if (err == Interop.AppControl.ErrorCode.None)
279 Log.Warn(LogTag, "Failed to set the uri to the appcontrol. Err = " + err);
285 /// Gets and sets the explicit category.
288 /// (if the category is null for setter, it clears the previous value.)
290 /// <since_tizen> 3 </since_tizen>
291 public string Category
295 if (String.IsNullOrEmpty(_category))
297 Interop.AppControl.ErrorCode err = Interop.AppControl.GetCategory(_handle, out _category);
298 if (err != Interop.AppControl.ErrorCode.None)
300 Log.Warn(LogTag, "Failed to get the category from the appcontrol. Err = " + err);
307 Interop.AppControl.ErrorCode err = Interop.AppControl.SetCategory(_handle, value);
308 if (err == Interop.AppControl.ErrorCode.None)
314 Log.Warn(LogTag, "Failed to set the category to the appcontrol. Err = " + err);
320 /// Gets and sets the application ID to explicitly launch.
323 /// (if the application ID is null for setter, it clears the previous value.)
327 /// AppControl appControl = new AppControl();
328 /// appControl.ApplicationId = "org.tizen.calculator";
329 /// Log.Debug(LogTag, "ApplicationId: " + appControl.ApplicationId);
332 /// <since_tizen> 3 </since_tizen>
333 public string ApplicationId
337 if (String.IsNullOrEmpty(_applicationId))
339 Interop.AppControl.ErrorCode err = Interop.AppControl.GetAppId(_handle, out _applicationId);
340 if (err != Interop.AppControl.ErrorCode.None)
342 Log.Warn(LogTag, "Failed to get the application id from the AppControl. Err = " + err);
345 return _applicationId;
349 Interop.AppControl.ErrorCode err = Interop.AppControl.SetAppId(_handle, value);
350 if (err == Interop.AppControl.ErrorCode.None)
352 _applicationId = value;
356 Log.Warn(LogTag, "Failed to set the application id to the AppControl. Err = " + err);
362 /// Gets and sets the launch mode of the application.
365 /// Although, LaunchMode were set as AppControlLaunchMode.Group, the
366 /// callee application would be launched as a single mode
367 /// if the manifest file of callee application defined the launch mode as "single".
368 /// This property can just set the preference of the caller application to launch an application.
369 /// Sub-applications, which were launched as a group mode always have own process.
370 /// Since Tizen 3.0, if launch mode is not set in the caller application control,
371 /// this property returns the AppControlLaunchMode.Single launch mode.
375 /// AppControl appControl = new AppControl();
376 /// appControl.LaunchMode = AppControlLaunchMode.Group;
379 /// <since_tizen> 3 </since_tizen>
380 public AppControlLaunchMode LaunchMode
385 Interop.AppControl.ErrorCode err = Interop.AppControl.GetLaunchMode(_handle, out value);
386 if (err != Interop.AppControl.ErrorCode.None)
388 Log.Warn(LogTag, "Failed to get the LaunchMode from the AppControl. Err = " + err);
390 return (AppControlLaunchMode)value;
394 Interop.AppControl.ErrorCode err = Interop.AppControl.SetLaunchMode(_handle, (int)value);
395 if (err != Interop.AppControl.ErrorCode.None)
397 Log.Warn(LogTag, "Failed to set the LaunchMode to the AppControl. Err = " + err);
403 /// Gets the collection of the extra data.
406 /// Extra data for communication between AppControls.
410 /// AppControl appControl = new AppControl();
411 /// appControl.ExtraData.Add("key", "value");
415 /// <since_tizen> 3 </since_tizen>
416 public ExtraDataCollection ExtraData
420 if (_extraData == null)
421 _extraData = new ExtraDataCollection(_handle);
426 #endregion // Public Properties
429 /// Retrieves all applications that can be launched to handle the given app_control request.
431 /// <param name="control">The AppControl.</param>
432 /// <returns>ApplicationIds.</returns>
433 /// <exception cref="InvalidOperationException">Thrown when failed because of an invalid parameter.</exception>
436 /// IEnumerable<string> applicationIds = AppControl.GetMatchedApplicationIds(control);
437 /// if (applicationIds != null)
439 /// foreach (string id in applicationIds)
446 /// <since_tizen> 3 </since_tizen>
447 public static IEnumerable<string> GetMatchedApplicationIds(AppControl control)
451 throw new ArgumentNullException("control");
454 List<string> ids = new List<string>();
455 Interop.AppControl.AppMatchedCallback callback = (handle, applicationId, userData) =>
457 if (applicationId == null)
462 ids.Add(applicationId);
466 Interop.AppControl.ErrorCode err = Interop.AppControl.ForeachAppMatched(control._handle, callback, IntPtr.Zero);
467 if (err != Interop.AppControl.ErrorCode.None)
469 throw new InvalidOperationException("Failed to get matched application ids. err = " + err);
476 /// Sends the launch request.
479 /// The operation is mandatory information for the launch request.
480 /// If the operation is not specified, AppControlOperations.Default is used by default.
481 /// If the operation is AppControlOperations.Default, the application ID is mandatory to explicitly launch the application.<br/>
482 /// Since Tizen 2.4, the launch request of the service application over out of packages is restricted by the platform.
483 /// Also, implicit launch requests are NOT delivered to service applications since 2.4.
484 /// To launch a service application, an explicit launch request with the application ID given by property ApplicationId MUST be sent.
486 /// <param name="launchRequest">The AppControl.</param>
487 /// <exception cref="ArgumentNullException">Thrown when failed because of a null argument.</exception>
488 /// <exception cref="InvalidOperationException">Thrown when failed because of an invalid operation.</exception>
489 /// <exception cref="TimeoutException">Thrown when failed because of timeout.</exception>
490 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
493 /// AppControl appControl = new AppControl();
494 /// appControl.ApplicationId = "org.tizen.calculator";
495 /// AppControl.SendLaunchRequest(appControl);
498 /// <since_tizen> 3 </since_tizen>
499 public static void SendLaunchRequest(AppControl launchRequest)
501 SendLaunchRequest(launchRequest, null);
505 /// Sends the launch request.
508 /// The operation is mandatory information for the launch request.
509 /// If the operation is not specified, AppControlOperations.Default is used by default.
510 /// If the operation is AppControlOperations.Default, the application ID is mandatory to explicitly launch the application.<br/>
511 /// Since Tizen 2.4, the launch request of the service application over out of packages is restricted by the platform.
512 /// Also, implicit launch requests are NOT delivered to service applications since 2.4.
513 /// To launch a service application, an explicit launch request with the application ID given by property ApplicationId MUST be sent.
515 /// <param name="launchRequest">The AppControl.</param>
516 /// <param name="replyAfterLaunching">The callback function to be called when the reply is delivered.</param>
517 /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
518 /// <exception cref="Exceptions.AppNotFoundException">Thrown when the application to run is not found.</exception>
519 /// <exception cref="Exceptions.LaunchFailedException">Thrown when the request failed to launch the application.</exception>
520 /// <exception cref="Exceptions.LaunchRejectedException">Thrown when the launch request is rejected.</exception>
521 /// <exception cref="Exceptions.OutOfMemoryException">Thrown when the memory is insufficient.</exception>
522 /// <exception cref="Exceptions.PermissionDeniedException">Thrown when the permission is denied.</exception>
523 /// <exception cref="TimeoutException">Thrown when failed because of timeout.</exception>
524 /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
527 /// AppControl appControl = new AppControl();
528 /// appControl.ApplicationId = "org.tizen.calculator";
529 /// AppControl.SendLaunchRequest(appControl, (launchRequest, replyRequest, result) => {
534 /// <since_tizen> 3 </since_tizen>
535 public static void SendLaunchRequest(AppControl launchRequest, AppControlReplyCallback replyAfterLaunching)
537 if (launchRequest == null)
539 throw new ArgumentNullException("launchRequest");
542 Interop.AppControl.ErrorCode err;
544 if (replyAfterLaunching != null)
547 lock (s_replyNativeCallbackMaps)
549 id = s_replyNativeCallbackId++;
550 s_replyNativeCallbackMaps[id] = (launchRequestHandle, replyRequestHandle, result, userData) =>
552 if (replyAfterLaunching != null)
554 Log.Debug(LogTag, "Reply Callback is launched");
555 replyAfterLaunching(new AppControl(launchRequestHandle), new AppControl(replyRequestHandle), (AppControlReplyResult)result);
556 if (result != Interop.AppControl.AppStartedStatus)
558 lock (s_replyNativeCallbackMaps)
560 s_replyNativeCallbackMaps.Remove(id);
566 err = Interop.AppControl.SendLaunchRequest(launchRequest._handle, s_replyNativeCallbackMaps[id], IntPtr.Zero);
570 err = Interop.AppControl.SendLaunchRequest(launchRequest._handle, null, IntPtr.Zero);
573 if (err != Interop.AppControl.ErrorCode.None)
577 case Interop.AppControl.ErrorCode.InvalidParameter:
578 throw new ArgumentException("Invalid Arguments");
579 case Interop.AppControl.ErrorCode.TimedOut:
580 throw new TimeoutException("Timed out");
581 case Interop.AppControl.ErrorCode.OutOfMemory:
582 throw new Exceptions.OutOfMemoryException("Out-of-memory");
583 case Interop.AppControl.ErrorCode.AppNotFound:
584 throw new Exceptions.AppNotFoundException("App not found");
585 case Interop.AppControl.ErrorCode.LaunchRejected:
586 throw new Exceptions.LaunchRejectedException("Launch rejected");
587 case Interop.AppControl.ErrorCode.LaunchFailed:
588 throw new Exceptions.LaunchFailedException("Launch failed");
589 case Interop.AppControl.ErrorCode.PermissionDenied:
590 throw new Exceptions.PermissionDeniedException("Permission denied");
593 throw new Exceptions.LaunchRejectedException("Launch rejected");
599 /// Sends the terminate request to the application that is launched by AppControl.
602 /// You are not allowed to terminate other general applications using this API.
603 /// This API can be used to terminate sub-applications, which were launched as a group mode by the caller application.
604 /// Once the callee application is being terminated by this API,
605 /// other applications, which were launched by the callee application as a group mode will be terminated as well.
607 /// <param name="terminateRequest">The AppControl.</param>
608 /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
609 /// <exception cref="InvalidOperationException">Thrown when failed because of an invalid operation.</exception>
610 /// <exception cref="TimeoutException">Thrown when failed because of timeout.</exception>
613 /// AppControl terminateRequest = new AppControl();
614 /// terminateRequest.ApplicationId = "org.tizen.calculator";
615 /// AppControl.SendTerminateRequest(terminateRequest);
618 /// <since_tizen> 3 </since_tizen>
619 public static void SendTerminateRequest(AppControl terminateRequest)
621 if (terminateRequest == null)
623 throw new ArgumentNullException("terminateRequest");
625 Interop.AppControl.ErrorCode err;
627 err = Interop.AppControl.SendTerminateRequest(terminateRequest._handle);
629 if (err != Interop.AppControl.ErrorCode.None)
633 case Interop.AppControl.ErrorCode.InvalidParameter:
634 throw new ArgumentException("Invalid Arguments");
635 case Interop.AppControl.ErrorCode.TimedOut:
636 throw new TimeoutException("Timed out");
638 throw new InvalidOperationException("Error = " + err);
644 /// Class for extra data.
646 /// <since_tizen> 3 </since_tizen>
647 public class ExtraDataCollection
649 private readonly SafeAppControlHandle _handle;
651 internal ExtraDataCollection(SafeAppControlHandle handle)
660 /// The function replaces any existing value for the given key.
662 /// <param name="key">The name of the extra data.</param>
663 /// <param name="value">The value associated with the given key.</param>
664 /// <exception cref="ArgumentNullException">Thrown when a key or a value is a zero-length string.</exception>
665 /// <exception cref="ArgumentException">Thrown when the application tries to use the same key with the system-defined key.</exception>
668 /// AppControl appControl = new AppControl();
669 /// appControl.ExtraData.Add("myKey", "myValue");
672 /// <since_tizen> 3 </since_tizen>
673 public void Add(string key, string value)
675 if (string.IsNullOrEmpty(key))
677 throw new ArgumentNullException("key");
679 if (string.IsNullOrEmpty(value))
681 throw new ArgumentNullException("value");
683 Interop.AppControl.ErrorCode err = Interop.AppControl.AddExtraData(_handle, key, value);
684 if (err != Interop.AppControl.ErrorCode.None)
688 case Interop.AppControl.ErrorCode.InvalidParameter:
689 throw new ArgumentException("Invalid parameter: key or value is a zero-length string");
690 case Interop.AppControl.ErrorCode.KeyRejected:
691 throw new ArgumentException("Key is rejected: the key is system-defined key.");
693 throw new InvalidOperationException("Error = " + err);
702 /// The function replaces any existing value for the given key.
704 /// <param name="key">The name of the extra data.</param>
705 /// <param name="value">The value associated with the given key.</param>
706 /// <exception cref="ArgumentNullException">Thrown when key or value is a zero-length string.</exception>
707 /// <exception cref="ArgumentException">Thrown when the application tries to use the same key with the system-defined key.</exception>
710 /// AppControl appControl = new AppControl();
711 /// string[] myValues = new string[] { "first", "second", "third" };
712 /// appControl.ExtraData.Add("myKey", myValues);
715 /// <since_tizen> 3 </since_tizen>
716 public void Add(string key, IEnumerable<string> value)
718 if (string.IsNullOrEmpty(key))
720 throw new ArgumentNullException("key");
724 throw new ArgumentNullException("value");
726 string[] valueArray = value.ToArray();
727 Interop.AppControl.ErrorCode err = Interop.AppControl.AddExtraDataArray(_handle, key, valueArray, valueArray.Length);
728 if (err != Interop.AppControl.ErrorCode.None)
732 case Interop.AppControl.ErrorCode.InvalidParameter:
733 throw new ArgumentException("Invalid parameter: key or value is a zero-length string");
734 case Interop.AppControl.ErrorCode.KeyRejected:
735 throw new ArgumentException("Key is rejected: the key is system-defined key.");
737 throw new InvalidOperationException("Error = " + err);
743 /// Gets the extra data.
745 /// <typeparam name="T">Only string and IEnumerable<string></typeparam>
746 /// <param name="key">The name of extra data.</param>
747 /// <returns>The value associated with the given key.</returns>
748 /// <exception cref="ArgumentNullException">Thrown when the key is an invalid parameter.</exception>
749 /// <exception cref="KeyNotFoundException">Thrown when the key is not found.</exception>
750 /// <exception cref="ArgumentException">Thrown when the key is rejected.</exception>
753 /// AppControl appControl = new AppControl();
754 /// string myValue = appControl.ExtraData.Get<string>("myKey");
757 /// <since_tizen> 3 </since_tizen>
758 public T Get<T>(string key)
760 object ret = Get(key);
765 /// Gets the extra data.
767 /// <param name="key">The name of extra data.</param>
768 /// <returns>The value associated with the given key.</returns>
769 /// <exception cref="ArgumentNullException">Thrown when the key is an invalid parameter.</exception>
770 /// <exception cref="KeyNotFoundException">Thrown when the key is not found.</exception>
771 /// <exception cref="ArgumentException">Thrown when the key is rejected.</exception>
774 /// AppControl appControl = new AppControl();
775 /// string myValue = appControl.ExtraData.Get("myKey") as string;
776 /// if (myValue != null)
782 /// <since_tizen> 3 </since_tizen>
783 public object Get(string key)
785 if (IsCollection(key))
787 return GetDataCollection(key);
796 /// Gets all keys in extra data.
798 /// <returns>The keys in the AppControl.</returns>
799 /// <exception cref="InvalidOperationException">Thrown when the key is an invalid parameter.</exception>
802 /// AppControl appControl = new AppControl();
803 /// IEnumerable<string> keys = appControl.GetKeys();
804 /// if (keys != null)
806 /// foreach (string key in keys)
813 /// <since_tizen> 3 </since_tizen>
814 public IEnumerable<string> GetKeys()
816 List<string> keys = new List<string>();
817 Interop.AppControl.ExtraDataCallback callback = (handle, key, userData) =>
828 Interop.AppControl.ErrorCode err = Interop.AppControl.ForeachExtraData(_handle, callback, IntPtr.Zero);
829 if (err != Interop.AppControl.ErrorCode.None)
831 throw new InvalidOperationException("Failed to get keys. err = " + err);
838 /// Tries getting the extra data.
840 /// <param name="key">The name of extra data.</param>
841 /// <param name="value">The value associated with the given key.</param>
842 /// <returns>The result whether getting the value is done.</returns>
843 /// <exception cref="ArgumentNullException">Thrown when the key is an invalid parameter.</exception>
844 /// <exception cref="KeyNotFoundException">Thrown when the key is not found.</exception>
845 /// <exception cref="ArgumentException">Thrown when the key is rejected.</exception>
848 /// AppControl appControl = new AppControl();
849 /// string myValue = string.Empty;
850 /// bool result = appControl.ExtraData.TryGet("myKey", out myValue);
851 /// if (result != null)
857 /// <since_tizen> 3 </since_tizen>
858 public bool TryGet(string key, out string value)
860 if (string.IsNullOrEmpty(key))
862 throw new ArgumentNullException("key");
864 Interop.AppControl.GetExtraData(_handle, key, out value);
871 value = default(string);
877 /// Tries getting the extra data.
879 /// <param name="key">The name of extra data.</param>
880 /// <param name="value">The value associated with the given key.</param>
881 /// <returns>The result whether getting the value is done.</returns>
882 /// <exception cref="ArgumentNullException">Thrown when the key is an invalid parameter.</exception>
883 /// <exception cref="KeyNotFoundException">Thrown when the key is not found.</exception>
884 /// <exception cref="ArgumentException">Thrown when the key is rejected.</exception>
887 /// AppControl appControl = new AppControl();
888 /// IEnumerable<string> myValue = null;
889 /// bool result = appControl.ExtraData.TryGet("myKey", out myValue);
892 /// foreach (string value in myValue)
899 /// <since_tizen> 3 </since_tizen>
900 public bool TryGet(string key, out IEnumerable<string> value)
902 if (string.IsNullOrEmpty(key))
904 throw new ArgumentNullException("key");
906 IntPtr valuePtr = IntPtr.Zero;
908 Interop.AppControl.ErrorCode err = Interop.AppControl.GetExtraDataArray(_handle, key, out valuePtr, out len);
909 if (err == Interop.AppControl.ErrorCode.None && valuePtr != IntPtr.Zero)
911 List<string> stringList = new List<string>();
912 for (int i = 0; i < len; ++i)
914 IntPtr charArr = Marshal.ReadIntPtr(valuePtr, IntPtr.Size * i);
915 stringList.Add(Marshal.PtrToStringAnsi(charArr));
916 Interop.Libc.Free(charArr);
918 Interop.Libc.Free(valuePtr);
924 value = default(IEnumerable<string>);
930 /// Removes the extra data.
932 /// <param name="key">The name of the extra data.</param>
933 /// <exception cref="ArgumentNullException">Thrown when the key is a zero-length string.</exception>
934 /// <exception cref="KeyNotFoundException">Thrown when the key is not found.</exception>
935 /// <exception cref="ArgumentException">Thrown when the key is rejected.</exception>
938 /// AppControl appControl = new AppControl();
939 /// appControl.ExtraData.Remove("myKey");
942 /// <since_tizen> 3 </since_tizen>
943 public void Remove(string key)
945 if (string.IsNullOrEmpty(key))
947 throw new ArgumentNullException("key");
949 Interop.AppControl.ErrorCode err = Interop.AppControl.RemoveExtraData(_handle, key);
950 if (err != Interop.AppControl.ErrorCode.None)
954 case Interop.AppControl.ErrorCode.InvalidParameter:
955 throw new ArgumentException("Invalid parameter: key is a zero-length string");
956 case Interop.AppControl.ErrorCode.KeyNotFound:
957 throw new KeyNotFoundException("Key is not found"); ;
958 case Interop.AppControl.ErrorCode.KeyRejected:
959 throw new ArgumentException("Key is rejected: the key is system-defined key.");
961 throw new InvalidOperationException("Error = " + err);
967 /// Counts keys in the extra data.
969 /// <returns>The number of counting keys.</returns>
970 /// <exception cref="InvalidOperationException">Thrown when the key is an invalid parameter.</exception>
973 /// AppControl appControl = new AppControl();
974 /// int numberOfKeys = appControl.ExtraData.Count();
977 /// <since_tizen> 3 </since_tizen>
980 return GetKeys().Count();
984 /// Checks whether the extra data associated with the given key is of the collection data type.
986 /// <param name="key">The name of the extra data.</param>
987 /// <returns>If true, the extra data is of the array data type, otherwise false.</returns>
988 /// <exception cref="ArgumentNullException">Thrown when the key is a zero-length string.</exception>
989 /// <exception cref="InvalidOperationException">Thrown when failed to check the key.</exception>
992 /// AppControl appControl = new AppControl();
993 /// bool result = appControl.ExtraData.IsCollection("myKey");
996 /// <since_tizen> 3 </since_tizen>
997 public bool IsCollection(string key)
999 if (string.IsNullOrEmpty(key))
1001 throw new ArgumentNullException("key");
1003 bool isArray = false;
1004 Interop.AppControl.ErrorCode err = Interop.AppControl.IsExtraDataArray(_handle, key, out isArray);
1005 if (err != Interop.AppControl.ErrorCode.None)
1007 throw new InvalidOperationException("Error = " + err);
1012 private string GetData(string key)
1014 if (string.IsNullOrEmpty(key))
1016 throw new ArgumentNullException("key");
1018 string value = string.Empty;
1019 Interop.AppControl.ErrorCode err = Interop.AppControl.GetExtraData(_handle, key, out value);
1020 if (err != Interop.AppControl.ErrorCode.None)
1024 case Interop.AppControl.ErrorCode.InvalidParameter:
1025 throw new ArgumentException("Invalid parameter: key is a zero-length string");
1026 case Interop.AppControl.ErrorCode.KeyNotFound:
1027 throw new KeyNotFoundException("Key is not found"); ;
1028 case Interop.AppControl.ErrorCode.InvalidDataType:
1029 throw new ArgumentException("Invalid data type: value is data collection type");
1030 case Interop.AppControl.ErrorCode.KeyRejected:
1031 throw new ArgumentException("Key is rejected: the key is system-defined key.");
1033 throw new InvalidOperationException("Error = " + err);
1039 private IEnumerable<string> GetDataCollection(string key)
1041 if (string.IsNullOrEmpty(key))
1043 throw new ArgumentNullException("key");
1045 IntPtr valuePtr = IntPtr.Zero;
1047 Interop.AppControl.ErrorCode err = Interop.AppControl.GetExtraDataArray(_handle, key, out valuePtr, out len);
1048 if (err != Interop.AppControl.ErrorCode.None)
1052 case Interop.AppControl.ErrorCode.InvalidParameter:
1053 throw new ArgumentException("Invalid parameter: key is a zero-length string");
1054 case Interop.AppControl.ErrorCode.KeyNotFound:
1055 throw new KeyNotFoundException("Key is not found"); ;
1056 case Interop.AppControl.ErrorCode.InvalidDataType:
1057 throw new ArgumentException("Invalid data type: value is data collection type");
1058 case Interop.AppControl.ErrorCode.KeyRejected:
1059 throw new ArgumentException("Key is rejected: the key is system-defined key.");
1061 throw new InvalidOperationException("Error = " + err);
1065 List<string> valueArray = new List<string>();
1066 if (valuePtr != IntPtr.Zero)
1068 for (int i = 0; i < len; ++i)
1070 IntPtr charArr = Marshal.ReadIntPtr(valuePtr, IntPtr.Size * i);
1071 valueArray.Add(Marshal.PtrToStringAnsi(charArr));
1072 Interop.Libc.Free(charArr);
1074 Interop.Libc.Free(valuePtr);