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 /// <since_tizen> 3 </since_tizen>
29 public static class ApplicationManager
31 private const string LogTag = "Tizen.Applications";
32 private static EventHandler<ApplicationLaunchedEventArgs> s_launchedHandler;
33 private static EventHandler<ApplicationTerminatedEventArgs> s_terminatedHandler;
34 private static Interop.ApplicationManager.AppManagerAppContextEventCallback s_applicationChangedEventCallback;
35 private static EventHandler<ApplicationEnabledEventArgs> s_enabledHandler;
36 private static EventHandler<ApplicationDisabledEventArgs> s_disabledHandler;
37 private static Interop.ApplicationManager.AppManagerEventCallback s_eventCallback;
38 private static IntPtr _eventHandle = IntPtr.Zero;
39 private static readonly object s_eventLock = new object();
40 private static readonly object s_applicationChangedEventLock = new object();
43 /// Occurs whenever the installed application is enabled.
45 /// <since_tizen> 3 </since_tizen>
46 public static event EventHandler<ApplicationEnabledEventArgs> ApplicationEnabled
52 if (s_eventCallback == null)
54 RegisterApplicationEvent();
56 s_enabledHandler += value;
63 s_enabledHandler -= value;
64 if (s_enabledHandler == null && s_disabledHandler == null && s_eventCallback != null)
66 UnRegisterApplicationEvent();
67 s_eventCallback = null;
74 /// Occurs whenever the installed application is disabled.
76 /// <since_tizen> 3 </since_tizen>
77 public static event EventHandler<ApplicationDisabledEventArgs> ApplicationDisabled
83 if (s_eventCallback == null)
85 RegisterApplicationEvent();
87 s_disabledHandler += value;
94 s_disabledHandler -= value;
95 if (s_enabledHandler == null && s_disabledHandler == null && s_eventCallback != null)
97 UnRegisterApplicationEvent();
98 s_eventCallback = null;
105 /// Occurs whenever the installed applications get launched.
107 /// <since_tizen> 3 </since_tizen>
108 public static event EventHandler<ApplicationLaunchedEventArgs> ApplicationLaunched
112 lock (s_applicationChangedEventLock)
114 if (s_applicationChangedEventCallback == null)
116 RegisterApplicationChangedEvent();
118 s_launchedHandler += value;
123 lock (s_applicationChangedEventLock)
125 s_launchedHandler -= value;
126 if (s_launchedHandler == null && s_terminatedHandler == null && s_applicationChangedEventCallback != null)
128 UnRegisterApplicationChangedEvent();
129 s_applicationChangedEventCallback = null;
136 /// Occurs whenever the installed applications get terminated.
138 /// <since_tizen> 3 </since_tizen>
139 public static event EventHandler<ApplicationTerminatedEventArgs> ApplicationTerminated
143 lock (s_applicationChangedEventLock)
145 if (s_applicationChangedEventCallback == null)
147 RegisterApplicationChangedEvent();
149 s_terminatedHandler += value;
154 lock (s_applicationChangedEventLock)
156 s_terminatedHandler -= value;
157 if (s_launchedHandler == null && s_terminatedHandler == null && s_applicationChangedEventCallback != null)
159 UnRegisterApplicationChangedEvent();
160 s_applicationChangedEventCallback = null;
167 /// Gets the information of the installed applications asynchronously.
169 /// <since_tizen> 3 </since_tizen>
170 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync()
172 return await Task.Run(() =>
174 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
175 List<ApplicationInfo> result = new List<ApplicationInfo>();
177 Interop.ApplicationManager.AppManagerAppInfoCallback cb = (IntPtr infoHandle, IntPtr userData) =>
179 if (infoHandle != IntPtr.Zero)
181 IntPtr clonedHandle = IntPtr.Zero;
182 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);
194 err = Interop.ApplicationManager.AppManagerForeachAppInfo(cb, IntPtr.Zero);
195 if (err != Interop.ApplicationManager.ErrorCode.None)
197 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach the appinfo.");
204 /// Gets the information of the installed applications with the ApplicationInfoFilter asynchronously.
206 /// <param name="filter">Key-value pairs for filtering.</param>
207 /// <since_tizen> 3 </since_tizen>
208 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync(ApplicationInfoFilter filter)
210 return await Task.Run(() =>
212 List<ApplicationInfo> result = new List<ApplicationInfo>();
214 Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr infoHandle, IntPtr userData) =>
216 if (infoHandle != IntPtr.Zero)
218 IntPtr clonedHandle = IntPtr.Zero;
219 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
220 if (err != Interop.ApplicationManager.ErrorCode.None)
222 Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
225 ApplicationInfo app = new ApplicationInfo(clonedHandle);
237 /// Gets the information of the installed applications with the ApplicationInfoMetadataFilter asynchronously.
239 /// <param name="filter">Key-value pairs for filtering.</param>
240 /// <since_tizen> 3 </since_tizen>
241 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync(ApplicationInfoMetadataFilter filter)
243 return await Task.Run(() =>
245 List<ApplicationInfo> result = new List<ApplicationInfo>();
247 Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr infoHandle, IntPtr userData) =>
249 if (infoHandle != IntPtr.Zero)
251 IntPtr clonedHandle = IntPtr.Zero;
252 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
253 if (err != Interop.ApplicationManager.ErrorCode.None)
255 Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
258 ApplicationInfo app = new ApplicationInfo(clonedHandle);
270 /// Gets the information of the running applications asynchronously.
272 /// <since_tizen> 3 </since_tizen>
273 public static async Task<IEnumerable<ApplicationRunningContext>> GetRunningApplicationsAsync()
275 return await Task.Run(() =>
277 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
278 List<ApplicationRunningContext> result = new List<ApplicationRunningContext>();
280 Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr contextHandle, IntPtr userData) =>
282 if (contextHandle != IntPtr.Zero)
284 IntPtr clonedHandle = IntPtr.Zero;
285 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
286 if (err != Interop.ApplicationManager.ErrorCode.None)
288 Log.Warn(LogTag, "Failed to clone the app context. err = " + err);
291 ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle);
298 err = Interop.ApplicationManager.AppManagerForeachAppContext(cb, IntPtr.Zero);
299 if (err != Interop.ApplicationManager.ErrorCode.None)
301 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach appcontext.");
308 /// Gets the information of the running applications including subapp asynchronously.
310 /// <since_tizen> 3 </since_tizen>
311 public static async Task<IEnumerable<ApplicationRunningContext>> GetAllRunningApplicationsAsync()
313 return await Task.Run(() =>
315 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
316 List<ApplicationRunningContext> result = new List<ApplicationRunningContext>();
318 Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr contextHandle, IntPtr userData) =>
320 if (contextHandle != IntPtr.Zero)
322 IntPtr clonedHandle = IntPtr.Zero;
323 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
324 if (err != Interop.ApplicationManager.ErrorCode.None)
326 Log.Warn(LogTag, "Failed to clone the app context. err = " + err);
329 ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle);
336 err = Interop.ApplicationManager.AppManagerForeachRunningAppContext(cb, IntPtr.Zero);
337 if (err != Interop.ApplicationManager.ErrorCode.None)
339 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach appcontext.");
346 /// Gets the information of the specified application with the application ID.
348 /// <param name="applicationId">Application ID.</param>
349 /// <since_tizen> 3 </since_tizen>
350 public static ApplicationInfo GetInstalledApplication(string applicationId)
352 IntPtr infoHandle = IntPtr.Zero;
353 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppManagerGetAppInfo(applicationId, out infoHandle);
354 if (err != Interop.ApplicationManager.ErrorCode.None)
356 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get the installed application information of " + applicationId + ".");
358 ApplicationInfo app = new ApplicationInfo(infoHandle);
363 /// Returns if the specified application is running or not.
365 /// <param name="applicationId">The application ID.</param>
366 /// <returns>Returns true if the given application is running, otherwise false.</returns>
367 /// <exception cref="ArgumentException">Thrown when the given parameter is invalid.</exception>
368 /// <since_tizen> 3 </since_tizen>
369 public static bool IsRunning(string applicationId)
371 bool isRunning = false;
372 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppManagerIsRunning(applicationId, out isRunning);
373 if (err != Interop.ApplicationManager.ErrorCode.None)
375 throw ApplicationManagerErrorFactory.GetException(Interop.ApplicationManager.ErrorCode.InvalidParameter, "Invalid parameter");
380 private static void RegisterApplicationChangedEvent()
382 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
383 s_applicationChangedEventCallback = (IntPtr contextHandle, Interop.ApplicationManager.AppContextEvent state, IntPtr userData) =>
385 if (contextHandle == IntPtr.Zero) return;
387 IntPtr clonedHandle = IntPtr.Zero;
388 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
389 if (err != Interop.ApplicationManager.ErrorCode.None)
391 throw ApplicationManagerErrorFactory.GetException(err, "Failed to register the application context event.");
393 using (ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle))
395 if (state == Interop.ApplicationManager.AppContextEvent.Launched)
397 s_launchedHandler?.Invoke(null, new ApplicationLaunchedEventArgs { ApplicationRunningContext = context });
399 else if (state == Interop.ApplicationManager.AppContextEvent.Terminated)
401 s_terminatedHandler?.Invoke(null, new ApplicationTerminatedEventArgs { ApplicationRunningContext = context });
405 err = Interop.ApplicationManager.AppManagerSetAppContextEvent(s_applicationChangedEventCallback, IntPtr.Zero);
406 if (err != Interop.ApplicationManager.ErrorCode.None)
408 throw ApplicationManagerErrorFactory.GetException(err, "Failed to register the application context event.");
412 private static void UnRegisterApplicationChangedEvent()
414 Interop.ApplicationManager.AppManagerUnSetAppContextEvent();
417 private static void RegisterApplicationEvent()
419 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
420 err = Interop.ApplicationManager.AppManagerEventCreate(out _eventHandle);
421 if (err != Interop.ApplicationManager.ErrorCode.None)
423 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the application event handle");
426 err = Interop.ApplicationManager.AppManagerEventSetStatus(_eventHandle, Interop.ApplicationManager.AppManagerEventStatusType.All);
427 if (err != Interop.ApplicationManager.ErrorCode.None)
429 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
430 _eventHandle = IntPtr.Zero;
431 throw ApplicationManagerErrorFactory.GetException(err, "Failed to set the application event");
434 s_eventCallback = (string appType, string appId, Interop.ApplicationManager.AppManagerEventType eventType, Interop.ApplicationManager.AppManagerEventState eventState, IntPtr eventHandle, IntPtr UserData) =>
436 if (eventType == Interop.ApplicationManager.AppManagerEventType.Enable)
438 s_enabledHandler?.Invoke(null, new ApplicationEnabledEventArgs(appId, (ApplicationEventState)eventState));
440 else if (eventType == Interop.ApplicationManager.AppManagerEventType.Disable)
442 s_disabledHandler?.Invoke(null, new ApplicationDisabledEventArgs(appId, (ApplicationEventState)eventState));
445 err = Interop.ApplicationManager.AppManagerSetEventCallback(_eventHandle, s_eventCallback, IntPtr.Zero);
446 if (err != Interop.ApplicationManager.ErrorCode.None)
448 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
449 _eventHandle = IntPtr.Zero;
450 throw ApplicationManagerErrorFactory.GetException(err, "Failed to set the application event callback");
454 private static void UnRegisterApplicationEvent()
456 if (_eventHandle != IntPtr.Zero)
458 Interop.ApplicationManager.AppManagerUnSetEventCallback(_eventHandle);
459 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
460 _eventHandle = IntPtr.Zero;
465 /// Gets the information of the recent applications.
467 /// <returns>Returns a dictionary containing all the recent application info.</returns>
468 /// <exception cref="InvalidOperationException">Thrown when failed because of an invalid operation.</exception>
469 /// <since_tizen> 3 </since_tizen>
470 [EditorBrowsable(EditorBrowsableState.Never)]
471 public static IEnumerable<RecentApplicationInfo> GetRecentApplications()
473 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
475 List<RecentApplicationInfo> result = new List<RecentApplicationInfo>();
479 err = Interop.ApplicationManager.RuaHistoryLoadDb(out table, out nrows, out ncols);
480 if (err != Interop.ApplicationManager.ErrorCode.None)
482 throw ApplicationManagerErrorFactory.GetException(err, "Failed to load a table for the recent application list.");
485 for (int row = 0; row < nrows; ++row)
487 Interop.ApplicationManager.RuaRec record;
489 err = Interop.ApplicationManager.RuaHistoryGetRecord(out record, table, nrows, ncols, row);
490 if (err != Interop.ApplicationManager.ErrorCode.None)
492 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get record.");
495 RecentApplicationInfo info = new RecentApplicationInfo(record);
499 err = Interop.ApplicationManager.RuaHistoryUnLoadDb(ref table);
500 if (err != Interop.ApplicationManager.ErrorCode.None)
502 throw ApplicationManagerErrorFactory.GetException(err, "Failed to unload a table for the recent application list.");
509 internal static class FilterExtension
511 private const string LogTag = "Tizen.Applications";
512 internal static void Fetch(this ApplicationInfoFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
514 if (filter is ApplicationInfoMetadataFilter)
516 ApplicationInfoMetadataFilter metaFilter = (ApplicationInfoMetadataFilter)filter;
517 metaFilter.Fetch(callback);
521 IntPtr nativeHandle = MakeNativeAppInfoFilter(filter.Filter);
522 if (nativeHandle == IntPtr.Zero)
524 throw ApplicationManagerErrorFactory.NativeFilterHandleIsInvalid();
528 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoFilterForeachAppinfo(nativeHandle, callback, IntPtr.Zero);
529 if (err != Interop.ApplicationManager.ErrorCode.None)
531 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get application information list with filter.");
536 Interop.ApplicationManager.AppInfoFilterDestroy(nativeHandle);
540 internal static void Fetch(this ApplicationInfoMetadataFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
542 IntPtr nativeHandle = MakeNativeAppMetadataFilter(filter.Filter);
543 if (nativeHandle == IntPtr.Zero)
545 throw ApplicationManagerErrorFactory.NativeFilterHandleIsInvalid();
549 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoMetadataFilterForeach(nativeHandle, callback, IntPtr.Zero);
550 if (err != Interop.ApplicationManager.ErrorCode.None)
552 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get metadata list with filter.");
557 Interop.ApplicationManager.AppInfoMetadataFilterDestroy(nativeHandle);
561 private static IntPtr MakeNativeAppInfoFilter(IDictionary<string, string> filter)
563 if (filter == null || filter.Count == 0)
565 throw ApplicationManagerErrorFactory.FilterIsInvalid();
568 IntPtr infoHandle = IntPtr.Zero;
569 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoFilterCreate(out infoHandle);
570 if (err != Interop.ApplicationManager.ErrorCode.None)
572 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the filter handle.");
575 foreach (var item in filter)
577 if ((item.Key == ApplicationInfoFilter.Keys.Id) ||
578 (item.Key == ApplicationInfoFilter.Keys.Type) ||
579 (item.Key == ApplicationInfoFilter.Keys.Category) ||
580 (item.Key == ApplicationInfoFilter.Keys.InstalledStorage))
582 err = Interop.ApplicationManager.AppInfoFilterAddString(infoHandle, item.Key, item.Value);
584 else if ((item.Key == ApplicationInfoFilter.Keys.NoDisplay) ||
585 (item.Key == ApplicationInfoFilter.Keys.TaskManage))
587 err = Interop.ApplicationManager.AppInfoFilterAddBool(infoHandle, item.Key, Convert.ToBoolean(item.Value));
591 Log.Warn(LogTag, string.Format("'{0}' is not supported key for the filter.", item.Key));
593 if (err != Interop.ApplicationManager.ErrorCode.None)
595 Interop.ApplicationManager.AppInfoFilterDestroy(infoHandle);
596 throw ApplicationManagerErrorFactory.GetException(err, "Failed to add item to the filter.");
602 private static IntPtr MakeNativeAppMetadataFilter(IDictionary<string, string> filter)
604 if (filter == null || filter.Count == 0)
606 throw ApplicationManagerErrorFactory.FilterIsInvalid();
609 IntPtr infoHandle = IntPtr.Zero;
610 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoMetadataFilterCreate(out infoHandle);
611 if (err != Interop.ApplicationManager.ErrorCode.None)
613 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the filter for searching with metadata.");
615 foreach (var item in filter)
617 err = Interop.ApplicationManager.AppInfoMetadataFilterAdd(infoHandle, item.Key, item.Value);
618 if (err != Interop.ApplicationManager.ErrorCode.None)
620 Interop.ApplicationManager.AppInfoMetadataFilterDestroy(infoHandle);
621 throw ApplicationManagerErrorFactory.GetException(err, "Failed to add the item to the filter.");
628 internal static class ApplicationManagerErrorFactory
630 internal static Exception NativeFilterHandleIsInvalid()
632 return new InvalidOperationException("The native handle for filtering is invalid.");
635 internal static Exception FilterIsInvalid()
637 return new ArgumentException("The filter is invalid.");
640 internal static Exception GetException(Interop.ApplicationManager.ErrorCode err, string message)
642 string errMessage = String.Format("{0} err = {1}", message, err);
645 case Interop.ApplicationManager.ErrorCode.InvalidParameter:
646 return new ArgumentException(errMessage);
648 return new InvalidOperationException(errMessage);