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 System.ComponentModel;
20 using System.Runtime.InteropServices;
21 using System.Threading.Tasks;
23 namespace Tizen.Applications
26 /// This class has the methods and events of the ApplicationManager.
28 public static class ApplicationManager
30 private const string LogTag = "Tizen.Applications";
31 private static EventHandler<ApplicationLaunchedEventArgs> s_launchedHandler;
32 private static EventHandler<ApplicationTerminatedEventArgs> s_terminatedHandler;
33 private static Interop.ApplicationManager.AppManagerAppContextEventCallback s_applicationChangedEventCallback;
34 private static EventHandler<ApplicationEnabledEventArgs> _enabledHandler;
35 private static EventHandler<ApplicationDisabledEventArgs> _disabledHandler;
36 private static Interop.ApplicationManager.AppManagerEventCallback _eventCallback;
37 private static IntPtr _eventHandle = IntPtr.Zero;
40 /// Occurs whenever the installed application is enabled.
42 public static event EventHandler<ApplicationEnabledEventArgs> ApplicationEnabled
46 if (_enabledHandler == null && _disabledHandler == null)
48 RegisterApplicationEvent();
50 _enabledHandler += value;
54 _enabledHandler -= value;
55 if (_enabledHandler == null && _disabledHandler == null)
57 UnRegisterApplicationEvent();
63 /// Occurs whenever the installed application is disabled.
65 public static event EventHandler<ApplicationDisabledEventArgs> ApplicationDisabled
69 if (_disabledHandler == null && _enabledHandler == null)
71 RegisterApplicationEvent();
73 _disabledHandler += value;
77 _disabledHandler -= value;
78 if (_disabledHandler == null && _enabledHandler == null)
80 UnRegisterApplicationEvent();
86 /// Occurs whenever the installed applications get launched.
88 public static event EventHandler<ApplicationLaunchedEventArgs> ApplicationLaunched
92 if (s_launchedHandler == null && s_terminatedHandler == null)
94 RegisterApplicationChangedEvent();
96 s_launchedHandler += value;
100 s_launchedHandler -= value;
101 if (s_launchedHandler == null && s_terminatedHandler == null)
103 UnRegisterApplicationChangedEvent();
109 /// Occurs whenever the installed applications get terminated.
111 public static event EventHandler<ApplicationTerminatedEventArgs> ApplicationTerminated
115 if (s_launchedHandler == null && s_terminatedHandler == null)
117 RegisterApplicationChangedEvent();
119 s_terminatedHandler += value;
123 s_terminatedHandler -= value;
124 if (s_launchedHandler == null && s_terminatedHandler == null)
126 UnRegisterApplicationChangedEvent();
132 /// Gets the information of the installed applications asynchronously.
134 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync()
136 return await Task.Run(() =>
138 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
139 List<ApplicationInfo> result = new List<ApplicationInfo>();
141 Interop.ApplicationManager.AppManagerAppInfoCallback cb = (IntPtr infoHandle, IntPtr userData) =>
143 if (infoHandle != IntPtr.Zero)
145 IntPtr clonedHandle = IntPtr.Zero;
146 err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
147 if (err != Interop.ApplicationManager.ErrorCode.None)
149 Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
152 ApplicationInfo app = new ApplicationInfo(clonedHandle);
158 err = Interop.ApplicationManager.AppManagerForeachAppInfo(cb, IntPtr.Zero);
159 if (err != Interop.ApplicationManager.ErrorCode.None)
161 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach the appinfo.");
168 /// Gets the information of the installed applications with the ApplicationInfoFilter asynchronously.
170 /// <param name="filter">Key-value pairs for filtering.</param>
171 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync(ApplicationInfoFilter filter)
173 return await Task.Run(() =>
175 List<ApplicationInfo> result = new List<ApplicationInfo>();
177 Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr infoHandle, IntPtr userData) =>
179 if (infoHandle != IntPtr.Zero)
181 IntPtr clonedHandle = IntPtr.Zero;
182 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
183 if (err != Interop.ApplicationManager.ErrorCode.None)
185 Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
188 ApplicationInfo app = new ApplicationInfo(clonedHandle);
200 /// Gets the information of the installed applications with the ApplicationInfoMetadataFilter asynchronously.
202 /// <param name="filter">Key-value pairs for filtering.</param>
203 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync(ApplicationInfoMetadataFilter filter)
205 return await Task.Run(() =>
207 List<ApplicationInfo> result = new List<ApplicationInfo>();
209 Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr infoHandle, IntPtr userData) =>
211 if (infoHandle != IntPtr.Zero)
213 IntPtr clonedHandle = IntPtr.Zero;
214 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
215 if (err != Interop.ApplicationManager.ErrorCode.None)
217 Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
220 ApplicationInfo app = new ApplicationInfo(clonedHandle);
232 /// Gets the information of the running applications asynchronously.
234 public static async Task<IEnumerable<ApplicationRunningContext>> GetRunningApplicationsAsync()
236 return await Task.Run(() =>
238 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
239 List<ApplicationRunningContext> result = new List<ApplicationRunningContext>();
241 Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr contextHandle, IntPtr userData) =>
243 if (contextHandle != IntPtr.Zero)
245 IntPtr clonedHandle = IntPtr.Zero;
246 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
247 if (err != Interop.ApplicationManager.ErrorCode.None)
249 Log.Warn(LogTag, "Failed to clone the app context. err = " + err);
252 ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle);
259 err = Interop.ApplicationManager.AppManagerForeachAppContext(cb, IntPtr.Zero);
260 if (err != Interop.ApplicationManager.ErrorCode.None)
262 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach appcontext.");
269 /// Gets the information of the running applications including subapp asynchronously.
271 public static async Task<IEnumerable<ApplicationRunningContext>> GetAllRunningApplicationsAsync()
273 return await Task.Run(() =>
275 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
276 List<ApplicationRunningContext> result = new List<ApplicationRunningContext>();
278 Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr contextHandle, IntPtr userData) =>
280 if (contextHandle != IntPtr.Zero)
282 IntPtr clonedHandle = IntPtr.Zero;
283 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
284 if (err != Interop.ApplicationManager.ErrorCode.None)
286 Log.Warn(LogTag, "Failed to clone the app context. err = " + err);
289 ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle);
296 err = Interop.ApplicationManager.AppManagerForeachRunningAppContext(cb, IntPtr.Zero);
297 if (err != Interop.ApplicationManager.ErrorCode.None)
299 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach appcontext.");
306 /// Gets the information of the specified application with the application id.
308 /// <param name="applicationId">Application id.</param>
309 public static ApplicationInfo GetInstalledApplication(string applicationId)
311 IntPtr infoHandle = IntPtr.Zero;
312 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppManagerGetAppInfo(applicationId, out infoHandle);
313 if (err != Interop.ApplicationManager.ErrorCode.None)
315 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get the installed application information of " + applicationId + ".");
317 ApplicationInfo app = new ApplicationInfo(infoHandle);
322 /// Returns if the specified application is running or not.
324 /// <param name="applicationId">The application Id.</param>
325 /// <returns>Returns true if the given application is running, otherwise false.</returns>
326 /// <exception cref="ArgumentException">Thrown when the given parameter is invalid.</exception>
327 public static bool IsRunning(string applicationId)
329 bool isRunning = false;
330 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppManagerIsRunning(applicationId, out isRunning);
331 if (err != Interop.ApplicationManager.ErrorCode.None)
333 throw ApplicationManagerErrorFactory.GetException(Interop.ApplicationManager.ErrorCode.InvalidParameter, "Invalid parameter");
338 private static void RegisterApplicationChangedEvent()
340 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
341 s_applicationChangedEventCallback = (IntPtr contextHandle, Interop.ApplicationManager.AppContextEvent state, IntPtr userData) =>
343 if (contextHandle == IntPtr.Zero) return;
345 IntPtr clonedHandle = IntPtr.Zero;
346 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
347 if (err != Interop.ApplicationManager.ErrorCode.None)
349 throw ApplicationManagerErrorFactory.GetException(err, "Failed to register the application context event.");
351 using (ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle))
353 if (state == Interop.ApplicationManager.AppContextEvent.Launched)
355 s_launchedHandler?.Invoke(null, new ApplicationLaunchedEventArgs { ApplicationRunningContext = context });
357 else if (state == Interop.ApplicationManager.AppContextEvent.Terminated)
359 s_terminatedHandler?.Invoke(null, new ApplicationTerminatedEventArgs { ApplicationRunningContext = context });
363 err = Interop.ApplicationManager.AppManagerSetAppContextEvent(s_applicationChangedEventCallback, IntPtr.Zero);
364 if (err != Interop.ApplicationManager.ErrorCode.None)
366 throw ApplicationManagerErrorFactory.GetException(err, "Failed to register the application context event.");
370 private static void UnRegisterApplicationChangedEvent()
372 Interop.ApplicationManager.AppManagerUnSetAppContextEvent();
375 private static void RegisterApplicationEvent()
377 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
378 err = Interop.ApplicationManager.AppManagerEventCreate(out _eventHandle);
379 if (err != Interop.ApplicationManager.ErrorCode.None)
381 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the application event handle");
384 err = Interop.ApplicationManager.AppManagerEventSetStatus(_eventHandle, Interop.ApplicationManager.AppManagerEventStatusType.All);
385 if (err != Interop.ApplicationManager.ErrorCode.None)
387 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
388 _eventHandle = IntPtr.Zero;
389 throw ApplicationManagerErrorFactory.GetException(err, "Failed to set the application event");
392 _eventCallback = (string appType, string appId, Interop.ApplicationManager.AppManagerEventType eventType, Interop.ApplicationManager.AppManagerEventState eventState, IntPtr eventHandle, IntPtr UserData) =>
394 if (eventType == Interop.ApplicationManager.AppManagerEventType.Enable)
396 _enabledHandler?.Invoke(null, new ApplicationEnabledEventArgs(appId, (ApplicationEventState)eventState));
398 else if (eventType == Interop.ApplicationManager.AppManagerEventType.Disable)
400 _disabledHandler?.Invoke(null, new ApplicationDisabledEventArgs(appId, (ApplicationEventState)eventState));
403 err = Interop.ApplicationManager.AppManagerSetEventCallback(_eventHandle, _eventCallback, IntPtr.Zero);
404 if (err != Interop.ApplicationManager.ErrorCode.None)
406 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
407 _eventHandle = IntPtr.Zero;
408 throw ApplicationManagerErrorFactory.GetException(err, "Failed to set the application event callback");
412 private static void UnRegisterApplicationEvent()
414 if (_eventHandle != IntPtr.Zero)
416 Interop.ApplicationManager.AppManagerUnSetEventCallback(_eventHandle);
417 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
418 _eventHandle = IntPtr.Zero;
423 /// Gets the information of the recent applications.
425 /// <returns>Returns a dictionary containing all recent application info.</returns>
426 /// <exception cref="InvalidOperationException">Thrown when failed because of invalid operation</exception>
427 [EditorBrowsable(EditorBrowsableState.Never)]
428 public static IEnumerable<RecentApplicationInfo> GetRecentApplications()
430 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
432 List<RecentApplicationInfo> result = new List<RecentApplicationInfo>();
436 err = Interop.ApplicationManager.RuaHistoryLoadDb(out table, out nrows, out ncols);
437 if (err != Interop.ApplicationManager.ErrorCode.None)
439 throw ApplicationManagerErrorFactory.GetException(err, "Failed to load a table for the recent application list.");
442 for (int row = 0; row < nrows; ++row)
444 Interop.ApplicationManager.RuaRec record;
446 err = Interop.ApplicationManager.RuaHistoryGetRecord(out record, table, nrows, ncols, row);
447 if (err != Interop.ApplicationManager.ErrorCode.None)
449 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get record.");
452 RecentApplicationInfo info = new RecentApplicationInfo(record);
456 err = Interop.ApplicationManager.RuaHistoryUnLoadDb(ref table);
457 if (err != Interop.ApplicationManager.ErrorCode.None)
459 throw ApplicationManagerErrorFactory.GetException(err, "Failed to unload a table for the recent application list.");
466 internal static class FilterExtension
468 private const string LogTag = "Tizen.Applications";
469 internal static void Fetch(this ApplicationInfoFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
471 if (filter is ApplicationInfoMetadataFilter)
473 ApplicationInfoMetadataFilter metaFilter = (ApplicationInfoMetadataFilter)filter;
474 metaFilter.Fetch(callback);
478 IntPtr nativeHandle = MakeNativeAppInfoFilter(filter.Filter);
479 if (nativeHandle == IntPtr.Zero)
481 throw ApplicationManagerErrorFactory.NativeFilterHandleIsInvalid();
485 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoFilterForeachAppinfo(nativeHandle, callback, IntPtr.Zero);
486 if (err != Interop.ApplicationManager.ErrorCode.None)
488 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get application information list with filter.");
493 Interop.ApplicationManager.AppInfoFilterDestroy(nativeHandle);
497 internal static void Fetch(this ApplicationInfoMetadataFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
499 IntPtr nativeHandle = MakeNativeAppMetadataFilter(filter.Filter);
500 if (nativeHandle == IntPtr.Zero)
502 throw ApplicationManagerErrorFactory.NativeFilterHandleIsInvalid();
506 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoMetadataFilterForeach(nativeHandle, callback, IntPtr.Zero);
507 if (err != Interop.ApplicationManager.ErrorCode.None)
509 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get metadata list with filter.");
514 Interop.ApplicationManager.AppInfoMetadataFilterDestroy(nativeHandle);
518 private static IntPtr MakeNativeAppInfoFilter(IDictionary<string, string> filter)
520 if (filter == null || filter.Count == 0)
522 throw ApplicationManagerErrorFactory.FilterIsInvalid();
525 IntPtr infoHandle = IntPtr.Zero;
526 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoFilterCreate(out infoHandle);
527 if (err != Interop.ApplicationManager.ErrorCode.None)
529 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the filter handle.");
532 foreach (var item in filter)
534 if ((item.Key == ApplicationInfoFilter.Keys.Id) ||
535 (item.Key == ApplicationInfoFilter.Keys.Type) ||
536 (item.Key == ApplicationInfoFilter.Keys.Category))
538 err = Interop.ApplicationManager.AppInfoFilterAddString(infoHandle, item.Key, item.Value);
540 else if ((item.Key == ApplicationInfoFilter.Keys.NoDisplay) ||
541 (item.Key == ApplicationInfoFilter.Keys.TaskManage))
543 err = Interop.ApplicationManager.AppInfoFilterAddBool(infoHandle, item.Key, Convert.ToBoolean(item.Value));
547 Log.Warn(LogTag, string.Format("'{0}' is not supported key for the filter.", item.Key));
549 if (err != Interop.ApplicationManager.ErrorCode.None)
551 Interop.ApplicationManager.AppInfoFilterDestroy(infoHandle);
552 throw ApplicationManagerErrorFactory.GetException(err, "Failed to add item to the filter.");
558 private static IntPtr MakeNativeAppMetadataFilter(IDictionary<string, string> filter)
560 if (filter == null || filter.Count == 0)
562 throw ApplicationManagerErrorFactory.FilterIsInvalid();
565 IntPtr infoHandle = IntPtr.Zero;
566 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoMetadataFilterCreate(out infoHandle);
567 if (err != Interop.ApplicationManager.ErrorCode.None)
569 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the filter for searching with metadata.");
571 foreach (var item in filter)
573 err = Interop.ApplicationManager.AppInfoMetadataFilterAdd(infoHandle, item.Key, item.Value);
574 if (err != Interop.ApplicationManager.ErrorCode.None)
576 Interop.ApplicationManager.AppInfoMetadataFilterDestroy(infoHandle);
577 throw ApplicationManagerErrorFactory.GetException(err, "Failed to add the item to the filter.");
584 internal static class ApplicationManagerErrorFactory
586 internal static Exception NativeFilterHandleIsInvalid()
588 return new InvalidOperationException("The native handle for filtering is invalid.");
591 internal static Exception FilterIsInvalid()
593 return new ArgumentException("The filter is invalid.");
596 internal static Exception GetException(Interop.ApplicationManager.ErrorCode err, string message)
598 string errMessage = String.Format("{0} err = {1}", message, err);
601 case Interop.ApplicationManager.ErrorCode.InvalidParameter:
602 return new ArgumentException(errMessage);
604 return new InvalidOperationException(errMessage);