{
internal const int AppStartedStatus = 1;
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate bool ExtraDataCallback(IntPtr handle, string key, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate bool AppMatchedCallback(IntPtr handle, string applicationId, IntPtr userData);
+
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
internal delegate void ReplyCallback(IntPtr request, IntPtr reply, int result, IntPtr userData);
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ internal delegate void ResultCallback(IntPtr request, int result, IntPtr userData);
+
internal enum ErrorCode
{
None = Tizen.Internals.Errors.ErrorCode.None,
[DllImport(Libraries.AppControl, EntryPoint = "app_control_enable_app_started_result_event")]
internal static extern ErrorCode EnableAppStartedResultEvent(SafeAppControlHandle handle);
+
+ [DllImport(Libraries.AppControl, EntryPoint = "app_control_send_launch_request_async")]
+ internal static extern ErrorCode SendLaunchRequestAsync(SafeAppControlHandle handle, ResultCallback resultCallback, ReplyCallback replyCallback, IntPtr userData);
}
}
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
+using System.Threading.Tasks;
namespace Tizen.Applications
{
{
private const string LogTag = "Tizen.Applications";
- private static Dictionary<int, Interop.AppControl.ReplyCallback> s_replyNativeCallbackMaps = new Dictionary<int, Interop.AppControl.ReplyCallback>();
- private static int s_replyNativeCallbackId = 0;
+ private static Dictionary<int, Interop.AppControl.ResultCallback> s_resultNativeCallbackMaps = new Dictionary<int, Interop.AppControl.ResultCallback>();
+ private static Dictionary<int, AppControlReplyCallback> s_replyCallbackMaps = new Dictionary<int, AppControlReplyCallback>();
+ private static int s_reaustId = 0;
private readonly SafeAppControlHandle _handle;
}
}
- #region Public Properties
+ private static Interop.AppControl.ReplyCallback s_replyNativeCallback = (launchHandle, replyHandle, result, userData) =>
+ {
+ int requestId = (int)userData;
+ lock (s_replyCallbackMaps)
+ {
+ if (s_replyCallbackMaps.ContainsKey(requestId))
+ {
+ s_replyCallbackMaps[requestId](new AppControl(launchHandle), new AppControl(replyHandle), (AppControlReplyResult)result);
+ if (result != Interop.AppControl.AppStartedStatus)
+ {
+ lock (s_replyCallbackMaps)
+ {
+ s_replyCallbackMaps.Remove(requestId);
+ }
+ }
+ }
+ }
+ };
+
+#region Public Properties
/// <summary>
/// Gets the SafeAppControlHandle instance.
}
}
- #endregion // Public Properties
+#endregion // Public Properties
/// <summary>
/// Retrieves all applications that can be launched to handle the given app_control request.
if (replyAfterLaunching != null)
{
int id = 0;
- lock (s_replyNativeCallbackMaps)
+ lock (s_replyCallbackMaps)
{
- id = s_replyNativeCallbackId++;
- s_replyNativeCallbackMaps[id] = (launchRequestHandle, replyRequestHandle, result, userData) =>
- {
- if (replyAfterLaunching != null)
- {
- Log.Debug(LogTag, "Reply Callback is launched");
- replyAfterLaunching(new AppControl(launchRequestHandle), new AppControl(replyRequestHandle), (AppControlReplyResult)result);
- if (result != Interop.AppControl.AppStartedStatus)
- {
- lock (s_replyNativeCallbackMaps)
- {
- s_replyNativeCallbackMaps.Remove(id);
- }
- }
- }
- };
+ id = s_reaustId++;
+ s_replyCallbackMaps[id] = replyAfterLaunching;
}
- err = Interop.AppControl.SendLaunchRequest(launchRequest._handle, s_replyNativeCallbackMaps[id], IntPtr.Zero);
+ err = Interop.AppControl.SendLaunchRequest(launchRequest._handle, s_replyNativeCallback, (IntPtr)id);
}
else
{
}
/// <summary>
+ /// Sends the launch request asynchronously.
+ /// </summary>
+ /// <remarks>
+ /// The operation is mandatory information for the launch request.
+ /// If the operation is not specified, AppControlOperations.Default is used by default.
+ /// If the operation is AppControlOperations.Default, the application ID is mandatory to explicitly launch the application.<br/>
+ /// Since Tizen 2.4, the launch request of the service application over out of packages is restricted by the platform.
+ /// Also, implicit launch requests are NOT delivered to service applications since 2.4.
+ /// To launch a service application, an explicit launch request with the application ID given by property ApplicationId MUST be sent.
+ /// </remarks>
+ /// <param name="launchRequest">The AppControl.</param>
+ /// <param name="replyAfterLaunching">The callback function to be called when the reply is delivered.</param>
+ /// <returns>A task with the result of the launch request.</returns>
+ /// <exception cref="ArgumentException">Thrown when failed because of the argument is invalid.</exception>
+ /// <exception cref="Exceptions.AppNotFoundException">Thrown when the application to run is not found.</exception>
+ /// <exception cref="Exceptions.LaunchRejectedException">Thrown when the launch request is rejected.</exception>
+ /// <privilege>http://tizen.org/privilege/appmanager.launch</privilege>
+ /// <since_tizen> 6 </since_tizen>
+ public static Task<AppControlResult> SendLaunchRequestAsync(AppControl launchRequest, AppControlReplyCallback replyAfterLaunching)
+ {
+ if (launchRequest == null)
+ {
+ throw new ArgumentNullException(nameof(launchRequest));
+ }
+
+ var task = new TaskCompletionSource<AppControlResult>();
+ Interop.AppControl.ErrorCode err;
+ int requestId = 0;
+
+ lock (s_resultNativeCallbackMaps)
+ {
+ requestId = s_reaustId++;
+ s_resultNativeCallbackMaps[requestId] = (handle, result, userData) =>
+ {
+ task.SetResult((AppControlResult)result);
+ lock (s_resultNativeCallbackMaps)
+ {
+ s_resultNativeCallbackMaps.Remove((int)userData);
+ }
+ };
+ }
+
+ if (replyAfterLaunching != null)
+ {
+ lock (s_replyCallbackMaps)
+ {
+ s_replyCallbackMaps[requestId] = replyAfterLaunching;
+ }
+ err = Interop.AppControl.SendLaunchRequestAsync(launchRequest.SafeAppControlHandle, s_resultNativeCallbackMaps[requestId], s_replyNativeCallback, (IntPtr)requestId);
+ }
+ else
+ {
+ err = Interop.AppControl.SendLaunchRequestAsync(launchRequest.SafeAppControlHandle, s_resultNativeCallbackMaps[requestId], null, (IntPtr)requestId);
+ }
+
+ if (err != Interop.AppControl.ErrorCode.None)
+ {
+ switch (err)
+ {
+ case Interop.AppControl.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid Arguments");
+ case Interop.AppControl.ErrorCode.AppNotFound:
+ throw new Exceptions.AppNotFoundException("App not found");
+ case Interop.AppControl.ErrorCode.LaunchRejected:
+ throw new Exceptions.LaunchRejectedException("Launch rejected");
+ case Interop.AppControl.ErrorCode.PermissionDenied:
+ throw new Exceptions.PermissionDeniedException("Permission denied");
+
+ default:
+ throw new Exceptions.LaunchRejectedException("Launch rejected");
+ }
+ }
+
+ return task.Task;
+ }
+
+ /// <summary>
/// Class for extra data.
/// </summary>
/// <since_tizen> 3 </since_tizen>
--- /dev/null
+/*
+ * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Enumeration for the application control result.
+ /// </summary>
+ /// <since_tizen> 6 </since_tizen>
+ public enum AppControlResult
+ {
+ /// <summary>
+ /// Successful.
+ /// </summary>
+ None = Interop.AppControl.ErrorCode.None,
+
+ /// <summary>
+ /// Invalid parameter.
+ /// </summary>
+ InvalidParameter = Interop.AppControl.ErrorCode.InvalidParameter,
+
+ /// <summary>
+ /// The application to run the given launch request is not found.
+ /// </summary>
+ AppNotFound = Interop.AppControl.ErrorCode.AppNotFound,
+
+ /// <summary>
+ /// The application cannot be launched in current context.
+ /// </summary>
+ LaunchRejected = Interop.AppControl.ErrorCode.LaunchRejected,
+
+ /// <summary>
+ /// Permission denied.
+ /// </summary>
+ PermissionDenied = Interop.AppControl.ErrorCode.PermissionDenied,
+ }
+}