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