d6b57a324a771718046aa20f404ded52991fab50
[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         /// Retrieves the package information of all installed packages.
357         /// </summary>
358         /// <returns>Returns the list of packages.</returns>
359         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
360         /// <since_tizen> 3 </since_tizen>
361         public static IEnumerable<Package> GetPackages()
362         {
363             return GetPackages(null);
364         }
365
366         /// <summary>
367         /// Retrieves the package information of all the installed packages satisfying the filter conditions.
368         /// </summary>
369         /// <param name="filter">Optional - package filters.</param>
370         /// <returns>Returns the list of packages.</returns>
371         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
372         /// <since_tizen> 3 </since_tizen>
373         public static IEnumerable<Package> GetPackages(PackageFilter filter)
374         {
375             List<Package> packageList = new List<Package>();
376
377             IntPtr filterHandle;
378             var err = Interop.PackageManager.PackageManagerFilterCreate(out filterHandle);
379             if (err != Interop.PackageManager.ErrorCode.None)
380             {
381                 Log.Warn(LogTag, string.Format("Failed to create package filter handle. err = {0}", err));
382                 return packageList;
383             }
384
385             if (filter != null && filter.Filters != null)
386             {
387                 foreach (KeyValuePair<string, bool> entry in filter?.Filters)
388                 {
389                     err = Interop.PackageManager.PackageManagerFilterAdd(filterHandle, entry.Key, entry.Value);
390                     if (err != Interop.PackageManager.ErrorCode.None)
391                     {
392                         Log.Warn(LogTag, string.Format("Failed to configure package filter. err = {0}", err));
393                         break;
394                     }
395                 }
396             }
397
398             if (err == Interop.PackageManager.ErrorCode.None)
399             {
400                 Interop.PackageManager.PackageManagerPackageInfoCallback cb = (handle, userData) =>
401                 {
402                     packageList.Add(Package.GetPackage(handle));
403                     return true;
404                 };
405
406                 err = Interop.PackageManager.PackageManagerFilterForeachPackageInfo(filterHandle, cb, IntPtr.Zero);
407                 if (err != Interop.PackageManager.ErrorCode.None)
408                 {
409                     Log.Warn(LogTag, string.Format("Failed to get package Informations. err = {0}", err));
410                 }
411             }
412
413             err = Interop.PackageManager.PackageManagerFilterDestroy(filterHandle);
414             if (err != Interop.PackageManager.ErrorCode.None)
415             {
416                 Log.Warn(LogTag, string.Format("Failed to destroy package filter handle. err = {0}", err));
417             }
418             return packageList;
419         }
420
421         /// <summary>
422         /// Gets the total package size information.
423         /// </summary>
424         /// <returns>Returns the total package size information asynchronously.</returns>
425         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
426         /// <since_tizen> 3 </since_tizen>
427         public static async Task<PackageSizeInformation> GetTotalSizeInformationAsync()
428         {
429             TaskCompletionSource<PackageSizeInformation> tcs = new TaskCompletionSource<PackageSizeInformation>();
430
431             Interop.PackageManager.PackageManagerTotalSizeInfoCallback cb = (handle, userData) =>
432             {
433                 if (handle != IntPtr.Zero)
434                 {
435                     tcs.TrySetResult(PackageSizeInformation.GetPackageSizeInformation(handle));
436                 }
437
438                 lock (s_totalSizeInfoCallbackDict)
439                 {
440                     s_totalSizeInfoCallbackDict.Remove(userData);
441                 }
442             };
443
444             IntPtr callbackId;
445             lock (s_totalSizeInfoCallbackDict)
446             {
447                 callbackId = (IntPtr)s_callbackId++;
448                 s_totalSizeInfoCallbackDict[callbackId] = cb;
449             }
450
451             var err = Interop.PackageManager.PackageManagerGetTotalSizeInfo(cb, callbackId);
452             if (err != Interop.PackageManager.ErrorCode.None)
453             {
454                 tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info"));
455             }
456             return await tcs.Task.ConfigureAwait(false);
457         }
458
459         /// <summary>
460         /// Installs the package located at the given path.
461         /// </summary>
462         /// <param name="packagePath">Absolute path for the package to be installed.</param>
463         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
464         /// <returns>Returns true if the installation request is successful, otherwise false.</returns>
465         /// <remarks>
466         /// The 'true' means that the request for installation is successful.
467         /// To check the result of the installation, the caller should check the progress using the InstallProgressChanged event.
468         /// </remarks>
469         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
470         /// <privlevel>platform</privlevel>
471         /// <since_tizen> 3 </since_tizen>
472         public static bool Install(string packagePath, InstallationMode installMode = InstallationMode.Normal)
473         {
474             return Install(packagePath, null, PackageType.UNKNOWN, null, installMode);
475         }
476
477         /// <summary>
478         /// Installs the package located at the given path.
479         /// </summary>
480         /// <param name="packagePath">Absolute path for the package to be installed.</param>
481         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
482         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
483         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
484         /// <remarks>
485         /// The 'true' means that the request for installation is successful.
486         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
487         /// </remarks>
488         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
489         /// <privlevel>platform</privlevel>
490         /// <since_tizen> 3 </since_tizen>
491         public static bool Install(string packagePath, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
492         {
493             return Install(packagePath, null, PackageType.UNKNOWN, eventCallback, installMode);
494         }
495
496         /// <summary>
497         /// Installs the package located at the given path.
498         /// </summary>
499         /// <param name="packagePath">Absolute path for the package to be installed.</param>
500         /// <param name="type">Package type for the package to be installed.</param>
501         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
502         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
503         /// <remarks>
504         /// The 'true' means that the request for installation is successful.
505         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
506         /// </remarks>
507         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
508         /// <privlevel>platform</privlevel>
509         /// <since_tizen> 3 </since_tizen>
510         public static bool Install(string packagePath, PackageType type, InstallationMode installMode = InstallationMode.Normal)
511         {
512             return Install(packagePath, null, type, null, installMode);
513         }
514
515         /// <summary>
516         /// Installs the package located at the given path.
517         /// </summary>
518         /// <param name="packagePath">Absolute path for the package to be installed.</param>
519         /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
520         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
521         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
522         /// <remarks>
523         /// The 'true' means that the request for installation is successful.
524         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
525         /// </remarks>
526         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
527         /// <privlevel>platform</privlevel>
528         /// <since_tizen> 3 </since_tizen>
529         public static bool Install(string packagePath, string expansionPackagePath, InstallationMode installMode = InstallationMode.Normal)
530         {
531             return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, null, installMode);
532         }
533
534         /// <summary>
535         /// Installs the package located at the given path.
536         /// </summary>
537         /// <param name="packagePath">Absolute path for the package to be installed.</param>
538         /// <param name="type">Package type for the package to be installed.</param>
539         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
540         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
541         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
542         /// <remarks>
543         /// The 'true' means that the request for installation is successful.
544         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
545         /// </remarks>
546         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
547         /// <privlevel>platform</privlevel>
548         /// <since_tizen> 3 </since_tizen>
549         public static bool Install(string packagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
550         {
551             return Install(packagePath, null, type, eventCallback, installMode);
552         }
553
554         /// <summary>
555         /// Installs the package located at the given path.
556         /// </summary>
557         /// <param name="packagePath">Absolute path for the package to be installed.</param>
558         /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
559         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
560         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
561         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
562         /// <remarks>
563         /// The 'true' means that the request for installation is successful.
564         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
565         /// </remarks>
566         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
567         /// <privlevel>platform</privlevel>
568         /// <since_tizen> 3 </since_tizen>
569         public static bool Install(string packagePath, string expansionPackagePath, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
570         {
571             return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, eventCallback, installMode);
572         }
573
574         /// <summary>
575         /// Installs the package located at the given path.
576         /// </summary>
577         /// <param name="packagePath">Absolute path for the package to be installed.</param>
578         /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
579         /// <param name="type">Package type for the package to be installed.</param>
580         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
581         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
582         /// <remarks>
583         /// The 'true' means that the request for installation is successful.
584         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
585         /// </remarks>
586         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
587         /// <privlevel>platform</privlevel>
588         /// <since_tizen> 3 </since_tizen>
589         public static bool Install(string packagePath, string expansionPackagePath, PackageType type, InstallationMode installMode = InstallationMode.Normal)
590         {
591             return Install(packagePath, expansionPackagePath, type, null, installMode);
592         }
593
594         /// <summary>
595         /// Installs the package located at the given path.
596         /// </summary>
597         /// <param name="packagePath">Absolute path for the package to be installed.</param>
598         /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
599         /// <param name="type">Package type for the package to be installed.</param>
600         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
601         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
602         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
603         /// <remarks>
604         /// The 'true' means that the request for installation is successful.
605         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
606         /// </remarks>
607         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
608         /// <privlevel>platform</privlevel>
609         /// <since_tizen> 3 </since_tizen>
610         public static bool Install(string packagePath, string expansionPackagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
611         {
612             return InstallInternal(new List<string>{ packagePath }, expansionPackagePath, type, eventCallback, installMode);
613         }
614
615         /// <summary>
616         /// Installs the packages located at the given path.
617         /// </summary>
618         /// <param name="packagePaths">Absolute paths for the package to be installed.</param>
619         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
620         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
621         /// <remarks>
622         /// The 'true' means that the request for installation is successful.
623         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
624         /// </remarks>
625         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
626         /// <privlevel>platform</privlevel>
627         /// <since_tizen> 8 </since_tizen>
628         public static bool Install(List<string> packagePaths, InstallationMode installMode = InstallationMode.Normal)
629         {
630             return InstallInternal(packagePaths, null, PackageType.UNKNOWN, null, installMode);
631         }
632
633         /// <summary>
634         /// Installs the packages located at the given path.
635         /// </summary>
636         /// <param name="packagePaths">Absolute paths for the package to be installed.</param>
637         /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
638         /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
639         /// <returns>Returns true if installation request is successful, false otherwise.</returns>
640         /// <remarks>
641         /// The 'true' means that the request for installation is successful.
642         /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
643         /// </remarks>
644         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
645         /// <privlevel>platform</privlevel>
646         /// <since_tizen> 8 </since_tizen>
647         public static bool Install(List<string> packagePaths, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
648         {
649             return InstallInternal(packagePaths, null, PackageType.UNKNOWN, eventCallback, installMode);
650         }
651
652         private static bool InstallInternal(List<string> packagePaths, string expansionPackagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode)
653         {
654             if (packagePaths == null || !packagePaths.Any())
655             {
656                 Log.Warn(LogTag, string.Format("Invalid argument"));
657                 return false;
658             }
659
660             SafePackageManagerRequestHandle RequestHandle;
661             var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
662             if (err != Interop.PackageManager.ErrorCode.None)
663             {
664                 Log.Warn(LogTag, string.Format("Failed to install packages. Error in creating package manager request handle. err = {0}", err));
665                 return false;
666             }
667
668             try
669             {
670                 if (type != PackageType.UNKNOWN)
671                 {
672                     err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
673                     if (err != Interop.PackageManager.ErrorCode.None)
674                     {
675                         Log.Warn(LogTag, string.Format("Failed to install packages. Error in setting request package type. err = {0}", err));
676                         RequestHandle.Dispose();
677                         return false;
678                     }
679                 }
680
681                 if (!string.IsNullOrEmpty(expansionPackagePath))
682                 {
683                     err = Interop.PackageManager.PackageManagerRequestSetTepPath(RequestHandle, expansionPackagePath);
684                     if (err != Interop.PackageManager.ErrorCode.None)
685                     {
686                         Log.Warn(LogTag, string.Format("Failed to install package. Error in setting request package mode. err = {0}", err));
687                         RequestHandle.Dispose();
688                         return false;
689                     }
690                 }
691
692                 int requestId;
693                 if (eventCallback != null)
694                 {
695                     if (packagePaths.Count > 1)
696                     {
697                         InstallPackagesMethodWithCallback installPackages;
698                         if (installMode == InstallationMode.Mount)
699                         {
700                             installPackages = Interop.PackageManager.PackageManagerRequestMountInstallPackagesWithCb;
701                         }
702                         else
703                         {
704                             installPackages = Interop.PackageManager.PackageManagerRequestInstallPackagesWithCb;
705                         }
706                         err = installPackages(RequestHandle, packagePaths.ToArray(), packagePaths.Count, internalRequestEventCallback, IntPtr.Zero, out requestId);
707                         if (err == Interop.PackageManager.ErrorCode.None)
708                         {
709                             RequestCallbacks.Add(requestId, eventCallback);
710                             RequestHandles.Add(requestId, RequestHandle);
711                             RequestPackageCount.Add(requestId, packagePaths.Count);
712                         }
713                         else
714                         {
715                             Log.Warn(LogTag, string.Format("Failed to install packages. err = {0}",  err));
716                             RequestHandle.Dispose();
717                             return false;
718                         }
719                     }
720                     else
721                     {
722                         InstallMethodWithCallback install;
723                         if (installMode == InstallationMode.Mount)
724                         {
725                             install = Interop.PackageManager.PackageManagerRequestMountInstallWithCB;
726                         }
727                         else
728                         {
729                             install = Interop.PackageManager.PackageManagerRequestInstallWithCB;
730                         }
731                         err = install(RequestHandle, packagePaths[0], internalRequestEventCallback, IntPtr.Zero, out requestId);
732                         if (err == Interop.PackageManager.ErrorCode.None)
733                         {
734                             RequestCallbacks.Add(requestId, eventCallback);
735                             RequestHandles.Add(requestId, RequestHandle);
736                             RequestPackageCount.Add(requestId, packagePaths.Count);
737
738                         }
739                         else
740                         {
741                             Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePaths, err));
742                             RequestHandle.Dispose();
743                             return false;
744                         }
745
746                     }
747
748                 }
749                 else
750                 {
751                     if (packagePaths.Count > 1)
752                     {
753                         InstallPackagesMethod installPackages;
754                         if (installMode == InstallationMode.Mount)
755                         {
756                             installPackages = Interop.PackageManager.PackageManagerRequestMountInstallPackages;
757                         }
758                         else
759                         {
760                             installPackages = Interop.PackageManager.PackageManagerRequestInstallPackages;
761                         }
762                         err = installPackages(RequestHandle, packagePaths.ToArray(), packagePaths.Count, out requestId);
763                         if (err != Interop.PackageManager.ErrorCode.None)
764                         {
765                             Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePaths, err));
766                             RequestHandle.Dispose();
767                             return false;
768                         }
769                     }
770                     else
771                     {
772                         InstallMethod install;
773                         if (installMode == InstallationMode.Mount)
774                         {
775                             install = Interop.PackageManager.PackageManagerRequestMountInstall;
776                         }
777                         else
778                         {
779                             install = Interop.PackageManager.PackageManagerRequestInstall;
780                         }
781                         err = install(RequestHandle, packagePaths[0], out requestId);
782                         if (err != Interop.PackageManager.ErrorCode.None)
783                         {
784                             Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePaths, err));
785                             RequestHandle.Dispose();
786                             return false;
787                         }
788                     }
789
790                     // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
791                     RequestHandle.Dispose();
792                 }
793                 return true;
794             }
795             catch (Exception e)
796             {
797                 Log.Warn(LogTag, e.Message);
798                 RequestHandle.Dispose();
799                 return false;
800             }
801         }
802
803         /// <summary>
804         /// Uninstalls the package with the given name.
805         /// </summary>
806         /// <param name="packageId">ID of the package to be uninstalled.</param>
807         /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
808         /// <remarks>
809         /// The 'true' means that the request for uninstallation is successful.
810         /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event.
811         /// </remarks>
812         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
813         /// <privlevel>platform</privlevel>
814         /// <since_tizen> 3 </since_tizen>
815         public static bool Uninstall(string packageId)
816         {
817             return Uninstall(packageId, PackageType.UNKNOWN, null);
818         }
819
820         /// <summary>
821         /// Uninstalls package with the given names.
822         /// </summary>
823         /// <param name="packageId">ID of the package to be uninstalled.</param>
824         /// <param name="type">Optional - Package type for the package to be uninstalled.</param>
825         /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
826         /// <remarks>
827         /// The 'true' means that the request for uninstallation is successful.
828         /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event.
829         /// </remarks>
830         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
831         /// <privlevel>platform</privlevel>
832         /// <since_tizen> 3 </since_tizen>
833         public static bool Uninstall(string packageId, PackageType type)
834         {
835             return Uninstall(packageId, type, null);
836         }
837
838         /// <summary>
839         /// Uninstalls the package with the given name.
840         /// </summary>
841         /// <param name="packageId">ID of the package to be uninstalled.</param>
842         /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</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 or eventCallback.
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, RequestEventCallback eventCallback)
852         {
853             return Uninstall(packageId, PackageType.UNKNOWN, eventCallback);
854         }
855
856         /// <summary>
857         /// Uninstalls the package with the given name.
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         /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
862         /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
863         /// <remarks>
864         /// The 'true' means that the request for uninstallation is successful.
865         /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event or eventCallback.
866         /// </remarks>
867         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
868         /// <privlevel>platform</privlevel>
869         /// <since_tizen> 3 </since_tizen>
870         public static bool Uninstall(string packageId, PackageType type, RequestEventCallback eventCallback)
871         {
872             SafePackageManagerRequestHandle RequestHandle;
873             var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
874             if (err != Interop.PackageManager.ErrorCode.None)
875             {
876                 Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. Error in creating package manager request handle. err = {1}", packageId, err));
877                 return false;
878             }
879
880             try
881             {
882                 err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
883                 if (err != Interop.PackageManager.ErrorCode.None)
884                 {
885                     Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. Error in setting request package type. err = {1}", packageId, err));
886                     RequestHandle.Dispose();
887                     return false;
888                 }
889
890                 int requestId;
891                 if (eventCallback != null)
892                 {
893                     err = Interop.PackageManager.PackageManagerRequestUninstallWithCB(RequestHandle, packageId, internalRequestEventCallback, IntPtr.Zero, out requestId);
894                     if (err == Interop.PackageManager.ErrorCode.None)
895                     {
896                         RequestCallbacks.Add(requestId, eventCallback);
897                         RequestHandles.Add(requestId, RequestHandle);
898                         RequestPackageCount.Add(requestId, 1);
899                     }
900                     else
901                     {
902                         Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. err = {1}", packageId, err));
903                         RequestHandle.Dispose();
904                         return false;
905                     }
906                 }
907                 else
908                 {
909                     err = Interop.PackageManager.PackageManagerRequestUninstall(RequestHandle, packageId, out requestId);
910                     if (err != Interop.PackageManager.ErrorCode.None)
911                     {
912                         Log.Warn(LogTag, string.Format("Failed to uninstall package. err = {0}", err));
913                         RequestHandle.Dispose();
914                         return false;
915                     }
916                     // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
917                     RequestHandle.Dispose();
918                 }
919                 return true;
920             }
921             catch (Exception e)
922             {
923                 Log.Warn(LogTag, e.Message);
924                 RequestHandle.Dispose();
925                 return false;
926             }
927         }
928
929         /// <summary>
930         /// Moves the package to the given storage.
931         /// </summary>
932         /// <param name="packageId">ID of the package to be moved.</param>
933         /// <param name="newStorage">Storage package should be moved to.</param>
934         /// <returns>Returns true if the move request is successful, false otherwise.</returns>
935         /// <remarks>
936         /// The 'true' means that the request for move is successful.
937         /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
938         /// </remarks>
939         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
940         /// <privlevel>platform</privlevel>
941         /// <since_tizen> 3 </since_tizen>
942         public static bool Move(string packageId, StorageType newStorage)
943         {
944             return Move(packageId, PackageType.UNKNOWN, newStorage, null);
945         }
946
947         /// <summary>
948         /// Moves the package to the given storage.
949         /// </summary>
950         /// <param name="packageId">ID of the package to be moved.</param>
951         /// <param name="type">Optional - Package type for the package to be moved.</param>
952         /// <param name="newStorage">Storage package should be moved to.</param>
953         /// <returns>Returns true if the move request is successful, false otherwise.</returns>
954         /// <remarks>
955         /// The 'true' means that the request for move is successful.
956         /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
957         /// </remarks>
958         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
959         /// <privlevel>platform</privlevel>
960         /// <since_tizen> 3 </since_tizen>
961         public static bool Move(string packageId, PackageType type, StorageType newStorage)
962         {
963             return Move(packageId, type, newStorage, null);
964         }
965
966         /// <summary>
967         /// Moves the package to the given storage.
968         /// </summary>
969         /// <param name="packageId">ID of the package to be moved.</param>
970         /// <param name="newStorage">Storage package should be moved to.</param>
971         /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
972         /// <returns>Returns true if move request is successful, false otherwise.</returns>
973         /// <remarks>
974         /// The 'true' means that the request for move is successful.
975         /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
976         /// </remarks>
977         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
978         /// <privlevel>platform</privlevel>
979         /// <since_tizen> 3 </since_tizen>
980         public static bool Move(string packageId, StorageType newStorage, RequestEventCallback eventCallback)
981         {
982             return Move(packageId, PackageType.UNKNOWN, newStorage, eventCallback);
983         }
984
985         /// <summary>
986         /// Moves the package to the given storage.
987         /// </summary>
988         /// <param name="packageId">ID of the package to be moved.</param>
989         /// <param name="type">Optional - Package type for the package to be moved.</param>
990         /// <param name="newStorage">Storage, package should be moved to.</param>
991         /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
992         /// <returns>Returns true if move request is successful, false otherwise.</returns>
993         /// <remarks>
994         /// The 'true' means that the request for move is successful.
995         /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
996         /// </remarks>
997         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
998         /// <privlevel>platform</privlevel>
999         /// <since_tizen> 3 </since_tizen>
1000         public static bool Move(string packageId, PackageType type, StorageType newStorage, RequestEventCallback eventCallback)
1001         {
1002             SafePackageManagerRequestHandle RequestHandle;
1003             var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
1004             if (err != Interop.PackageManager.ErrorCode.None)
1005             {
1006                 Log.Warn(LogTag, string.Format("Failed to create package manager request handle. err = {0}", err));
1007                 return false;
1008             }
1009
1010             try
1011             {
1012                 bool result = true;
1013                 err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
1014                 if (err != Interop.PackageManager.ErrorCode.None)
1015                 {
1016                     Log.Warn(LogTag, string.Format("Failed to move package. Error in setting request package type. err = {0}", err));
1017                     RequestHandle.Dispose();
1018                     return false;
1019                 }
1020
1021                 if (eventCallback != null)
1022                 {
1023                     int requestId;
1024                     err = Interop.PackageManager.PackageManagerRequestMoveWithCB(RequestHandle, packageId, (Interop.PackageManager.StorageType)newStorage, internalRequestEventCallback, IntPtr.Zero, out requestId);
1025                     if (err == Interop.PackageManager.ErrorCode.None)
1026                     {
1027                         RequestCallbacks.Add(requestId, eventCallback);
1028                         RequestHandles.Add(requestId, RequestHandle);
1029                         RequestPackageCount.Add(requestId, 1);
1030                     }
1031                     else
1032                     {
1033                         Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
1034                         RequestHandle.Dispose();
1035                         result = false;
1036                     }
1037                 }
1038                 else
1039                 {
1040                     err = Interop.PackageManager.PackageManagerRequestMove(RequestHandle, packageId, (Interop.PackageManager.StorageType)newStorage);
1041                     if (err != Interop.PackageManager.ErrorCode.None)
1042                     {
1043                         Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
1044                         RequestHandle.Dispose();
1045                         result = false;
1046                     }
1047                     // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
1048                     RequestHandle.Dispose();
1049                 }
1050                 return result;
1051             }
1052             catch (Exception e)
1053             {
1054                 Log.Warn(LogTag, e.Message);
1055                 RequestHandle.Dispose();
1056                 return false;
1057             }
1058         }
1059
1060         /// <summary>
1061         /// Gets the permission type of the package which has a given application ID.
1062         /// </summary>
1063         /// <param name="applicationId">ID of the application.</param>
1064         /// <returns>Returns the permission type.</returns>
1065         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
1066         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1067         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1068         /// <since_tizen> 3 </since_tizen>
1069         public static PermissionType GetPermissionTypeByApplicationId(string applicationId)
1070         {
1071             Interop.PackageManager.PackageManagerPermissionType permissionType;
1072             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetPermissionType(applicationId, out permissionType);
1073             if (err != Interop.PackageManager.ErrorCode.None)
1074             {
1075                 throw PackageManagerErrorFactory.GetException(err, "Failed to get permission type.");
1076             }
1077
1078             return (PermissionType)permissionType;
1079         }
1080
1081         /// <summary>
1082         /// Gets the package's preload attribute which contains a given application ID.
1083         /// </summary>
1084         /// <param name="applicationId">ID of the application.</param>
1085         /// <returns>Returns true if the package is preloaded, otherwise false.</returns>
1086         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
1087         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1088         /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1089         /// <since_tizen> 3 </since_tizen>
1090         public static bool IsPreloadPackageByApplicationId(string applicationId)
1091         {
1092             bool isPreloadPackage;
1093             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerIsPreloadPackageByApplicationId(applicationId, out isPreloadPackage);
1094             if (err != Interop.PackageManager.ErrorCode.None)
1095             {
1096                 throw PackageManagerErrorFactory.GetException(err, "Failed to get preload info");
1097             }
1098
1099             return isPreloadPackage;
1100         }
1101
1102         /// <summary>
1103         /// Compares the certificate of the two packages.
1104         /// </summary>
1105         /// <param name="lhsPackageId">Package ID to compare.</param>
1106         /// <param name="rhsPackageId">Package ID to be compared.</param>
1107         /// <returns>Returns certificate comparison result.</returns>
1108         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1109         /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal I/O error.</exception>
1110         /// <since_tizen> 3 </since_tizen>
1111         public static CertCompareResultType CompareCertInfo(string lhsPackageId, string rhsPackageId)
1112         {
1113             Interop.PackageManager.CertCompareResultType compareResult;
1114             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfo(lhsPackageId, rhsPackageId, out compareResult);
1115             if (err != Interop.PackageManager.ErrorCode.None)
1116             {
1117                 throw PackageManagerErrorFactory.GetException(err, "Failed to compare cert info");
1118             }
1119
1120             return (CertCompareResultType)compareResult;
1121         }
1122
1123         /// <summary>
1124         /// Compares the certificate of the two packages which contain each given application ID.
1125         /// </summary>
1126         /// <param name="lhsApplicationId">Application ID to compare.</param>
1127         /// <param name="rhsApplicationId">Application ID to be compared.</param>
1128         /// <returns>Returns certificate comparison result.</returns>
1129         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1130         /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal I/O error.</exception>
1131         /// <since_tizen> 3 </since_tizen>
1132         public static CertCompareResultType CompareCertInfoByApplicationId(string lhsApplicationId, string rhsApplicationId)
1133         {
1134             Interop.PackageManager.CertCompareResultType compareResult;
1135             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfoByApplicationId(lhsApplicationId, rhsApplicationId, out compareResult);
1136             if (err != Interop.PackageManager.ErrorCode.None)
1137             {
1138                 throw PackageManagerErrorFactory.GetException(err, "Failed to compare cert info by application id");
1139             }
1140
1141             return (CertCompareResultType)compareResult;
1142         }
1143
1144         /// <summary>
1145         /// Gets the package archive's information for the given archive path.
1146         /// </summary>
1147         /// <param name="archivePath">The path of the package archive.</param>
1148         /// <remarks>
1149         /// Regular 3rd party apps do not need to use this API
1150         /// </remarks>
1151         /// <returns>Returns the package archive information for the given archive path.</returns>
1152         /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
1153         /// <exception cref="System.IO.IOException">Thrown when the method fails due to an internal I/O error.</exception>
1154         /// <since_tizen> 6 </since_tizen>
1155         public static PackageArchive GetPackageArchive(string archivePath)
1156         {
1157             return PackageArchive.GetPackageArchive(archivePath);
1158         }
1159
1160         /// <summary>
1161         /// Drm nested class. This class has the PackageManager's drm related methods.
1162         /// </summary>
1163         /// <since_tizen> 3 </since_tizen>
1164         public static class Drm
1165         {
1166             /// <summary>
1167             /// Generates a request for getting the license.
1168             /// </summary>
1169             /// <param name="responseData">Response data string of the purchase request.</param>
1170             /// <returns>Returns the package DRM information of a given response data which contains the required data and license URL.</returns>
1171             /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1172             /// <privlevel>platform</privlevel>
1173             /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1174             /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1175             /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1176             /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
1177             /// <since_tizen> 3 </since_tizen>
1178             public static PackageDrm GenerateLicenseRequest(string responseData)
1179             {
1180                 return PackageDrm.GenerateLicenseRequest(responseData);
1181
1182             }
1183
1184             /// <summary>
1185             /// Registers the encrypted license.
1186             /// </summary>
1187             /// <param name="responseData">The response data string of the rights request.</param>
1188             /// <returns>Returns true if succeeds, otherwise false.</returns>
1189             /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1190             /// <privlevel>platform</privlevel>
1191             /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1192             /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1193             /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1194             /// <exception cref="SystemException">Thrown when the method failed due to internal system error.</exception>
1195             /// <since_tizen> 3 </since_tizen>
1196             public static bool RegisterLicense(string responseData)
1197             {
1198                 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmRegisterLicense(responseData);
1199                 if (err != Interop.PackageManager.ErrorCode.None)
1200                 {
1201                     throw PackageManagerErrorFactory.GetException(err, "Failed to register drm license");
1202                 }
1203
1204                 return true;
1205             }
1206
1207             /// <summary>
1208             /// Decrypts the contents which are encrypted.
1209             /// </summary>
1210             /// <param name="drmFilePath">Drm file path.</param>
1211             /// <param name="decryptedFilePath">Decrypted file path.</param>
1212             /// <returns>Returns true if succeeds, otherwise false.</returns>
1213             /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1214             /// <privlevel>platform</privlevel>
1215             /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1216             /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1217             /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1218             /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
1219             /// <since_tizen> 3 </since_tizen>
1220             public static bool DecryptPackage(string drmFilePath, string decryptedFilePath)
1221             {
1222                 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmDecryptPackage(drmFilePath, decryptedFilePath);
1223                 if (err != Interop.PackageManager.ErrorCode.None)
1224                 {
1225                     throw PackageManagerErrorFactory.GetException(err, "Failed to decrypt drm package");
1226                 }
1227
1228                 return true;
1229             }
1230         }
1231
1232         private static void SetPackageManagerEventStatus(Interop.PackageManager.EventStatus status)
1233         {
1234             if (Handle.IsInvalid) return;
1235
1236             Interop.PackageManager.EventStatus eventStatus = s_eventStatus;
1237             eventStatus |= status;
1238             if (eventStatus != Interop.PackageManager.EventStatus.All)
1239                 eventStatus |= Interop.PackageManager.EventStatus.Progress;
1240
1241             var err = Interop.PackageManager.ErrorCode.None;
1242             if (s_eventStatus != eventStatus)
1243             {
1244                 err = Interop.PackageManager.PackageManagerSetEventStatus(Handle, eventStatus);
1245                 if (err == Interop.PackageManager.ErrorCode.None)
1246                 {
1247                     s_eventStatus = eventStatus;
1248                     Log.Debug(LogTag, string.Format("New Event Status flag: {0}", s_eventStatus));
1249                     return;
1250                 }
1251                 Log.Debug(LogTag, string.Format("Failed to set flag for {0} event. err = {1}", eventStatus, err));
1252             }
1253         }
1254
1255         private static void UnsetPackageManagerEventStatus()
1256         {
1257             if (Handle.IsInvalid) return;
1258
1259             Interop.PackageManager.EventStatus eventStatus = Interop.PackageManager.EventStatus.All;
1260             if (s_installEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Install;
1261             if (s_uninstallEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Uninstall;
1262             if (s_updateEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Upgrade;
1263             if (s_moveEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Move;
1264             if (s_clearDataEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.ClearData;
1265             if (eventStatus != Interop.PackageManager.EventStatus.All)
1266                 eventStatus |= Interop.PackageManager.EventStatus.Progress;
1267
1268             var err = Interop.PackageManager.ErrorCode.None;
1269             if (s_eventStatus != eventStatus)
1270             {
1271                 err = Interop.PackageManager.PackageManagerSetEventStatus(Handle, eventStatus);
1272                 if (err == Interop.PackageManager.ErrorCode.None)
1273                 {
1274                     s_eventStatus = eventStatus;
1275                     Log.Debug(LogTag, string.Format("New Event Status flag: {0}", s_eventStatus));
1276                     return;
1277                 }
1278                 Log.Debug(LogTag, string.Format("Failed to set flag for {0} event. err = {1}", eventStatus, err));
1279             }
1280         }
1281
1282         private static void RegisterPackageManagerEventIfNeeded()
1283         {
1284             if (s_installEventHandler != null && s_uninstallEventHandler != null && s_updateEventHandler != null && s_moveEventHandler != null && s_clearDataEventHandler != null)
1285                 return;
1286
1287             var err = Interop.PackageManager.ErrorCode.None;
1288
1289             if (!Handle.IsInvalid)
1290             {
1291                 lock (Handle)
1292                 {
1293                     Log.Debug(LogTag, "Reset Package Event");
1294                     err = Interop.PackageManager.PackageManagerUnsetEvent(Handle);
1295                     if (err != Interop.PackageManager.ErrorCode.None)
1296                     {
1297                         throw PackageManagerErrorFactory.GetException(err, "Failed to unregister package manager event event.");
1298                     }
1299
1300                     err = Interop.PackageManager.PackageManagerSetEvent(Handle, s_packageManagerEventCallback, IntPtr.Zero);
1301                 }
1302             }
1303             if (err != Interop.PackageManager.ErrorCode.None)
1304             {
1305                 Log.Warn(LogTag, string.Format("Failed to register callback for package manager event. err = {0}", err));
1306             }
1307         }
1308
1309         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)
1310         {
1311             PackageManagerEventArgs args;
1312             try
1313             {
1314                 args = new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress);
1315             }
1316             catch (Exception e)
1317             {
1318                 Log.Warn(LogTag, e.Message);
1319                 return;
1320             }
1321
1322             EventHandler<PackageManagerEventArgs> handlers = null;
1323             lock (s_pkgEventLock)
1324             {
1325                 if (eventType == Interop.PackageManager.EventType.Install)
1326                 {
1327                     handlers = s_installEventHandler;
1328                 }
1329                 else if (eventType == Interop.PackageManager.EventType.Uninstall)
1330                 {
1331                     handlers = s_uninstallEventHandler;
1332                 }
1333                 else if (eventType == Interop.PackageManager.EventType.Update)
1334                 {
1335                     handlers = s_updateEventHandler;
1336                 }
1337                 else if (eventType == Interop.PackageManager.EventType.Move)
1338                 {
1339                     handlers = s_moveEventHandler;
1340                 }
1341                 else if (eventType == Interop.PackageManager.EventType.ClearData)
1342                 {
1343                     handlers = s_clearDataEventHandler;
1344                 }
1345             }
1346
1347             handlers?.Invoke(null, args);
1348         }
1349
1350         private static void UnregisterPackageManagerEventIfNeeded()
1351         {
1352             if (s_packageManagerEventCallback == null || s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null || s_moveEventHandler != null || s_clearDataEventHandler != null)
1353             {
1354                 return;
1355             }
1356
1357             lock (Handle)
1358             {
1359                 var err = Interop.PackageManager.PackageManagerUnsetEvent(Handle);
1360                 if (err != Interop.PackageManager.ErrorCode.None)
1361                 {
1362                     throw PackageManagerErrorFactory.GetException(err, "Failed to unregister package manager event event.");
1363                 }
1364             }
1365         }
1366     }
1367
1368     internal static class PackageManagerErrorFactory
1369     {
1370         internal static Exception GetException(Interop.PackageManager.ErrorCode err, string message)
1371         {
1372             string errMessage = string.Format("{0} err = {1}", message, err);
1373             switch (err)
1374             {
1375                 case Interop.PackageManager.ErrorCode.InvalidParameter:
1376                 case Interop.PackageManager.ErrorCode.NoSuchPackage:
1377                     return new ArgumentException(errMessage);
1378                 case Interop.PackageManager.ErrorCode.PermissionDenied:
1379                     return new UnauthorizedAccessException(errMessage);
1380                 case Interop.PackageManager.ErrorCode.IoError:
1381                     return new global::System.IO.IOException(errMessage);
1382                 default:
1383                     return new InvalidOperationException(errMessage);
1384             }
1385         }
1386     }
1387 }