36d7a256ad2b8a591eecabc487043a738bcb0510
[platform/core/csapi/tizenfx.git] / src / Tizen.Applications.PackageManager / Tizen.Applications / PackageManager.cs
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Threading.Tasks;
20 using System.IO;
21 using System.Linq;
22
23 namespace Tizen.Applications
24 {
25     /// <summary>
26     /// PackageManager class. This class has the methods and events of the PackageManager.
27     /// </summary>
28     /// <remarks>
29     /// The package manager is one of the core modules of the Tizen application framework and responsible for getting their information.
30     /// You can also retrieve information related to the packages that are installed on the device.
31     /// </remarks>
32     /// <since_tizen> 3 </since_tizen>
33     public static class PackageManager
34     {
35         private const string LogTag = "Tizen.Applications.PackageManager";
36
37         private static SafePackageManagerHandle s_handle = new SafePackageManagerHandle();
38         private static Interop.PackageManager.EventStatus s_eventStatus = Interop.PackageManager.EventStatus.All;
39         private static event EventHandler<PackageManagerEventArgs> s_installEventHandler;
40         private static event EventHandler<PackageManagerEventArgs> s_uninstallEventHandler;
41         private static event EventHandler<PackageManagerEventArgs> s_updateEventHandler;
42         private static event EventHandler<PackageManagerEventArgs> s_moveEventHandler;
43         private static event EventHandler<PackageManagerEventArgs> s_clearDataEventHandler;
44
45         private static readonly object s_pkgEventLock = new object();
46         private static Interop.PackageManager.PackageManagerEventCallback s_packageManagerEventCallback = new Interop.PackageManager.PackageManagerEventCallback(InternalEventCallback);
47
48         private static Dictionary<IntPtr, Interop.PackageManager.PackageManagerTotalSizeInfoCallback> s_totalSizeInfoCallbackDict = new Dictionary<IntPtr, Interop.PackageManager.PackageManagerTotalSizeInfoCallback>();
49         private static int s_callbackId = 0;
50
51         /// <summary>
52         /// Event callback method for the request.
53         /// </summary>
54         /// <param name="type">Type of the package which was requested.</param>
55         /// <param name="packageId">ID of the package which was requested.</param>
56         /// <param name="eventType">Event type of the request.</param>
57         /// <param name="eventState">Current event state of the request.</param>
58         /// <param name="progress">Progress for the request being processed by the package manager (in percent).</param>
59         /// <since_tizen> 3 </since_tizen>
60         public delegate void RequestEventCallback(string type, string packageId, PackageEventType eventType, PackageEventState eventState, int progress);
61
62         private static Dictionary<int, RequestEventCallback> RequestCallbacks = new Dictionary<int, RequestEventCallback>();
63         private static Dictionary<int, SafePackageManagerRequestHandle> RequestHandles = new Dictionary<int, SafePackageManagerRequestHandle>();
64         private static Dictionary<int, int> RequestPackageCount = new Dictionary<int, int>();
65
66         private delegate Interop.PackageManager.ErrorCode InstallMethodWithCallback(SafePackageManagerRequestHandle requestHandle, string pkgPath, Interop.PackageManager.PackageManagerRequestEventCallback requestCallback, IntPtr userData, out int requestID);
67         private delegate Interop.PackageManager.ErrorCode InstallPackagesMethodWithCallback(SafePackageManagerRequestHandle requestHandle, string[] pkgPaths, int pathsCount, Interop.PackageManager.PackageManagerRequestEventCallback requestCallback, IntPtr userData, out int requestId);
68         private delegate Interop.PackageManager.ErrorCode InstallMethod(SafePackageManagerRequestHandle requestHandle, string pkgPath, out int requestID);
69         private delegate Interop.PackageManager.ErrorCode InstallPackagesMethod(SafePackageManagerRequestHandle requestHandle, string[] pkgPaths, int pathsCount, out int requestID);
70
71         /// <summary>
72         /// InstallProgressChanged event. This event occurs when a package is getting installed and the progress of the request to the package manager is changed.
73         /// </summary>
74         /// <since_tizen> 3 </since_tizen>
75         public static event EventHandler<PackageManagerEventArgs> InstallProgressChanged
76         {
77             add
78             {
79                 lock (s_pkgEventLock)
80                 {
81                     SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Install);
82                     RegisterPackageManagerEventIfNeeded();
83                     s_installEventHandler += value;
84                 }
85             }
86             remove
87             {
88                 lock (s_pkgEventLock)
89                 {
90                     s_installEventHandler -= value;
91                     UnregisterPackageManagerEventIfNeeded();
92                     UnsetPackageManagerEventStatus();
93                 }
94             }
95         }
96
97         /// <summary>
98         /// UninstallProgressChanged event. This event occurs when a package is getting uninstalled and the progress of the request to the package manager is changed.
99         /// </summary>
100         /// <since_tizen> 3 </since_tizen>
101         public static event EventHandler<PackageManagerEventArgs> UninstallProgressChanged
102         {
103             add
104             {
105                 lock (s_pkgEventLock)
106                 {
107                     SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Uninstall);
108                     RegisterPackageManagerEventIfNeeded();
109                     s_uninstallEventHandler += value;
110                 }
111             }
112             remove
113             {
114                 lock (s_pkgEventLock)
115                 {
116                     s_uninstallEventHandler -= value;
117                     UnregisterPackageManagerEventIfNeeded();
118                     UnsetPackageManagerEventStatus();
119                 }
120            }
121         }
122
123         /// <summary>
124         /// UpdateProgressChanged event. This event occurs when a package is getting updated and the progress of the request to the package manager is changed.
125         /// </summary>
126         /// <since_tizen> 3 </since_tizen>
127         public static event EventHandler<PackageManagerEventArgs> UpdateProgressChanged
128         {
129             add
130             {
131                 lock (s_pkgEventLock)
132                 {
133                     SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Upgrade);
134                     RegisterPackageManagerEventIfNeeded();
135                     s_updateEventHandler += value;
136                 }
137             }
138             remove
139             {
140                 lock (s_pkgEventLock)
141                 {
142                     s_updateEventHandler -= value;
143                     UnregisterPackageManagerEventIfNeeded();
144                     UnsetPackageManagerEventStatus();
145                 }
146             }
147         }
148
149         /// <summary>
150         /// MoveProgressChanged event. This event occurs when a package is getting moved and the progress of the request to the package manager is changed.
151         /// </summary>
152         /// <since_tizen> 3 </since_tizen>
153         public static event EventHandler<PackageManagerEventArgs> MoveProgressChanged
154         {
155             add
156             {
157                 lock (s_pkgEventLock)
158                 {
159                     SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Move);
160                     RegisterPackageManagerEventIfNeeded();
161                     s_moveEventHandler += value;
162                 }
163             }
164             remove
165             {
166                 lock (s_pkgEventLock)
167                 {
168                     s_moveEventHandler -= value;
169                     UnregisterPackageManagerEventIfNeeded();
170                     UnsetPackageManagerEventStatus();
171                 }
172             }
173         }
174
175         /// <summary>
176         /// ClearDataProgressChanged event. This event occurs when data directories are cleared in the given package.
177         /// </summary>
178         /// <since_tizen> 3 </since_tizen>
179         public static event EventHandler<PackageManagerEventArgs> ClearDataProgressChanged
180         {
181             add
182             {
183                 lock (s_pkgEventLock)
184                 {
185                     SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.ClearData);
186                     RegisterPackageManagerEventIfNeeded();
187                     s_clearDataEventHandler += value;
188                 }
189             }
190             remove
191             {
192                 lock (s_pkgEventLock)
193                 {
194                     s_clearDataEventHandler -= value;
195                     UnregisterPackageManagerEventIfNeeded();
196                     UnsetPackageManagerEventStatus();
197                 }
198             }
199         }
200
201         private static SafePackageManagerHandle Handle
202         {
203             get
204             {
205                 if (s_handle.IsInvalid)
206                 {
207                     var err = Interop.PackageManager.PackageManagerCreate(out s_handle);
208                     if (err != Interop.PackageManager.ErrorCode.None)
209                     {
210                         Log.Warn(LogTag, string.Format("Failed to create package manager handle. err = {0}", err));
211                     }
212                 }
213                 return s_handle;
214             }
215         }
216
217         private static Interop.PackageManager.PackageManagerRequestEventCallback internalRequestEventCallback = (id, packageType, packageId, eventType, eventState, progress, error, userData) =>
218         {
219             if (RequestCallbacks.ContainsKey(id))
220             {
221                 try
222                 {
223                     RequestCallbacks[id](packageType, packageId, (PackageEventType)eventType, (PackageEventState)eventState, progress);
224                     if (eventState == Interop.PackageManager.PackageEventState.Completed || eventState == Interop.PackageManager.PackageEventState.Failed)
225                     {
226                         RequestPackageCount[id] -= 1;
227                         if (RequestPackageCount[id] < 1)
228                         {
229                             Log.Debug(LogTag, string.Format("release request handle for id : {0}", id));
230                             RequestHandles[id].Dispose();
231                             RequestHandles.Remove(id);
232                             RequestCallbacks.Remove(id);
233                             RequestPackageCount.Remove(id);
234                         }
235                     }
236                 }
237                 catch (Exception e)
238                 {
239                     Log.Warn(LogTag, e.Message);
240                     RequestHandles[id].Dispose();
241                     RequestHandles.Remove(id);
242                     RequestCallbacks.Remove(id);
243                     RequestPackageCount.Remove(id);
244                 }
245             }
246         };
247
248         /// <summary>
249         /// Gets the package ID for the given application ID.
250         /// </summary>
251         /// <param name="applicationId">The ID of the application.</param>
252         /// <returns>Returns the ID of the package.</returns>
253         /// <remarks>It returns null if the input is null.</remarks>
254         /// <exception cref="ArgumentException">Thrown when input application ID does not exist.</exception>
255         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
256         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
257         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
258         /// <since_tizen> 3 </since_tizen>
259         public static string GetPackageIdByApplicationId(string applicationId)
260         {
261             string packageId;
262             var err = Interop.PackageManager.PackageManagerGetPackageIdByAppId(applicationId, out packageId);
263             if (err != Interop.PackageManager.ErrorCode.None)
264             {
265                 Log.Warn(LogTag, string.Format("Failed to get package Id of {0}. err = {1}", applicationId, err));
266                 if (err != Interop.PackageManager.ErrorCode.InvalidParameter)
267                 {
268                     throw PackageManagerErrorFactory.GetException(err, "Failed to get package Id");
269                 }
270             }
271             return packageId;
272         }
273
274         /// <summary>
275         /// Gets the package information for the given package.
276         /// </summary>
277         /// <param name="packageId">The ID of the package.</param>
278         /// <returns>Returns the package information for the given package ID.</returns>
279         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
280         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
281         /// <exception cref="System.IO.IOException">Thrown when the method fails due to an internal I/O error.</exception>
282         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
283         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
284         /// <since_tizen> 3 </since_tizen>
285         public static Package GetPackage(string packageId)
286         {
287             return Package.GetPackage(packageId);
288         }
289
290         /// <summary>
291         /// Clears the application's internal and external cache directories.
292         /// </summary>
293         /// <param name="packageId">ID of the package.</param>
294         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
295         /// <exception cref="System.IO.IOException">Thrown when the method fails due to an internal I/O error.</exception>
296         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
297         /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
298         /// <privilege>http://tizen.org/privilege/packagemanager.clearcache</privilege>
299         /// <since_tizen> 3 </since_tizen>
300         public static void ClearCacheDirectory(string packageId)
301         {
302             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerClearCacheDir(packageId);
303             if (err != Interop.PackageManager.ErrorCode.None)
304             {
305                 Log.Warn(LogTag, string.Format("Failed to clear cache directory for {0}. err = {1}", packageId, err));
306                 throw PackageManagerErrorFactory.GetException(err, "Failed to clear cache directory");
307             }
308         }
309
310         /// <summary>
311         /// Clears all the application's internal and external cache directories.
312         /// </summary>
313         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
314         /// <exception cref="System.IO.IOException">Thrown when the method fails due to an internal IO error.</exception>
315         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
316         /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
317         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
318         /// <privlevel>platform</privlevel>
319         /// <since_tizen> 3 </since_tizen>
320         public static void ClearAllCacheDirectory()
321         {
322             var err = Interop.PackageManager.PackageManagerClearAllCacheDir();
323             if (err != Interop.PackageManager.ErrorCode.None)
324             {
325                 Log.Warn(LogTag, string.Format("Failed to clear all cache directories. err = {0}", err));
326                 throw PackageManagerErrorFactory.GetException(err, "Failed to clear all cache directories");
327             }
328         }
329
330         /// <summary>
331         /// Clears the application's internal and external data directories.
332         /// </summary>
333         /// <remarks>
334         /// All files under data, shared/data, and shared/trusted in the internal storage are removed.
335         /// And, if the external storage exists, then all files under data and shared/trusted in the external storage are removed.
336         /// </remarks>
337         /// <param name="packageId">ID of the package.</param>
338         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
339         /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal IO error.</exception>
340         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
341         /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
342         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
343         /// <privlevel>platform</privlevel>
344         /// <since_tizen> 3 </since_tizen>
345         public static void ClearDataDirectory(string packageId)
346         {
347             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerClearDataDir(packageId);
348             if (err != Interop.PackageManager.ErrorCode.None)
349             {
350                 Log.Warn(LogTag, string.Format("Failed to clear data directory for {0}. err = {1}", packageId, err));
351                 throw PackageManagerErrorFactory.GetException(err, "Failed to clear data directory");
352             }
353         }
354
355         /// <summary>
356         /// Removes a file or directory specified with <paramref name="path"/> from user data internal storage for the application.
357         /// </summary>
358         /// <param name="packageId">ID of the package.</param>
359         /// <param name="path">The path of the file or directory in the package user data folder.</param>
360         /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
361         /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal IO error.</exception>
362         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
363         /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
364         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
365         /// <privlevel>platform</privlevel>
366         /// <since_tizen> 11 </since_tizen>
367         public static void ClearUserData(string packageId, string path)
368         {
369             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerClearUserDataWithPath(packageId, path);
370             if (err != Interop.PackageManager.ErrorCode.None)
371             {
372                 Log.Warn(LogTag, string.Format("Failed to clear user data for {0} of {1}. err = {2}", path, packageId, err));
373                 throw PackageManagerErrorFactory.GetException(err, "Failed to clear user data");
374             }
375         }
376
377         /// <summary>
378         /// Retrieves the package information of all installed packages.
379         /// </summary>
380         /// <returns>Returns the list of packages.</returns>
381         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
382         /// <since_tizen> 3 </since_tizen>
383         public static IEnumerable<Package> GetPackages()
384         {
385             return GetPackages(null);
386         }
387
388         /// <summary>
389         /// Retrieves the package information of all the installed packages satisfying the filter conditions.
390         /// </summary>
391         /// <param name="filter">Optional - package filters.</param>
392         /// <returns>Returns the list of packages.</returns>
393         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
394         /// <since_tizen> 3 </since_tizen>
395         public static IEnumerable<Package> GetPackages(PackageFilter filter)
396         {
397             List<Package> packageList = new List<Package>();
398
399             IntPtr filterHandle;
400             var err = Interop.PackageManager.PackageManagerFilterCreate(out filterHandle);
401             if (err != Interop.PackageManager.ErrorCode.None)
402             {
403                 Log.Warn(LogTag, string.Format("Failed to create package filter handle. err = {0}", err));
404                 return packageList;
405             }
406
407             if (filter != null && filter.Filters != null)
408             {
409                 foreach (KeyValuePair<string, bool> entry in filter?.Filters)
410                 {
411                     err = Interop.PackageManager.PackageManagerFilterAdd(filterHandle, entry.Key, entry.Value);
412                     if (err != Interop.PackageManager.ErrorCode.None)
413                     {
414                         Log.Warn(LogTag, string.Format("Failed to configure package filter. err = {0}", err));
415                         break;
416                     }
417                 }
418
419             }
420
421             if (filter != null && filter.StringFilters != null)
422             {
423                 foreach (KeyValuePair<string, string> entry in filter?.StringFilters)
424                 {
425                     err = Interop.PackageManager.PackageManagerFilterAdd(filterHandle, entry.Key, entry.Value);
426                     if (err != Interop.PackageManager.ErrorCode.None)
427                     {
428                         Log.Warn(LogTag, string.Format("Failed to configure package filter. err = {0}", err));
429                         break;
430                     }
431                 }
432             }
433
434             if (err == Interop.PackageManager.ErrorCode.None)
435             {
436                 Interop.PackageManager.PackageManagerPackageInfoCallback cb = (handle, userData) =>
437                 {
438                     packageList.Add(Package.GetPackage(handle));
439                     return true;
440                 };
441
442                 err = Interop.PackageManager.PackageManagerFilterForeachPackageInfo(filterHandle, cb, IntPtr.Zero);
443                 if (err != Interop.PackageManager.ErrorCode.None)
444                 {
445                     Log.Warn(LogTag, string.Format("Failed to get package Informations. err = {0}", err));
446                 }
447             }
448
449             err = Interop.PackageManager.PackageManagerFilterDestroy(filterHandle);
450             if (err != Interop.PackageManager.ErrorCode.None)
451             {
452                 Log.Warn(LogTag, string.Format("Failed to destroy package filter handle. err = {0}", err));
453             }
454             return packageList;
455         }
456
457         /// <summary>
458         /// Gets the total package size information.
459         /// </summary>
460         /// <returns>Returns the total package size information asynchronously.</returns>
461         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
462         /// <since_tizen> 3 </since_tizen>
463         public static async Task<PackageSizeInformation> GetTotalSizeInformationAsync()
464         {
465             TaskCompletionSource<PackageSizeInformation> tcs = new TaskCompletionSource<PackageSizeInformation>();
466
467             Interop.PackageManager.PackageManagerTotalSizeInfoCallback cb = (handle, userData) =>
468             {
469                 if (handle != IntPtr.Zero)
470                 {
471                     tcs.TrySetResult(PackageSizeInformation.GetPackageSizeInformation(handle));
472                 }
473
474                 lock (s_totalSizeInfoCallbackDict)
475                 {
476                     s_totalSizeInfoCallbackDict.Remove(userData);
477                 }
478             };
479
480             IntPtr callbackId;
481             lock (s_totalSizeInfoCallbackDict)
482             {
483                 callbackId = (IntPtr)s_callbackId++;
484                 s_totalSizeInfoCallbackDict[callbackId] = cb;
485             }
486
487             var err = Interop.PackageManager.PackageManagerGetTotalSizeInfo(cb, callbackId);
488             if (err != Interop.PackageManager.ErrorCode.None)
489             {
490                 tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info"));
491             }
492             return await tcs.Task.ConfigureAwait(false);
493         }
494
495         /// <summary>
496         /// Installs the package located at the given path.
497         /// </summary>
498         /// <param name="packagePath">Absolute path for the package to be installed.</param>
499         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
500         /// <returns>Returns true if the installation request is successful, otherwise false.</returns>
501         /// <remarks>
502         /// The 'true' means that the request for installation is successful.
503         /// To check the result of the installation, the caller should check the progress using the InstallProgressChanged event.
504         /// </remarks>
505         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
506         /// <privlevel>platform</privlevel>
507         /// <since_tizen> 3 </since_tizen>
508         public static bool Install(string packagePath, InstallationMode installMode = InstallationMode.Normal)
509         {
510             return Install(packagePath, null, PackageType.UNKNOWN, null, installMode);
511         }
512
513         /// <summary>
514         /// Installs the package located at the given path.
515         /// </summary>
516         /// <param name="packagePath">Absolute path for the package to be installed.</param>
517         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
518         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
519         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
520         /// <remarks>
521         /// The 'true' means that the request for installation is successful.
522         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
523         /// </remarks>
524         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
525         /// <privlevel>platform</privlevel>
526         /// <since_tizen> 3 </since_tizen>
527         public static bool Install(string packagePath, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
528         {
529             return Install(packagePath, null, PackageType.UNKNOWN, eventCallback, installMode);
530         }
531
532         /// <summary>
533         /// Installs the package located at the given path.
534         /// </summary>
535         /// <param name="packagePath">Absolute path for the package to be installed.</param>
536         /// <param name="type">Package type for the package to be installed.</param>
537         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
538         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
539         /// <remarks>
540         /// The 'true' means that the request for installation is successful.
541         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
542         /// </remarks>
543         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
544         /// <privlevel>platform</privlevel>
545         /// <since_tizen> 3 </since_tizen>
546         public static bool Install(string packagePath, PackageType type, InstallationMode installMode = InstallationMode.Normal)
547         {
548             return Install(packagePath, null, type, null, installMode);
549         }
550
551         /// <summary>
552         /// Installs the package located at the given path.
553         /// </summary>
554         /// <param name="packagePath">Absolute path for the package to be installed.</param>
555         /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
556         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
557         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
558         /// <remarks>
559         /// The 'true' means that the request for installation is successful.
560         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
561         /// </remarks>
562         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
563         /// <privlevel>platform</privlevel>
564         /// <since_tizen> 3 </since_tizen>
565         public static bool Install(string packagePath, string expansionPackagePath, InstallationMode installMode = InstallationMode.Normal)
566         {
567             return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, null, installMode);
568         }
569
570         /// <summary>
571         /// Installs the package located at the given path.
572         /// </summary>
573         /// <param name="packagePath">Absolute path for the package to be installed.</param>
574         /// <param name="type">Package type for the package to be installed.</param>
575         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
576         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
577         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
578         /// <remarks>
579         /// The 'true' means that the request for installation is successful.
580         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
581         /// </remarks>
582         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
583         /// <privlevel>platform</privlevel>
584         /// <since_tizen> 3 </since_tizen>
585         public static bool Install(string packagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
586         {
587             return Install(packagePath, null, type, eventCallback, installMode);
588         }
589
590         /// <summary>
591         /// Installs the package located at the given path.
592         /// </summary>
593         /// <param name="packagePath">Absolute path for the package to be installed.</param>
594         /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
595         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
596         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
597         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
598         /// <remarks>
599         /// The 'true' means that the request for installation is successful.
600         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
601         /// </remarks>
602         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
603         /// <privlevel>platform</privlevel>
604         /// <since_tizen> 3 </since_tizen>
605         public static bool Install(string packagePath, string expansionPackagePath, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
606         {
607             return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, eventCallback, installMode);
608         }
609
610         /// <summary>
611         /// Installs the package located at the given path.
612         /// </summary>
613         /// <param name="packagePath">Absolute path for the package to be installed.</param>
614         /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
615         /// <param name="type">Package type for the package to be installed.</param>
616         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
617         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
618         /// <remarks>
619         /// The 'true' means that the request for installation is successful.
620         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
621         /// </remarks>
622         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
623         /// <privlevel>platform</privlevel>
624         /// <since_tizen> 3 </since_tizen>
625         public static bool Install(string packagePath, string expansionPackagePath, PackageType type, InstallationMode installMode = InstallationMode.Normal)
626         {
627             return Install(packagePath, expansionPackagePath, type, null, installMode);
628         }
629
630         /// <summary>
631         /// Installs the package located at the given path.
632         /// </summary>
633         /// <param name="packagePath">Absolute path for the package to be installed.</param>
634         /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
635         /// <param name="type">Package type for the package to be installed.</param>
636         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
637         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
638         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
639         /// <remarks>
640         /// The 'true' means that the request for installation is successful.
641         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
642         /// </remarks>
643         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
644         /// <privlevel>platform</privlevel>
645         /// <since_tizen> 3 </since_tizen>
646         public static bool Install(string packagePath, string expansionPackagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
647         {
648             return InstallInternal(new List<string>{ packagePath }, expansionPackagePath, type, eventCallback, installMode);
649         }
650
651         /// <summary>
652         /// Installs the packages located at the given path.
653         /// </summary>
654         /// <param name="packagePaths">Absolute paths for the package to be installed.</param>
655         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
656         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
657         /// <remarks>
658         /// The 'true' means that the request for installation is successful.
659         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
660         /// </remarks>
661         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
662         /// <privlevel>platform</privlevel>
663         /// <since_tizen> 8 </since_tizen>
664         public static bool Install(List<string> packagePaths, InstallationMode installMode = InstallationMode.Normal)
665         {
666             return InstallInternal(packagePaths, null, PackageType.UNKNOWN, null, installMode);
667         }
668
669         /// <summary>
670         /// Installs the packages located at the given path.
671         /// </summary>
672         /// <param name="packagePaths">Absolute paths for the package to be installed.</param>
673         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
674         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
675         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
676         /// <remarks>
677         /// The 'true' means that the request for installation is successful.
678         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
679         /// </remarks>
680         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
681         /// <privlevel>platform</privlevel>
682         /// <since_tizen> 8 </since_tizen>
683         public static bool Install(List<string> packagePaths, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
684         {
685             return InstallInternal(packagePaths, null, PackageType.UNKNOWN, eventCallback, installMode);
686         }
687
688         private static bool InstallInternal(List<string> packagePaths, string expansionPackagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode)
689         {
690             if (packagePaths == null || !packagePaths.Any())
691             {
692                 Log.Warn(LogTag, string.Format("Invalid argument"));
693                 return false;
694             }
695
696             SafePackageManagerRequestHandle RequestHandle;
697             var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
698             if (err != Interop.PackageManager.ErrorCode.None)
699             {
700                 Log.Warn(LogTag, string.Format("Failed to install packages. Error in creating package manager request handle. err = {0}", err));
701                 return false;
702             }
703
704             try
705             {
706                 if (type != PackageType.UNKNOWN)
707                 {
708                     err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLowerInvariant());
709                     if (err != Interop.PackageManager.ErrorCode.None)
710                     {
711                         Log.Warn(LogTag, string.Format("Failed to install packages. Error in setting request package type. err = {0}", err));
712                         RequestHandle.Dispose();
713                         return false;
714                     }
715                 }
716
717                 if (!string.IsNullOrEmpty(expansionPackagePath))
718                 {
719                     err = Interop.PackageManager.PackageManagerRequestSetTepPath(RequestHandle, expansionPackagePath);
720                     if (err != Interop.PackageManager.ErrorCode.None)
721                     {
722                         Log.Warn(LogTag, string.Format("Failed to install package. Error in setting request package mode. err = {0}", err));
723                         RequestHandle.Dispose();
724                         return false;
725                     }
726                 }
727
728                 int requestId;
729                 if (eventCallback != null)
730                 {
731                     if (packagePaths.Count > 1)
732                     {
733                         InstallPackagesMethodWithCallback installPackages;
734                         if (installMode == InstallationMode.Mount)
735                         {
736                             installPackages = Interop.PackageManager.PackageManagerRequestMountInstallPackagesWithCb;
737                         }
738                         else
739                         {
740                             installPackages = Interop.PackageManager.PackageManagerRequestInstallPackagesWithCb;
741                         }
742                         err = installPackages(RequestHandle, packagePaths.ToArray(), packagePaths.Count, internalRequestEventCallback, IntPtr.Zero, out requestId);
743                         if (err == Interop.PackageManager.ErrorCode.None)
744                         {
745                             RequestCallbacks.Add(requestId, eventCallback);
746                             RequestHandles.Add(requestId, RequestHandle);
747                             RequestPackageCount.Add(requestId, packagePaths.Count);
748                         }
749                         else
750                         {
751                             Log.Warn(LogTag, string.Format("Failed to install packages. err = {0}",  err));
752                             RequestHandle.Dispose();
753                             return false;
754                         }
755                     }
756                     else
757                     {
758                         InstallMethodWithCallback install;
759                         if (installMode == InstallationMode.Mount)
760                         {
761                             install = Interop.PackageManager.PackageManagerRequestMountInstallWithCB;
762                         }
763                         else
764                         {
765                             install = Interop.PackageManager.PackageManagerRequestInstallWithCB;
766                         }
767                         err = install(RequestHandle, packagePaths[0], internalRequestEventCallback, IntPtr.Zero, out requestId);
768                         if (err == Interop.PackageManager.ErrorCode.None)
769                         {
770                             RequestCallbacks.Add(requestId, eventCallback);
771                             RequestHandles.Add(requestId, RequestHandle);
772                             RequestPackageCount.Add(requestId, packagePaths.Count);
773
774                         }
775                         else
776                         {
777                             Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePaths, err));
778                             RequestHandle.Dispose();
779                             return false;
780                         }
781
782                     }
783
784                 }
785                 else
786                 {
787                     if (packagePaths.Count > 1)
788                     {
789                         InstallPackagesMethod installPackages;
790                         if (installMode == InstallationMode.Mount)
791                         {
792                             installPackages = Interop.PackageManager.PackageManagerRequestMountInstallPackages;
793                         }
794                         else
795                         {
796                             installPackages = Interop.PackageManager.PackageManagerRequestInstallPackages;
797                         }
798                         err = installPackages(RequestHandle, packagePaths.ToArray(), packagePaths.Count, out requestId);
799                         if (err != Interop.PackageManager.ErrorCode.None)
800                         {
801                             Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePaths, err));
802                             RequestHandle.Dispose();
803                             return false;
804                         }
805                     }
806                     else
807                     {
808                         InstallMethod install;
809                         if (installMode == InstallationMode.Mount)
810                         {
811                             install = Interop.PackageManager.PackageManagerRequestMountInstall;
812                         }
813                         else
814                         {
815                             install = Interop.PackageManager.PackageManagerRequestInstall;
816                         }
817                         err = install(RequestHandle, packagePaths[0], out requestId);
818                         if (err != Interop.PackageManager.ErrorCode.None)
819                         {
820                             Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePaths, err));
821                             RequestHandle.Dispose();
822                             return false;
823                         }
824                     }
825
826                     // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
827                     RequestHandle.Dispose();
828                 }
829                 return true;
830             }
831             catch (Exception e)
832             {
833                 Log.Warn(LogTag, e.Message);
834                 RequestHandle.Dispose();
835                 return false;
836             }
837         }
838
839         /// <summary>
840         /// Uninstalls the package with the given name.
841         /// </summary>
842         /// <param name="packageId">ID of the package to be uninstalled.</param>
843         /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
844         /// <remarks>
845         /// The 'true' means that the request for uninstallation is successful.
846         /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event.
847         /// </remarks>
848         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
849         /// <privlevel>platform</privlevel>
850         /// <since_tizen> 3 </since_tizen>
851         public static bool Uninstall(string packageId)
852         {
853             return Uninstall(packageId, PackageType.UNKNOWN, null);
854         }
855
856         /// <summary>
857         /// Uninstalls package with the given names.
858         /// </summary>
859         /// <param name="packageId">ID of the package to be uninstalled.</param>
860         /// <param name="type">Optional - Package type for the package to be uninstalled.</param>
861         /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
862         /// <remarks>
863         /// The 'true' means that the request for uninstallation is successful.
864         /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event.
865         /// </remarks>
866         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
867         /// <privlevel>platform</privlevel>
868         /// <since_tizen> 3 </since_tizen>
869         public static bool Uninstall(string packageId, PackageType type)
870         {
871             return Uninstall(packageId, type, null);
872         }
873
874         /// <summary>
875         /// Uninstalls the package with the given name.
876         /// </summary>
877         /// <param name="packageId">ID of the package to be uninstalled.</param>
878         /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
879         /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
880         /// <remarks>
881         /// The 'true' means that the request for uninstallation is successful.
882         /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event or eventCallback.
883         /// </remarks>
884         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
885         /// <privlevel>platform</privlevel>
886         /// <since_tizen> 3 </since_tizen>
887         public static bool Uninstall(string packageId, RequestEventCallback eventCallback)
888         {
889             return Uninstall(packageId, PackageType.UNKNOWN, eventCallback);
890         }
891
892         /// <summary>
893         /// Uninstalls the package with the given name.
894         /// </summary>
895         /// <param name="packageId">ID of the package to be uninstalled</param>
896         /// <param name="type">Optional - Package type for the package to be uninstalled.</param>
897         /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
898         /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
899         /// <remarks>
900         /// The 'true' means that the request for uninstallation is successful.
901         /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event or eventCallback.
902         /// </remarks>
903         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
904         /// <privlevel>platform</privlevel>
905         /// <since_tizen> 3 </since_tizen>
906         public static bool Uninstall(string packageId, PackageType type, RequestEventCallback eventCallback)
907         {
908             SafePackageManagerRequestHandle RequestHandle;
909             var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
910             if (err != Interop.PackageManager.ErrorCode.None)
911             {
912                 Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. Error in creating package manager request handle. err = {1}", packageId, err));
913                 return false;
914             }
915
916             try
917             {
918                 err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLowerInvariant());
919                 if (err != Interop.PackageManager.ErrorCode.None)
920                 {
921                     Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. Error in setting request package type. err = {1}", packageId, err));
922                     RequestHandle.Dispose();
923                     return false;
924                 }
925
926                 int requestId;
927                 if (eventCallback != null)
928                 {
929                     err = Interop.PackageManager.PackageManagerRequestUninstallWithCB(RequestHandle, packageId, internalRequestEventCallback, IntPtr.Zero, out requestId);
930                     if (err == Interop.PackageManager.ErrorCode.None)
931                     {
932                         RequestCallbacks.Add(requestId, eventCallback);
933                         RequestHandles.Add(requestId, RequestHandle);
934                         RequestPackageCount.Add(requestId, 1);
935                     }
936                     else
937                     {
938                         Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. err = {1}", packageId, err));
939                         RequestHandle.Dispose();
940                         return false;
941                     }
942                 }
943                 else
944                 {
945                     err = Interop.PackageManager.PackageManagerRequestUninstall(RequestHandle, packageId, out requestId);
946                     if (err != Interop.PackageManager.ErrorCode.None)
947                     {
948                         Log.Warn(LogTag, string.Format("Failed to uninstall package. err = {0}", err));
949                         RequestHandle.Dispose();
950                         return false;
951                     }
952                     // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
953                     RequestHandle.Dispose();
954                 }
955                 return true;
956             }
957             catch (Exception e)
958             {
959                 Log.Warn(LogTag, e.Message);
960                 RequestHandle.Dispose();
961                 return false;
962             }
963         }
964
965         /// <summary>
966         /// Moves the package to the given storage.
967         /// </summary>
968         /// <param name="packageId">ID of the package to be moved.</param>
969         /// <param name="newStorage">Storage package should be moved to.</param>
970         /// <returns>Returns true if the move request is successful, false otherwise.</returns>
971         /// <remarks>
972         /// The 'true' means that the request for move is successful.
973         /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
974         /// </remarks>
975         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
976         /// <privlevel>platform</privlevel>
977         /// <since_tizen> 3 </since_tizen>
978         public static bool Move(string packageId, StorageType newStorage)
979         {
980             return Move(packageId, PackageType.UNKNOWN, newStorage, null);
981         }
982
983         /// <summary>
984         /// Moves the package to the given storage.
985         /// </summary>
986         /// <param name="packageId">ID of the package to be moved.</param>
987         /// <param name="type">Optional - Package type for the package to be moved.</param>
988         /// <param name="newStorage">Storage package should be moved to.</param>
989         /// <returns>Returns true if the move request is successful, false otherwise.</returns>
990         /// <remarks>
991         /// The 'true' means that the request for move is successful.
992         /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
993         /// </remarks>
994         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
995         /// <privlevel>platform</privlevel>
996         /// <since_tizen> 3 </since_tizen>
997         public static bool Move(string packageId, PackageType type, StorageType newStorage)
998         {
999             return Move(packageId, type, newStorage, null);
1000         }
1001
1002         /// <summary>
1003         /// Moves the package to the given storage.
1004         /// </summary>
1005         /// <param name="packageId">ID of the package to be moved.</param>
1006         /// <param name="newStorage">Storage package should be moved to.</param>
1007         /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
1008         /// <returns>Returns true if move request is successful, false otherwise.</returns>
1009         /// <remarks>
1010         /// The 'true' means that the request for move is successful.
1011         /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
1012         /// </remarks>
1013         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1014         /// <privlevel>platform</privlevel>
1015         /// <since_tizen> 3 </since_tizen>
1016         public static bool Move(string packageId, StorageType newStorage, RequestEventCallback eventCallback)
1017         {
1018             return Move(packageId, PackageType.UNKNOWN, newStorage, eventCallback);
1019         }
1020
1021         /// <summary>
1022         /// Moves the package to the given storage.
1023         /// </summary>
1024         /// <param name="packageId">ID of the package to be moved.</param>
1025         /// <param name="type">Optional - Package type for the package to be moved.</param>
1026         /// <param name="newStorage">Storage, package should be moved to.</param>
1027         /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
1028         /// <returns>Returns true if move request is successful, false otherwise.</returns>
1029         /// <remarks>
1030         /// The 'true' means that the request for move is successful.
1031         /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
1032         /// </remarks>
1033         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1034         /// <privlevel>platform</privlevel>
1035         /// <since_tizen> 3 </since_tizen>
1036         public static bool Move(string packageId, PackageType type, StorageType newStorage, RequestEventCallback eventCallback)
1037         {
1038             SafePackageManagerRequestHandle RequestHandle;
1039             var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
1040             if (err != Interop.PackageManager.ErrorCode.None)
1041             {
1042                 Log.Warn(LogTag, string.Format("Failed to create package manager request handle. err = {0}", err));
1043                 return false;
1044             }
1045
1046             try
1047             {
1048                 bool result = true;
1049                 err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLowerInvariant());
1050                 if (err != Interop.PackageManager.ErrorCode.None)
1051                 {
1052                     Log.Warn(LogTag, string.Format("Failed to move package. Error in setting request package type. err = {0}", err));
1053                     RequestHandle.Dispose();
1054                     return false;
1055                 }
1056
1057                 if (eventCallback != null)
1058                 {
1059                     int requestId;
1060                     err = Interop.PackageManager.PackageManagerRequestMoveWithCB(RequestHandle, packageId, (Interop.PackageManager.StorageType)newStorage, internalRequestEventCallback, IntPtr.Zero, out requestId);
1061                     if (err == Interop.PackageManager.ErrorCode.None)
1062                     {
1063                         RequestCallbacks.Add(requestId, eventCallback);
1064                         RequestHandles.Add(requestId, RequestHandle);
1065                         RequestPackageCount.Add(requestId, 1);
1066                     }
1067                     else
1068                     {
1069                         Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
1070                         RequestHandle.Dispose();
1071                         result = false;
1072                     }
1073                 }
1074                 else
1075                 {
1076                     err = Interop.PackageManager.PackageManagerRequestMove(RequestHandle, packageId, (Interop.PackageManager.StorageType)newStorage);
1077                     if (err != Interop.PackageManager.ErrorCode.None)
1078                     {
1079                         Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
1080                         RequestHandle.Dispose();
1081                         result = false;
1082                     }
1083                     // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
1084                     RequestHandle.Dispose();
1085                 }
1086                 return result;
1087             }
1088             catch (Exception e)
1089             {
1090                 Log.Warn(LogTag, e.Message);
1091                 RequestHandle.Dispose();
1092                 return false;
1093             }
1094         }
1095
1096         /// <summary>
1097         /// Gets the permission type of the package which has a given application ID.
1098         /// </summary>
1099         /// <param name="applicationId">ID of the application.</param>
1100         /// <returns>Returns the permission type.</returns>
1101         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
1102         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1103         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1104         /// <since_tizen> 3 </since_tizen>
1105         public static PermissionType GetPermissionTypeByApplicationId(string applicationId)
1106         {
1107             Interop.PackageManager.PackageManagerPermissionType permissionType;
1108             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetPermissionType(applicationId, out permissionType);
1109             if (err != Interop.PackageManager.ErrorCode.None)
1110             {
1111                 throw PackageManagerErrorFactory.GetException(err, "Failed to get permission type.");
1112             }
1113
1114             return (PermissionType)permissionType;
1115         }
1116
1117         /// <summary>
1118         /// Gets the package's preload attribute which contains a given application ID.
1119         /// </summary>
1120         /// <param name="applicationId">ID of the application.</param>
1121         /// <returns>Returns true if the package is preloaded, otherwise false.</returns>
1122         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
1123         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1124         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1125         /// <since_tizen> 3 </since_tizen>
1126         public static bool IsPreloadPackageByApplicationId(string applicationId)
1127         {
1128             bool isPreloadPackage;
1129             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerIsPreloadPackageByApplicationId(applicationId, out isPreloadPackage);
1130             if (err != Interop.PackageManager.ErrorCode.None)
1131             {
1132                 throw PackageManagerErrorFactory.GetException(err, "Failed to get preload info");
1133             }
1134
1135             return isPreloadPackage;
1136         }
1137
1138         /// <summary>
1139         /// Compares the certificate of the two packages.
1140         /// </summary>
1141         /// <param name="lhsPackageId">Package ID to compare.</param>
1142         /// <param name="rhsPackageId">Package ID to be compared.</param>
1143         /// <returns>Returns certificate comparison result.</returns>
1144         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1145         /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal I/O error.</exception>
1146         /// <since_tizen> 3 </since_tizen>
1147         public static CertCompareResultType CompareCertInfo(string lhsPackageId, string rhsPackageId)
1148         {
1149             Interop.PackageManager.CertCompareResultType compareResult;
1150             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfo(lhsPackageId, rhsPackageId, out compareResult);
1151             if (err != Interop.PackageManager.ErrorCode.None)
1152             {
1153                 throw PackageManagerErrorFactory.GetException(err, "Failed to compare cert info");
1154             }
1155
1156             return (CertCompareResultType)compareResult;
1157         }
1158
1159         /// <summary>
1160         /// Compares the certificate of the two packages which contain each given application ID.
1161         /// </summary>
1162         /// <param name="lhsApplicationId">Application ID to compare.</param>
1163         /// <param name="rhsApplicationId">Application ID to be compared.</param>
1164         /// <returns>Returns certificate comparison result.</returns>
1165         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1166         /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal I/O error.</exception>
1167         /// <since_tizen> 3 </since_tizen>
1168         public static CertCompareResultType CompareCertInfoByApplicationId(string lhsApplicationId, string rhsApplicationId)
1169         {
1170             Interop.PackageManager.CertCompareResultType compareResult;
1171             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfoByApplicationId(lhsApplicationId, rhsApplicationId, out compareResult);
1172             if (err != Interop.PackageManager.ErrorCode.None)
1173             {
1174                 throw PackageManagerErrorFactory.GetException(err, "Failed to compare cert info by application id");
1175             }
1176
1177             return (CertCompareResultType)compareResult;
1178         }
1179
1180         /// <summary>
1181         /// Gets the package archive's information for the given archive path.
1182         /// </summary>
1183         /// <param name="archivePath">The path of the package archive.</param>
1184         /// <remarks>
1185         /// Regular 3rd party apps do not need to use this API
1186         /// </remarks>
1187         /// <returns>Returns the package archive information for the given archive path.</returns>
1188         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1189         /// <exception cref="System.IO.IOException">Thrown when the method fails due to an internal I/O error.</exception>
1190         /// <since_tizen> 6 </since_tizen>
1191         public static PackageArchive GetPackageArchive(string archivePath)
1192         {
1193             return PackageArchive.GetPackageArchive(archivePath);
1194         }
1195
1196         /// <summary>
1197         /// Drm nested class. This class has the PackageManager's drm related methods.
1198         /// </summary>
1199         /// <since_tizen> 3 </since_tizen>
1200         public static class Drm
1201         {
1202             /// <summary>
1203             /// Generates a request for getting the license.
1204             /// </summary>
1205             /// <param name="responseData">Response data string of the purchase request.</param>
1206             /// <returns>Returns the package DRM information of a given response data which contains the required data and license URL.</returns>
1207             /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1208             /// <privlevel>platform</privlevel>
1209             /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1210             /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1211             /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1212             /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
1213             /// <since_tizen> 3 </since_tizen>
1214             public static PackageDrm GenerateLicenseRequest(string responseData)
1215             {
1216                 return PackageDrm.GenerateLicenseRequest(responseData);
1217
1218             }
1219
1220             /// <summary>
1221             /// Registers the encrypted license.
1222             /// </summary>
1223             /// <param name="responseData">The response data string of the rights request.</param>
1224             /// <returns>Returns true if succeeds, otherwise false.</returns>
1225             /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1226             /// <privlevel>platform</privlevel>
1227             /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1228             /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1229             /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1230             /// <exception cref="SystemException">Thrown when the method failed due to internal system error.</exception>
1231             /// <since_tizen> 3 </since_tizen>
1232             public static bool RegisterLicense(string responseData)
1233             {
1234                 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmRegisterLicense(responseData);
1235                 if (err != Interop.PackageManager.ErrorCode.None)
1236                 {
1237                     throw PackageManagerErrorFactory.GetException(err, "Failed to register drm license");
1238                 }
1239
1240                 return true;
1241             }
1242
1243             /// <summary>
1244             /// Decrypts the contents which are encrypted.
1245             /// </summary>
1246             /// <param name="drmFilePath">Drm file path.</param>
1247             /// <param name="decryptedFilePath">Decrypted file path.</param>
1248             /// <returns>Returns true if succeeds, otherwise false.</returns>
1249             /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1250             /// <privlevel>platform</privlevel>
1251             /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1252             /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1253             /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1254             /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
1255             /// <since_tizen> 3 </since_tizen>
1256             public static bool DecryptPackage(string drmFilePath, string decryptedFilePath)
1257             {
1258                 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmDecryptPackage(drmFilePath, decryptedFilePath);
1259                 if (err != Interop.PackageManager.ErrorCode.None)
1260                 {
1261                     throw PackageManagerErrorFactory.GetException(err, "Failed to decrypt drm package");
1262                 }
1263
1264                 return true;
1265             }
1266         }
1267
1268         private static void SetPackageManagerEventStatus(Interop.PackageManager.EventStatus status)
1269         {
1270             if (Handle.IsInvalid) return;
1271
1272             Interop.PackageManager.EventStatus eventStatus = s_eventStatus;
1273             eventStatus |= status;
1274             if (eventStatus != Interop.PackageManager.EventStatus.All)
1275                 eventStatus |= Interop.PackageManager.EventStatus.Progress;
1276
1277             var err = Interop.PackageManager.ErrorCode.None;
1278             if (s_eventStatus != eventStatus)
1279             {
1280                 err = Interop.PackageManager.PackageManagerSetEventStatus(Handle, eventStatus);
1281                 if (err == Interop.PackageManager.ErrorCode.None)
1282                 {
1283                     s_eventStatus = eventStatus;
1284                     Log.Debug(LogTag, string.Format("New Event Status flag: {0}", s_eventStatus));
1285                     return;
1286                 }
1287                 Log.Debug(LogTag, string.Format("Failed to set flag for {0} event. err = {1}", eventStatus, err));
1288             }
1289         }
1290
1291         private static void UnsetPackageManagerEventStatus()
1292         {
1293             if (Handle.IsInvalid) return;
1294
1295             Interop.PackageManager.EventStatus eventStatus = Interop.PackageManager.EventStatus.All;
1296             if (s_installEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Install;
1297             if (s_uninstallEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Uninstall;
1298             if (s_updateEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Upgrade;
1299             if (s_moveEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Move;
1300             if (s_clearDataEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.ClearData;
1301             if (eventStatus != Interop.PackageManager.EventStatus.All)
1302                 eventStatus |= Interop.PackageManager.EventStatus.Progress;
1303
1304             var err = Interop.PackageManager.ErrorCode.None;
1305             if (s_eventStatus != eventStatus)
1306             {
1307                 err = Interop.PackageManager.PackageManagerSetEventStatus(Handle, eventStatus);
1308                 if (err == Interop.PackageManager.ErrorCode.None)
1309                 {
1310                     s_eventStatus = eventStatus;
1311                     Log.Debug(LogTag, string.Format("New Event Status flag: {0}", s_eventStatus));
1312                     return;
1313                 }
1314                 Log.Debug(LogTag, string.Format("Failed to set flag for {0} event. err = {1}", eventStatus, err));
1315             }
1316         }
1317
1318         private static void RegisterPackageManagerEventIfNeeded()
1319         {
1320             if (s_installEventHandler != null && s_uninstallEventHandler != null && s_updateEventHandler != null && s_moveEventHandler != null && s_clearDataEventHandler != null)
1321                 return;
1322
1323             var err = Interop.PackageManager.ErrorCode.None;
1324
1325             if (!Handle.IsInvalid)
1326             {
1327                 lock (Handle)
1328                 {
1329                     err = Interop.PackageManager.PackageManagerSetEvent(Handle, s_packageManagerEventCallback, IntPtr.Zero);
1330                 }
1331             }
1332             if (err != Interop.PackageManager.ErrorCode.None)
1333             {
1334                 Log.Warn(LogTag, string.Format("Failed to register callback for package manager event. err = {0}", err));
1335             }
1336         }
1337
1338         private static void InternalEventCallback(string packageType, string packageId, Interop.PackageManager.EventType eventType, Interop.PackageManager.PackageEventState eventState, int progress, Interop.PackageManager.ErrorCode error, IntPtr user_data)
1339         {
1340             PackageManagerEventArgs args;
1341             try
1342             {
1343                 args = new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress);
1344             }
1345             catch (Exception e)
1346             {
1347                 Log.Warn(LogTag, e.Message);
1348                 return;
1349             }
1350
1351             EventHandler<PackageManagerEventArgs> handlers = null;
1352             lock (s_pkgEventLock)
1353             {
1354                 if (eventType == Interop.PackageManager.EventType.Install)
1355                 {
1356                     handlers = s_installEventHandler;
1357                 }
1358                 else if (eventType == Interop.PackageManager.EventType.Uninstall)
1359                 {
1360                     handlers = s_uninstallEventHandler;
1361                 }
1362                 else if (eventType == Interop.PackageManager.EventType.Update)
1363                 {
1364                     handlers = s_updateEventHandler;
1365                 }
1366                 else if (eventType == Interop.PackageManager.EventType.Move)
1367                 {
1368                     handlers = s_moveEventHandler;
1369                 }
1370                 else if (eventType == Interop.PackageManager.EventType.ClearData)
1371                 {
1372                     handlers = s_clearDataEventHandler;
1373                 }
1374             }
1375
1376             handlers?.Invoke(null, args);
1377         }
1378
1379         private static void UnregisterPackageManagerEventIfNeeded()
1380         {
1381             if (s_packageManagerEventCallback == null || s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null || s_moveEventHandler != null || s_clearDataEventHandler != null)
1382             {
1383                 return;
1384             }
1385
1386             lock (Handle)
1387             {
1388                 var err = Interop.PackageManager.PackageManagerUnsetEvent(Handle);
1389                 if (err != Interop.PackageManager.ErrorCode.None)
1390                 {
1391                     throw PackageManagerErrorFactory.GetException(err, "Failed to unregister package manager event event.");
1392                 }
1393             }
1394         }
1395     }
1396
1397     internal static class PackageManagerErrorFactory
1398     {
1399         internal static Exception GetException(Interop.PackageManager.ErrorCode err, string message)
1400         {
1401             string errMessage = string.Format("{0} err = {1}", message, err);
1402             switch (err)
1403             {
1404                 case Interop.PackageManager.ErrorCode.InvalidParameter:
1405                 case Interop.PackageManager.ErrorCode.NoSuchPackage:
1406                     return new ArgumentException(errMessage);
1407                 case Interop.PackageManager.ErrorCode.PermissionDenied:
1408                     return new UnauthorizedAccessException(errMessage);
1409                 case Interop.PackageManager.ErrorCode.IoError:
1410                     return new global::System.IO.IOException(errMessage);
1411                 default:
1412                     return new InvalidOperationException(errMessage);
1413             }
1414         }
1415     }
1416 }