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