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> _enabledHandler;
36 private static EventHandler<ApplicationDisabledEventArgs> _disabledHandler;
37 private static Interop.ApplicationManager.AppManagerEventCallback _eventCallback;
38 private static IntPtr _eventHandle = IntPtr.Zero;
41 /// Occurs whenever the installed application is enabled.
43 /// <since_tizen> 3 </since_tizen>
44 public static event EventHandler<ApplicationEnabledEventArgs> ApplicationEnabled
48 if (_enabledHandler == null && _disabledHandler == null)
50 RegisterApplicationEvent();
52 _enabledHandler += value;
56 _enabledHandler -= value;
57 if (_enabledHandler == null && _disabledHandler == null)
59 UnRegisterApplicationEvent();
65 /// Occurs whenever the installed application is disabled.
67 /// <since_tizen> 3 </since_tizen>
68 public static event EventHandler<ApplicationDisabledEventArgs> ApplicationDisabled
72 if (_disabledHandler == null && _enabledHandler == null)
74 RegisterApplicationEvent();
76 _disabledHandler += value;
80 _disabledHandler -= value;
81 if (_disabledHandler == null && _enabledHandler == null)
83 UnRegisterApplicationEvent();
89 /// Occurs whenever the installed applications get launched.
91 /// <since_tizen> 3 </since_tizen>
92 public static event EventHandler<ApplicationLaunchedEventArgs> ApplicationLaunched
96 if (s_launchedHandler == null && s_terminatedHandler == null)
98 RegisterApplicationChangedEvent();
100 s_launchedHandler += value;
104 s_launchedHandler -= value;
105 if (s_launchedHandler == null && s_terminatedHandler == null)
107 UnRegisterApplicationChangedEvent();
113 /// Occurs whenever the installed applications get terminated.
115 /// <since_tizen> 3 </since_tizen>
116 public static event EventHandler<ApplicationTerminatedEventArgs> ApplicationTerminated
120 if (s_launchedHandler == null && s_terminatedHandler == null)
122 RegisterApplicationChangedEvent();
124 s_terminatedHandler += value;
128 s_terminatedHandler -= value;
129 if (s_launchedHandler == null && s_terminatedHandler == null)
131 UnRegisterApplicationChangedEvent();
137 /// Gets the information of the installed applications asynchronously.
139 /// <since_tizen> 3 </since_tizen>
140 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync()
142 return await Task.Run(() =>
144 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
145 List<ApplicationInfo> result = new List<ApplicationInfo>();
147 Interop.ApplicationManager.AppManagerAppInfoCallback cb = (IntPtr infoHandle, IntPtr userData) =>
149 if (infoHandle != IntPtr.Zero)
151 IntPtr clonedHandle = IntPtr.Zero;
152 err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
153 if (err != Interop.ApplicationManager.ErrorCode.None)
155 Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
158 ApplicationInfo app = new ApplicationInfo(clonedHandle);
164 err = Interop.ApplicationManager.AppManagerForeachAppInfo(cb, IntPtr.Zero);
165 if (err != Interop.ApplicationManager.ErrorCode.None)
167 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach the appinfo.");
174 /// Gets the information of the installed applications with the ApplicationInfoFilter asynchronously.
176 /// <param name="filter">Key-value pairs for filtering.</param>
177 /// <since_tizen> 3 </since_tizen>
178 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync(ApplicationInfoFilter filter)
180 return await Task.Run(() =>
182 List<ApplicationInfo> result = new List<ApplicationInfo>();
184 Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr infoHandle, IntPtr userData) =>
186 if (infoHandle != IntPtr.Zero)
188 IntPtr clonedHandle = IntPtr.Zero;
189 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
190 if (err != Interop.ApplicationManager.ErrorCode.None)
192 Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
195 ApplicationInfo app = new ApplicationInfo(clonedHandle);
207 /// Gets the information of the installed applications with the ApplicationInfoMetadataFilter asynchronously.
209 /// <param name="filter">Key-value pairs for filtering.</param>
210 /// <since_tizen> 3 </since_tizen>
211 public static async Task<IEnumerable<ApplicationInfo>> GetInstalledApplicationsAsync(ApplicationInfoMetadataFilter filter)
213 return await Task.Run(() =>
215 List<ApplicationInfo> result = new List<ApplicationInfo>();
217 Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr infoHandle, IntPtr userData) =>
219 if (infoHandle != IntPtr.Zero)
221 IntPtr clonedHandle = IntPtr.Zero;
222 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoClone(out clonedHandle, infoHandle);
223 if (err != Interop.ApplicationManager.ErrorCode.None)
225 Log.Warn(LogTag, "Failed to clone the appinfo. err = " + err);
228 ApplicationInfo app = new ApplicationInfo(clonedHandle);
240 /// Gets the information of the running applications asynchronously.
242 /// <since_tizen> 3 </since_tizen>
243 public static async Task<IEnumerable<ApplicationRunningContext>> GetRunningApplicationsAsync()
245 return await Task.Run(() =>
247 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
248 List<ApplicationRunningContext> result = new List<ApplicationRunningContext>();
250 Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr contextHandle, IntPtr userData) =>
252 if (contextHandle != IntPtr.Zero)
254 IntPtr clonedHandle = IntPtr.Zero;
255 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
256 if (err != Interop.ApplicationManager.ErrorCode.None)
258 Log.Warn(LogTag, "Failed to clone the app context. err = " + err);
261 ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle);
268 err = Interop.ApplicationManager.AppManagerForeachAppContext(cb, IntPtr.Zero);
269 if (err != Interop.ApplicationManager.ErrorCode.None)
271 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach appcontext.");
278 /// Gets the information of the running applications including subapp asynchronously.
280 /// <since_tizen> 3 </since_tizen>
281 public static async Task<IEnumerable<ApplicationRunningContext>> GetAllRunningApplicationsAsync()
283 return await Task.Run(() =>
285 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
286 List<ApplicationRunningContext> result = new List<ApplicationRunningContext>();
288 Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr contextHandle, IntPtr userData) =>
290 if (contextHandle != IntPtr.Zero)
292 IntPtr clonedHandle = IntPtr.Zero;
293 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
294 if (err != Interop.ApplicationManager.ErrorCode.None)
296 Log.Warn(LogTag, "Failed to clone the app context. err = " + err);
299 ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle);
306 err = Interop.ApplicationManager.AppManagerForeachRunningAppContext(cb, IntPtr.Zero);
307 if (err != Interop.ApplicationManager.ErrorCode.None)
309 throw ApplicationManagerErrorFactory.GetException(err, "Failed to foreach appcontext.");
316 /// Gets the information of the specified application with the application ID.
318 /// <param name="applicationId">Application ID.</param>
319 /// <since_tizen> 3 </since_tizen>
320 public static ApplicationInfo GetInstalledApplication(string applicationId)
322 IntPtr infoHandle = IntPtr.Zero;
323 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppManagerGetAppInfo(applicationId, out infoHandle);
324 if (err != Interop.ApplicationManager.ErrorCode.None)
326 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get the installed application information of " + applicationId + ".");
328 ApplicationInfo app = new ApplicationInfo(infoHandle);
333 /// Returns if the specified application is running or not.
335 /// <param name="applicationId">The application ID.</param>
336 /// <returns>Returns true if the given application is running, otherwise false.</returns>
337 /// <exception cref="ArgumentException">Thrown when the given parameter is invalid.</exception>
338 /// <since_tizen> 3 </since_tizen>
339 public static bool IsRunning(string applicationId)
341 bool isRunning = false;
342 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppManagerIsRunning(applicationId, out isRunning);
343 if (err != Interop.ApplicationManager.ErrorCode.None)
345 throw ApplicationManagerErrorFactory.GetException(Interop.ApplicationManager.ErrorCode.InvalidParameter, "Invalid parameter");
350 private static void RegisterApplicationChangedEvent()
352 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
353 s_applicationChangedEventCallback = (IntPtr contextHandle, Interop.ApplicationManager.AppContextEvent state, IntPtr userData) =>
355 if (contextHandle == IntPtr.Zero) return;
357 IntPtr clonedHandle = IntPtr.Zero;
358 err = Interop.ApplicationManager.AppContextClone(out clonedHandle, contextHandle);
359 if (err != Interop.ApplicationManager.ErrorCode.None)
361 throw ApplicationManagerErrorFactory.GetException(err, "Failed to register the application context event.");
363 using (ApplicationRunningContext context = new ApplicationRunningContext(clonedHandle))
365 if (state == Interop.ApplicationManager.AppContextEvent.Launched)
367 s_launchedHandler?.Invoke(null, new ApplicationLaunchedEventArgs { ApplicationRunningContext = context });
369 else if (state == Interop.ApplicationManager.AppContextEvent.Terminated)
371 s_terminatedHandler?.Invoke(null, new ApplicationTerminatedEventArgs { ApplicationRunningContext = context });
375 err = Interop.ApplicationManager.AppManagerSetAppContextEvent(s_applicationChangedEventCallback, IntPtr.Zero);
376 if (err != Interop.ApplicationManager.ErrorCode.None)
378 throw ApplicationManagerErrorFactory.GetException(err, "Failed to register the application context event.");
382 private static void UnRegisterApplicationChangedEvent()
384 Interop.ApplicationManager.AppManagerUnSetAppContextEvent();
387 private static void RegisterApplicationEvent()
389 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
390 err = Interop.ApplicationManager.AppManagerEventCreate(out _eventHandle);
391 if (err != Interop.ApplicationManager.ErrorCode.None)
393 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the application event handle");
396 err = Interop.ApplicationManager.AppManagerEventSetStatus(_eventHandle, Interop.ApplicationManager.AppManagerEventStatusType.All);
397 if (err != Interop.ApplicationManager.ErrorCode.None)
399 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
400 _eventHandle = IntPtr.Zero;
401 throw ApplicationManagerErrorFactory.GetException(err, "Failed to set the application event");
404 _eventCallback = (string appType, string appId, Interop.ApplicationManager.AppManagerEventType eventType, Interop.ApplicationManager.AppManagerEventState eventState, IntPtr eventHandle, IntPtr UserData) =>
406 if (eventType == Interop.ApplicationManager.AppManagerEventType.Enable)
408 _enabledHandler?.Invoke(null, new ApplicationEnabledEventArgs(appId, (ApplicationEventState)eventState));
410 else if (eventType == Interop.ApplicationManager.AppManagerEventType.Disable)
412 _disabledHandler?.Invoke(null, new ApplicationDisabledEventArgs(appId, (ApplicationEventState)eventState));
415 err = Interop.ApplicationManager.AppManagerSetEventCallback(_eventHandle, _eventCallback, IntPtr.Zero);
416 if (err != Interop.ApplicationManager.ErrorCode.None)
418 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
419 _eventHandle = IntPtr.Zero;
420 throw ApplicationManagerErrorFactory.GetException(err, "Failed to set the application event callback");
424 private static void UnRegisterApplicationEvent()
426 if (_eventHandle != IntPtr.Zero)
428 Interop.ApplicationManager.AppManagerUnSetEventCallback(_eventHandle);
429 Interop.ApplicationManager.AppManagerEventDestroy(_eventHandle);
430 _eventHandle = IntPtr.Zero;
435 /// Gets the information of the recent applications.
437 /// <returns>Returns a dictionary containing all the recent application info.</returns>
438 /// <exception cref="InvalidOperationException">Thrown when failed because of an invalid operation.</exception>
439 /// <since_tizen> 3 </since_tizen>
440 [EditorBrowsable(EditorBrowsableState.Never)]
441 public static IEnumerable<RecentApplicationInfo> GetRecentApplications()
443 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.ErrorCode.None;
445 List<RecentApplicationInfo> result = new List<RecentApplicationInfo>();
449 err = Interop.ApplicationManager.RuaHistoryLoadDb(out table, out nrows, out ncols);
450 if (err != Interop.ApplicationManager.ErrorCode.None)
452 throw ApplicationManagerErrorFactory.GetException(err, "Failed to load a table for the recent application list.");
455 for (int row = 0; row < nrows; ++row)
457 Interop.ApplicationManager.RuaRec record;
459 err = Interop.ApplicationManager.RuaHistoryGetRecord(out record, table, nrows, ncols, row);
460 if (err != Interop.ApplicationManager.ErrorCode.None)
462 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get record.");
465 RecentApplicationInfo info = new RecentApplicationInfo(record);
469 err = Interop.ApplicationManager.RuaHistoryUnLoadDb(ref table);
470 if (err != Interop.ApplicationManager.ErrorCode.None)
472 throw ApplicationManagerErrorFactory.GetException(err, "Failed to unload a table for the recent application list.");
479 internal static class FilterExtension
481 private const string LogTag = "Tizen.Applications";
482 internal static void Fetch(this ApplicationInfoFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
484 if (filter is ApplicationInfoMetadataFilter)
486 ApplicationInfoMetadataFilter metaFilter = (ApplicationInfoMetadataFilter)filter;
487 metaFilter.Fetch(callback);
491 IntPtr nativeHandle = MakeNativeAppInfoFilter(filter.Filter);
492 if (nativeHandle == IntPtr.Zero)
494 throw ApplicationManagerErrorFactory.NativeFilterHandleIsInvalid();
498 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoFilterForeachAppinfo(nativeHandle, callback, IntPtr.Zero);
499 if (err != Interop.ApplicationManager.ErrorCode.None)
501 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get application information list with filter.");
506 Interop.ApplicationManager.AppInfoFilterDestroy(nativeHandle);
510 internal static void Fetch(this ApplicationInfoMetadataFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
512 IntPtr nativeHandle = MakeNativeAppMetadataFilter(filter.Filter);
513 if (nativeHandle == IntPtr.Zero)
515 throw ApplicationManagerErrorFactory.NativeFilterHandleIsInvalid();
519 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoMetadataFilterForeach(nativeHandle, callback, IntPtr.Zero);
520 if (err != Interop.ApplicationManager.ErrorCode.None)
522 throw ApplicationManagerErrorFactory.GetException(err, "Failed to get metadata list with filter.");
527 Interop.ApplicationManager.AppInfoMetadataFilterDestroy(nativeHandle);
531 private static IntPtr MakeNativeAppInfoFilter(IDictionary<string, string> filter)
533 if (filter == null || filter.Count == 0)
535 throw ApplicationManagerErrorFactory.FilterIsInvalid();
538 IntPtr infoHandle = IntPtr.Zero;
539 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoFilterCreate(out infoHandle);
540 if (err != Interop.ApplicationManager.ErrorCode.None)
542 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the filter handle.");
545 foreach (var item in filter)
547 if ((item.Key == ApplicationInfoFilter.Keys.Id) ||
548 (item.Key == ApplicationInfoFilter.Keys.Type) ||
549 (item.Key == ApplicationInfoFilter.Keys.Category))
551 err = Interop.ApplicationManager.AppInfoFilterAddString(infoHandle, item.Key, item.Value);
553 else if ((item.Key == ApplicationInfoFilter.Keys.NoDisplay) ||
554 (item.Key == ApplicationInfoFilter.Keys.TaskManage))
556 err = Interop.ApplicationManager.AppInfoFilterAddBool(infoHandle, item.Key, Convert.ToBoolean(item.Value));
560 Log.Warn(LogTag, string.Format("'{0}' is not supported key for the filter.", item.Key));
562 if (err != Interop.ApplicationManager.ErrorCode.None)
564 Interop.ApplicationManager.AppInfoFilterDestroy(infoHandle);
565 throw ApplicationManagerErrorFactory.GetException(err, "Failed to add item to the filter.");
571 private static IntPtr MakeNativeAppMetadataFilter(IDictionary<string, string> filter)
573 if (filter == null || filter.Count == 0)
575 throw ApplicationManagerErrorFactory.FilterIsInvalid();
578 IntPtr infoHandle = IntPtr.Zero;
579 Interop.ApplicationManager.ErrorCode err = Interop.ApplicationManager.AppInfoMetadataFilterCreate(out infoHandle);
580 if (err != Interop.ApplicationManager.ErrorCode.None)
582 throw ApplicationManagerErrorFactory.GetException(err, "Failed to create the filter for searching with metadata.");
584 foreach (var item in filter)
586 err = Interop.ApplicationManager.AppInfoMetadataFilterAdd(infoHandle, item.Key, item.Value);
587 if (err != Interop.ApplicationManager.ErrorCode.None)
589 Interop.ApplicationManager.AppInfoMetadataFilterDestroy(infoHandle);
590 throw ApplicationManagerErrorFactory.GetException(err, "Failed to add the item to the filter.");
597 internal static class ApplicationManagerErrorFactory
599 internal static Exception NativeFilterHandleIsInvalid()
601 return new InvalidOperationException("The native handle for filtering is invalid.");
604 internal static Exception FilterIsInvalid()
606 return new ArgumentException("The filter is invalid.");
609 internal static Exception GetException(Interop.ApplicationManager.ErrorCode err, string message)
611 string errMessage = String.Format("{0} err = {1}", message, err);
614 case Interop.ApplicationManager.ErrorCode.InvalidParameter:
615 return new ArgumentException(errMessage);
617 return new InvalidOperationException(errMessage);