3fb98cbdc458824fa1cd40016384398113c10fc5
[platform/core/csapi/tizenfx.git] / Tizen.Applications / Tizen.Applications.Managers / ApplicationManagerImpl.cs
1 /// Copyright 2016 by Samsung Electronics, Inc.,
2 ///
3 /// This software is the confidential and proprietary information
4 /// of Samsung Electronics, Inc. ("Confidential Information"). You
5 /// shall not disclose such Confidential Information and shall use
6 /// it only in accordance with the terms of the license agreement
7 /// you entered into with Samsung.
8
9
10 using System;
11 using System.Collections.Generic;
12 using System.Threading.Tasks;
13 using System.Runtime.InteropServices;
14
15 namespace Tizen.Applications.Managers
16 {
17     internal class ApplicationManagerImpl : IDisposable
18     {
19         private static ApplicationManagerImpl s_instance = new ApplicationManagerImpl();
20
21         private bool _disposed = false;
22         private Interop.ApplicationManager.AppManagerAppContextEventCallback _applicationChangedEventCallback;
23
24         private const string LogTag = "Tizen.Applications.Managers";
25
26         private ApplicationManagerImpl()
27         {
28             Log.Debug(LogTag, "ApplicationManagerImpl()");
29             RegisterApplicationChangedEvent();
30         }
31
32
33         ~ApplicationManagerImpl()
34         {
35             Log.Debug(LogTag, "~ApplicationManagerImpl()");
36             UnRegisterApplicationChangedEvent();
37             Dispose(false);
38         }
39
40         internal event EventHandler<ApplicationChangedEventArgs> ApplicationLaunched;
41         internal event EventHandler<ApplicationChangedEventArgs> ApplicationTerminated;
42
43         internal static ApplicationManagerImpl Instance
44         {
45             get
46             {
47                 return s_instance;
48             }
49         }
50
51         public void Dispose()
52         {
53             Dispose(true);
54             GC.SuppressFinalize(this);
55         }
56
57         private void Dispose(bool disposing)
58         {
59             if (_disposed)
60                 return;
61
62             if (disposing)
63             {
64                 // Free managed objects.
65             }
66             //Free unmanaged objects
67             _disposed = true;
68         }
69
70         internal async Task<IEnumerable<InstalledApplication>> GetInstalledAppsAsync()
71         {
72             Log.Debug(LogTag, "GetInstalledAppsAsync()");
73             return await Task.Run(() =>
74             {
75                 List<InstalledApplication> Result = new List<InstalledApplication>();
76
77                 Interop.ApplicationManager.AppManagerAppInfoCallback cb = (IntPtr handle, IntPtr userData) =>
78                 {
79                     if (handle != IntPtr.Zero)
80                     {
81                         IntPtr clonedHandle = IntPtr.Zero;
82                         int result = Interop.ApplicationManager.AppInfoClone(out clonedHandle, handle);
83                         if (result != 0)
84                         {
85                             return false;
86                         }
87                         InstalledApplication app = new InstalledApplication(clonedHandle);
88                         Result.Add(app);
89                         return true;
90                     }
91                     return false;
92                 };
93                 int ret = Interop.ApplicationManager.AppManagerForeachAppInfo(cb, IntPtr.Zero);
94                 if (ret != 0)
95                 {
96                     ApplicationManagerErrorFactory.ExceptionChecker(ret, "GetInstalledAppsAsync() failed.");
97                 }
98                 return Result;
99             });
100         }
101
102         internal async Task<IEnumerable<InstalledApplication>> GetInstalledAppsAsync(InstalledApplicationFilter filter)
103         {
104             Log.Debug(LogTag, "GetInstalledAppsAsync(InstalledApplicationFilter filter)");
105             return await Task.Run(() =>
106             {
107                 List<InstalledApplication> Result = new List<InstalledApplication>();
108
109                 Interop.ApplicationManager.AppInfoFilterCallback cb = (IntPtr handle, IntPtr userData) =>
110                 {
111                     Log.Debug(LogTag, "AppInfoFilterCallback");
112                     if (handle != IntPtr.Zero)
113                     {
114                         IntPtr clonedHandle = IntPtr.Zero;
115                         int ret = Interop.ApplicationManager.AppInfoClone(out clonedHandle, handle);
116                         if (ret != 0)
117                         {
118                             return false;
119                         }
120                         InstalledApplication app = new InstalledApplication(clonedHandle);
121                         Result.Add(app);
122                         return true;
123                     }
124                     return false;
125                 };
126                 filter.Fetch(cb);
127                 return Result;
128             });
129         }
130         internal async Task<IEnumerable<RunningApplication>> GetRunningAppsAsync()
131         {
132             Log.Debug(LogTag, "GetRunningAppsAsync()");
133
134             return await Task.Run(() =>
135             {
136                 List<RunningApplication> Result = new List<RunningApplication>();
137
138                 Interop.ApplicationManager.AppManagerAppContextCallback cb = (IntPtr handle, IntPtr userData) =>
139                 {
140                     Log.Debug(LogTag, "AppManagerAppContextCallback");
141                     if (handle != IntPtr.Zero)
142                     {
143                         IntPtr ptr = IntPtr.Zero;
144                         int result = Interop.ApplicationManager.AppContextGetAppId(handle, out ptr);
145                         if (result != 0)
146                         {
147                             return false;
148                         }
149                         string appid = Marshal.PtrToStringAuto(ptr);
150                         int pid = 0;
151                         result = Interop.ApplicationManager.AppContextGetPid(handle, out pid);
152                         if (result != 0)
153                         {
154                             return false;
155                         }
156                         RunningApplication app = new RunningApplication(appid, pid);
157                         Result.Add(app);
158                         return true;
159                     }
160                     return false;
161                 };
162
163                 int ret = Interop.ApplicationManager.AppManagerForeachAppContext(cb, IntPtr.Zero);
164                 if (ret != 0)
165                 {
166                     ApplicationManagerErrorFactory.ExceptionChecker(ret, "GetRunningAppsAsync() failed.");
167                 }
168                 return Result;
169             });
170         }
171
172         internal InstalledApplication GetInstalledApp(string applicationId)
173         {
174             Log.Debug(LogTag, "GetInstalledApp(applicationId)");
175             IntPtr handle = IntPtr.Zero;
176             int ret = Interop.ApplicationManager.AppManagerGetAppInfo(applicationId, out handle);
177             if (ret != 0)
178             {
179                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "GetInstalledApp(applicationId) failed.");
180             }
181             if (handle != IntPtr.Zero)
182             {
183                 InstalledApplication app = new InstalledApplication(handle);
184                 return app;
185             }
186             return null;
187         }
188
189         internal RunningApplication GetRunningApp(string applicationId)
190         {
191             Log.Debug(LogTag, "GetRunningApp(applicationId)");
192             IntPtr handle = IntPtr.Zero;
193             int ret = Interop.ApplicationManager.AppManagerGetAppContext(applicationId, out handle);
194             if (ret != 0)
195             {
196                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "GetRunningApp(applicationId) failed.");
197             }
198             if (handle != IntPtr.Zero)
199             {
200                 int pid = 0;
201                 ret = Interop.ApplicationManager.AppContextGetPid(handle, out pid);
202                 if (ret != 0)
203                 {
204                     ApplicationManagerErrorFactory.ExceptionChecker(ret, "GetRunningApp(applicationId) failed.");
205                 }
206                 RunningApplication app = new RunningApplication(applicationId, pid);
207                 return app;
208             }
209             return null;
210         }
211
212         internal RunningApplication GetRunningApp(int processId)
213         {
214             Log.Debug(LogTag, "GetRunningApp(processId)");
215             string appid = "";
216             int ret = Interop.ApplicationManager.AppManagerGetAppId(processId, out appid);
217             if (ret != 0)
218             {
219                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "GetRunningApp(processId) failed.");
220             }
221             RunningApplication app = new RunningApplication(appid, processId);
222             return app;
223         }
224
225         internal bool IsRunningApp(string applicationId)
226         {
227             Log.Debug(LogTag, "IsRunningApp(applicationId)");
228             bool running = false;
229             int ret = Interop.ApplicationManager.AppManagerIsRunning(applicationId, out running);
230             if (ret != 0)
231             {
232                 Log.Warn(LogTag, "IsRunningApp(applicationId) failed.");
233             }
234             return running;
235         }
236
237         internal bool IsRunningApp(int processId)
238         {
239             Log.Debug(LogTag, "IsRunningApp(processId)");
240             string appid = "";
241             int ret = Interop.ApplicationManager.AppManagerGetAppId(processId, out appid);
242             if (ret != 0)
243             {
244                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "IsRunningApp(processId) failed.");
245             }
246             bool running = false;
247             ret = Interop.ApplicationManager.AppManagerIsRunning(appid, out running);
248             if (ret != 0)
249             {
250                 Log.Warn(LogTag, "IsRunningApp(processId) failed.");
251             }
252             return running;
253         }
254
255         private void RegisterApplicationChangedEvent()
256         {
257             Log.Debug(LogTag, "RegisterApplicationChangedEvent()");
258             _applicationChangedEventCallback = (IntPtr handle, int state, IntPtr userData) =>
259             {
260                 Log.Debug(LogTag, "ApplicationChangedEventCallback");
261                 if (handle == IntPtr.Zero) return;
262
263                 IntPtr ptr = IntPtr.Zero;
264                 int result = Interop.ApplicationManager.AppContextGetAppId(handle, out ptr);
265                 if (result != 0)
266                 {
267                     ApplicationManagerErrorFactory.ExceptionChecker(result, "RegisterApplicationChangedEvent() failed.");
268                 }
269                 string appid = Marshal.PtrToStringAuto(ptr);
270                 int pid = 0;
271                 result = Interop.ApplicationManager.AppContextGetPid(handle, out pid);
272                 if (result != 0)
273                 {
274                     ApplicationManagerErrorFactory.ExceptionChecker(result, "RegisterApplicationChangedEvent() failed.");
275                 }
276                 if (state == 0)
277                 {
278                     var launchedEventCache = ApplicationLaunched;
279                     if (launchedEventCache != null)
280                     {
281                         Log.Debug(LogTag, "Raise up ApplicationLaunched");
282                         ApplicationChangedEventArgs e = new ApplicationChangedEventArgs(appid, pid, state);
283                         launchedEventCache(null, e);
284                     }
285                 }
286                 else if (state == 1)
287                 {
288                     var terminatedEventCache = ApplicationTerminated;
289                     if (terminatedEventCache != null)
290                     {
291                         Log.Debug(LogTag, "Raise up ApplicationTerminated");
292                         ApplicationChangedEventArgs e = new ApplicationChangedEventArgs(appid, pid, state);
293                         terminatedEventCache(null, e);
294                     }
295                 }
296             };
297             int ret = Interop.ApplicationManager.AppManagerSetAppContextEvent(_applicationChangedEventCallback, IntPtr.Zero);
298             if (ret != 0)
299             {
300                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "RegisterApplicationChangedEvent() register failed.");
301             }
302         }
303
304         private void UnRegisterApplicationChangedEvent()
305         {
306             Log.Debug(LogTag, "UnRegisterApplicationChangedEvent()");
307             Interop.ApplicationManager.AppManagerUnSetAppContextEvent();
308         }
309     }
310     internal static class FilterExtension
311     {
312         private const string LogTag = "Tizen.Applications.Managers";
313         internal static void Fetch(this InstalledApplicationFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
314         {
315             if (filter is InstalledApplicationMetadataFilter)
316             {
317                 InstalledApplicationMetadataFilter metaFilter = (InstalledApplicationMetadataFilter)filter;
318                 metaFilter.Fetch(callback);
319                 return;
320             }
321
322             IntPtr nativeHandle = MakeNativeAppInfoFilter(filter.Filter);
323             int ret = Interop.ApplicationManager.AppInfoFilterForeachAppinfo(nativeHandle, callback, IntPtr.Zero);
324             if (nativeHandle != IntPtr.Zero)
325                 Interop.ApplicationManager.AppInfoFilterDestroy(nativeHandle);
326             if (ret != 0)
327             {
328                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "GetInstalledAppsAsync(InstalledApplicationFilter) failed.");
329             }
330         }
331
332         internal static void Fetch(this InstalledApplicationMetadataFilter filter, Interop.ApplicationManager.AppInfoFilterCallback callback)
333         {
334             IntPtr nativeHandle = MakeNativeAppMetadataFilter(filter.Filter);
335             int ret = Interop.ApplicationManager.AppInfoMetadataFilterForeach(nativeHandle, callback, IntPtr.Zero);
336             if (nativeHandle != IntPtr.Zero)
337                 Interop.ApplicationManager.AppInfoMetadataFilterDestroy(nativeHandle);
338             if (ret != 0)
339             {
340                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "GetInstalledAppsAsync(InstalledApplicationMetadataFilter) failed.");
341             }
342         }
343
344
345         private static IntPtr MakeNativeAppInfoFilter(IDictionary<string, string> filter)
346         {
347             if (filter == null)
348                 throw new ArgumentException("Filter dose not added");
349             IntPtr handle;
350             int ret = Interop.ApplicationManager.AppInfoFilterCreate(out handle);
351             if (ret != 0)
352             {
353                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "AppInfoFilter creation failed.");
354             }
355
356             foreach (var item in filter)
357             {
358                 if ((item.Key == InstalledApplicationFilter.Keys.Id) ||
359                     (item.Key == InstalledApplicationFilter.Keys.Type) ||
360                     (item.Key == InstalledApplicationFilter.Keys.Category))
361                 {
362                     ret = Interop.ApplicationManager.AppInfoFilterAddString(handle, item.Key, item.Value);
363                 }
364                 else if ((item.Key == InstalledApplicationFilter.Keys.NoDisplay) ||
365                          (item.Key == InstalledApplicationFilter.Keys.TaskManage))
366                 {
367                     ret = Interop.ApplicationManager.AppInfoFilterAddBool(handle, item.Key, Convert.ToBoolean(item.Value));
368                 }
369                 else
370                 {
371                     Log.Warn(LogTag, "InstalledApplicationFilter is NOT supported " + item.Key + " key.");
372                 }
373                 if (ret != 0)
374                 {
375                     Interop.ApplicationManager.AppInfoFilterDestroy(handle);
376                     ApplicationManagerErrorFactory.ExceptionChecker(ret, "InstalledApplicationFilter item add failed.");
377                 }
378             }
379             return handle;
380         }
381
382         private static IntPtr MakeNativeAppMetadataFilter(IDictionary<string, string> filter)
383         {
384             if (filter == null)
385                 throw new ArgumentException("Filter dose not added");
386             IntPtr handle;
387             int ret = Interop.ApplicationManager.AppInfoMetadataFilterCreate(out handle);
388             if (ret != 0)
389             {
390                 ApplicationManagerErrorFactory.ExceptionChecker(ret, "InstalledApplicationMetadataFilter creation failed.");
391             }
392             foreach (var item in filter)
393             {
394                 ret = Interop.ApplicationManager.AppInfoMetadataFilterAdd(handle, item.Key, item.Value);
395                 if (ret != 0)
396                 {
397                     Interop.ApplicationManager.AppInfoMetadataFilterDestroy(handle);
398                     ApplicationManagerErrorFactory.ExceptionChecker(ret, "InstalledApplicationMetadataFilter item add failed.");
399                 }
400             }
401             return handle;
402         }
403     }
404 }