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