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