2 * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 using System.Collections.Generic;
19 using System.Threading.Tasks;
22 namespace Tizen.Applications
25 /// PackageManager class. This class has the methods and events of the PackageManager.
28 /// The package manager is one of the core modules of the Tizen application framework and responsible for getting their information.
29 /// You can also retrieve information related to the packages that are installed on the device.
31 /// <since_tizen> 3 </since_tizen>
32 public static class PackageManager
34 private const string LogTag = "Tizen.Applications.PackageManager";
36 private static SafePackageManagerHandle s_handle = new SafePackageManagerHandle();
37 private static Interop.PackageManager.EventStatus s_eventStatus = Interop.PackageManager.EventStatus.All;
38 private static event EventHandler<PackageManagerEventArgs> s_installEventHandler;
39 private static event EventHandler<PackageManagerEventArgs> s_uninstallEventHandler;
40 private static event EventHandler<PackageManagerEventArgs> s_updateEventHandler;
41 private static event EventHandler<PackageManagerEventArgs> s_moveEventHandler;
42 private static event EventHandler<PackageManagerEventArgs> s_clearDataEventHandler;
44 private static Interop.PackageManager.PackageManagerEventCallback s_packageManagerEventCallback;
46 private static Dictionary<IntPtr, Interop.PackageManager.PackageManagerTotalSizeInfoCallback> s_totalSizeInfoCallbackDict = new Dictionary<IntPtr, Interop.PackageManager.PackageManagerTotalSizeInfoCallback>();
47 private static int s_callbackId = 0;
50 /// Event callback method for the request.
52 /// <param name="type">Type of the package which was requested.</param>
53 /// <param name="packageId">ID of the package which was requested.</param>
54 /// <param name="eventType">Event type of the request.</param>
55 /// <param name="eventState">Current event state of the request.</param>
56 /// <param name="progress">Progress for the request being processed by the package manager (in percent).</param>
57 /// <since_tizen> 3 </since_tizen>
58 public delegate void RequestEventCallback(string type, string packageId, PackageEventType eventType, PackageEventState eventState, int progress);
60 private static Dictionary<int, RequestEventCallback> RequestCallbacks = new Dictionary<int, RequestEventCallback>();
61 private static Dictionary<int, SafePackageManagerRequestHandle> RequestHandles = new Dictionary<int, SafePackageManagerRequestHandle>();
63 private delegate Interop.PackageManager.ErrorCode InstallMethodWithCallback(SafePackageManagerRequestHandle requestHandle, string pkgPath, Interop.PackageManager.PackageManagerRequestEventCallback requestCallback, IntPtr userData, out int requestID);
64 private delegate Interop.PackageManager.ErrorCode InstallMethod(SafePackageManagerRequestHandle requestHandle, string pkgPath, out int requestID);
67 /// InstallProgressChanged event. This event occurs when a package is getting installed and the progress of the request to the package manager is changed.
69 /// <since_tizen> 3 </since_tizen>
70 public static event EventHandler<PackageManagerEventArgs> InstallProgressChanged
74 SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Install);
75 RegisterPackageManagerEventIfNeeded();
76 s_installEventHandler += value;
80 s_installEventHandler -= value;
81 UnregisterPackageManagerEventIfNeeded();
82 UnsetPackageManagerEventStatus();
87 /// UninstallProgressChanged event. This event occurs when a package is getting uninstalled and the progress of the request to the package manager is changed.
89 /// <since_tizen> 3 </since_tizen>
90 public static event EventHandler<PackageManagerEventArgs> UninstallProgressChanged
94 SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Uninstall);
95 RegisterPackageManagerEventIfNeeded();
96 s_uninstallEventHandler += value;
100 s_uninstallEventHandler -= value;
101 UnregisterPackageManagerEventIfNeeded();
102 UnsetPackageManagerEventStatus();
107 /// UpdateProgressChanged event. This event occurs when a package is getting updated and the progress of the request to the package manager is changed.
109 /// <since_tizen> 3 </since_tizen>
110 public static event EventHandler<PackageManagerEventArgs> UpdateProgressChanged
114 SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Upgrade);
115 RegisterPackageManagerEventIfNeeded();
116 s_updateEventHandler += value;
120 s_updateEventHandler -= value;
121 UnregisterPackageManagerEventIfNeeded();
122 UnsetPackageManagerEventStatus();
127 /// MoveProgressChanged event. This event occurs when a package is getting moved and the progress of the request to the package manager is changed.
129 /// <since_tizen> 3 </since_tizen>
130 public static event EventHandler<PackageManagerEventArgs> MoveProgressChanged
134 SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.Move);
135 RegisterPackageManagerEventIfNeeded();
136 s_moveEventHandler += value;
140 s_moveEventHandler -= value;
141 UnregisterPackageManagerEventIfNeeded();
142 UnsetPackageManagerEventStatus();
147 /// ClearDataProgressChanged event. This event occurs when data directories are cleared in the given package.
149 /// <since_tizen> 3 </since_tizen>
150 public static event EventHandler<PackageManagerEventArgs> ClearDataProgressChanged
154 SetPackageManagerEventStatus(Interop.PackageManager.EventStatus.ClearData);
155 RegisterPackageManagerEventIfNeeded();
156 s_clearDataEventHandler += value;
160 s_clearDataEventHandler -= value;
161 UnregisterPackageManagerEventIfNeeded();
162 UnsetPackageManagerEventStatus();
166 private static SafePackageManagerHandle Handle
170 if (s_handle.IsInvalid)
172 var err = Interop.PackageManager.PackageManagerCreate(out s_handle);
173 if (err != Interop.PackageManager.ErrorCode.None)
175 Log.Warn(LogTag, string.Format("Failed to create package manager handle. err = {0}", err));
182 private static Interop.PackageManager.PackageManagerRequestEventCallback internalRequestEventCallback = (id, packageType, packageId, eventType, eventState, progress, error, userData) =>
184 if (RequestCallbacks.ContainsKey(id))
188 RequestCallbacks[id](packageType, packageId, (PackageEventType)eventType, (PackageEventState)eventState, progress);
189 if (eventState == Interop.PackageManager.PackageEventState.Completed || eventState == Interop.PackageManager.PackageEventState.Failed)
191 Log.Debug(LogTag, string.Format("release request handle for id : {0}", id));
192 RequestHandles[id].Dispose();
193 RequestHandles.Remove(id);
194 RequestCallbacks.Remove(id);
199 Log.Warn(LogTag, e.Message);
200 RequestHandles[id].Dispose();
201 RequestHandles.Remove(id);
202 RequestCallbacks.Remove(id);
208 /// Gets the package ID for the given application ID.
210 /// <param name="applicationId">The ID of the application.</param>
211 /// <returns>Returns the ID of the package.</returns>
212 /// <remarks>It returns null if the input is null.</remarks>
213 /// <exception cref="ArgumentException">Thrown when input application ID does not exist.</exception>
214 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
215 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
216 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
217 /// <since_tizen> 3 </since_tizen>
218 public static string GetPackageIdByApplicationId(string applicationId)
221 var err = Interop.PackageManager.PackageManagerGetPackageIdByAppId(applicationId, out packageId);
222 if (err != Interop.PackageManager.ErrorCode.None)
224 Log.Warn(LogTag, string.Format("Failed to get package Id of {0}. err = {1}", applicationId, err));
225 if (err != Interop.PackageManager.ErrorCode.InvalidParameter)
227 throw PackageManagerErrorFactory.GetException(err, "Failed to get package Id");
234 /// Gets the package information for the given package.
236 /// <param name="packageId">The ID of the package.</param>
237 /// <returns>Returns the package information for the given package ID.</returns>
238 /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
239 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
240 /// <exception cref="System.IO.IOException">Thrown when the method fails due to an internal I/O error.</exception>
241 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
242 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
243 /// <since_tizen> 3 </since_tizen>
244 public static Package GetPackage(string packageId)
246 return Package.GetPackage(packageId);
250 /// Clears the application's internal and external cache directories.
252 /// <param name="packageId">ID of the package.</param>
253 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
254 /// <exception cref="System.IO.IOException">Thrown when the method fails due to an internal I/O error.</exception>
255 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
256 /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
257 /// <privilege>http://tizen.org/privilege/packagemanager.clearcache</privilege>
258 /// <since_tizen> 3 </since_tizen>
259 public static void ClearCacheDirectory(string packageId)
261 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerClearCacheDir(packageId);
262 if (err != Interop.PackageManager.ErrorCode.None)
264 Log.Warn(LogTag, string.Format("Failed to clear cache directory for {0}. err = {1}", packageId, err));
265 throw PackageManagerErrorFactory.GetException(err, "Failed to clear cache directory");
270 /// Clears all the application's internal and external cache directories.
272 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
273 /// <exception cref="System.IO.IOException">Thrown when the method fails due to an internal IO error.</exception>
274 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
275 /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
276 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
277 /// <privlevel>platform</privlevel>
278 /// <since_tizen> 3 </since_tizen>
279 public static void ClearAllCacheDirectory()
281 var err = Interop.PackageManager.PackageManagerClearAllCacheDir();
282 if (err != Interop.PackageManager.ErrorCode.None)
284 Log.Warn(LogTag, string.Format("Failed to clear all cache directories. err = {0}", err));
285 throw PackageManagerErrorFactory.GetException(err, "Failed to clear all cache directories");
290 /// Clears the application's internal and external data directories.
293 /// All files under data, shared/data, and shared/trusted in the internal storage are removed.
294 /// And, if the external storage exists, then all files under data and shared/trusted in the external storage are removed.
296 /// <param name="packageId">ID of the package.</param>
297 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
298 /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal IO error.</exception>
299 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
300 /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
301 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
302 /// <privlevel>platform</privlevel>
303 /// <since_tizen> 3 </since_tizen>
304 public static void ClearDataDirectory(string packageId)
306 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerClearDataDir(packageId);
307 if (err != Interop.PackageManager.ErrorCode.None)
309 Log.Warn(LogTag, string.Format("Failed to clear data directory for {0}. err = {1}", packageId, err));
310 throw PackageManagerErrorFactory.GetException(err, "Failed to clear data directory");
315 /// Retrieves the package information of all installed packages.
317 /// <returns>Returns the list of packages.</returns>
318 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
319 /// <since_tizen> 3 </since_tizen>
320 public static IEnumerable<Package> GetPackages()
322 return GetPackages(null);
326 /// Retrieves the package information of all the installed packages satisfying the filter conditions.
328 /// <param name="filter">Optional - package filters.</param>
329 /// <returns>Returns the list of packages.</returns>
330 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
331 /// <since_tizen> 3 </since_tizen>
332 public static IEnumerable<Package> GetPackages(PackageFilter filter)
334 List<Package> packageList = new List<Package>();
337 var err = Interop.PackageManager.PackageManagerFilterCreate(out filterHandle);
338 if (err != Interop.PackageManager.ErrorCode.None)
340 Log.Warn(LogTag, string.Format("Failed to create package filter handle. err = {0}", err));
344 if (filter != null && filter.Filters != null)
346 foreach (KeyValuePair<string, bool> entry in filter?.Filters)
348 err = Interop.PackageManager.PackageManagerFilterAdd(filterHandle, entry.Key, entry.Value);
349 if (err != Interop.PackageManager.ErrorCode.None)
351 Log.Warn(LogTag, string.Format("Failed to configure package filter. err = {0}", err));
357 if (err == Interop.PackageManager.ErrorCode.None)
359 Interop.PackageManager.PackageManagerPackageInfoCallback cb = (handle, userData) =>
361 packageList.Add(Package.GetPackage(handle));
365 err = Interop.PackageManager.PackageManagerFilterForeachPackageInfo(filterHandle, cb, IntPtr.Zero);
366 if (err != Interop.PackageManager.ErrorCode.None)
368 Log.Warn(LogTag, string.Format("Failed to get package Informations. err = {0}", err));
372 err = Interop.PackageManager.PackageManagerFilterDestroy(filterHandle);
373 if (err != Interop.PackageManager.ErrorCode.None)
375 Log.Warn(LogTag, string.Format("Failed to destroy package filter handle. err = {0}", err));
381 /// Gets the total package size information.
383 /// <returns>Returns the total package size information asynchronously.</returns>
384 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
385 /// <since_tizen> 3 </since_tizen>
386 public static async Task<PackageSizeInformation> GetTotalSizeInformationAsync()
388 TaskCompletionSource<PackageSizeInformation> tcs = new TaskCompletionSource<PackageSizeInformation>();
390 Interop.PackageManager.PackageManagerTotalSizeInfoCallback cb = (handle, userData) =>
392 if (handle != IntPtr.Zero)
394 tcs.TrySetResult(PackageSizeInformation.GetPackageSizeInformation(handle));
397 lock (s_totalSizeInfoCallbackDict)
399 s_totalSizeInfoCallbackDict.Remove(userData);
404 lock (s_totalSizeInfoCallbackDict)
406 callbackId = (IntPtr)s_callbackId++;
407 s_totalSizeInfoCallbackDict[callbackId] = cb;
410 var err = Interop.PackageManager.PackageManagerGetTotalSizeInfo(cb, callbackId);
411 if (err != Interop.PackageManager.ErrorCode.None)
413 tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info"));
415 return await tcs.Task.ConfigureAwait(false);
419 /// Installs the package located at the given path.
421 /// <param name="packagePath">Absolute path for the package to be installed.</param>
422 /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
423 /// <returns>Returns true if the installation request is successful, otherwise false.</returns>
425 /// The 'true' means that the request for installation is successful.
426 /// To check the result of the installation, the caller should check the progress using the InstallProgressChanged event.
428 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
429 /// <privlevel>platform</privlevel>
430 /// <since_tizen> 3 </since_tizen>
431 public static bool Install(string packagePath, InstallationMode installMode = InstallationMode.Normal)
433 return Install(packagePath, null, PackageType.UNKNOWN, null, installMode);
437 /// Installs the package located at the given path.
439 /// <param name="packagePath">Absolute path for the package to be installed.</param>
440 /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
441 /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
442 /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
444 /// The 'true' means that the request for installation is successful.
445 /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
447 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
448 /// <privlevel>platform</privlevel>
449 /// <since_tizen> 3 </since_tizen>
450 public static bool Install(string packagePath, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
452 return Install(packagePath, null, PackageType.UNKNOWN, eventCallback, installMode);
456 /// Installs the package located at the given path.
458 /// <param name="packagePath">Absolute path for the package to be installed.</param>
459 /// <param name="type">Package type for the package to be installed.</param>
460 /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
461 /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
463 /// The 'true' means that the request for installation is successful.
464 /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
466 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
467 /// <privlevel>platform</privlevel>
468 /// <since_tizen> 3 </since_tizen>
469 public static bool Install(string packagePath, PackageType type, InstallationMode installMode = InstallationMode.Normal)
471 return Install(packagePath, null, type, null, installMode);
475 /// Installs the package located at the given path.
477 /// <param name="packagePath">Absolute path for the package to be installed.</param>
478 /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
479 /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
480 /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
482 /// The 'true' means that the request for installation is successful.
483 /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
485 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
486 /// <privlevel>platform</privlevel>
487 /// <since_tizen> 3 </since_tizen>
488 public static bool Install(string packagePath, string expansionPackagePath, InstallationMode installMode = InstallationMode.Normal)
490 return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, null, installMode);
494 /// Installs the package located at the given path.
496 /// <param name="packagePath">Absolute path for the package to be installed.</param>
497 /// <param name="type">Package type for the package to be installed.</param>
498 /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
499 /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
500 /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
502 /// The 'true' means that the request for installation is successful.
503 /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
505 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
506 /// <privlevel>platform</privlevel>
507 /// <since_tizen> 3 </since_tizen>
508 public static bool Install(string packagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
510 return Install(packagePath, null, type, eventCallback, installMode);
514 /// Installs the package located at the given path.
516 /// <param name="packagePath">Absolute path for the package to be installed.</param>
517 /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
518 /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
519 /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
520 /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
522 /// The 'true' means that the request for installation is successful.
523 /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
525 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
526 /// <privlevel>platform</privlevel>
527 /// <since_tizen> 3 </since_tizen>
528 public static bool Install(string packagePath, string expansionPackagePath, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
530 return Install(packagePath, expansionPackagePath, PackageType.UNKNOWN, eventCallback, installMode);
534 /// Installs the package located at the given path.
536 /// <param name="packagePath">Absolute path for the package to be installed.</param>
537 /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
538 /// <param name="type">Package type for the package to be installed.</param>
539 /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
540 /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
542 /// The 'true' means that the request for installation is successful.
543 /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event.
545 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
546 /// <privlevel>platform</privlevel>
547 /// <since_tizen> 3 </since_tizen>
548 public static bool Install(string packagePath, string expansionPackagePath, PackageType type, InstallationMode installMode = InstallationMode.Normal)
550 return Install(packagePath, expansionPackagePath, type, null, installMode);
554 /// Installs the package located at the given path.
556 /// <param name="packagePath">Absolute path for the package to be installed.</param>
557 /// <param name="expansionPackagePath">Absolute path for the expansion package to be installed.</param>
558 /// <param name="type">Package type for the package to be installed.</param>
559 /// <param name="eventCallback">The event callback will be invoked only for the current request.</param>
560 /// <param name="installMode">Optional parameter to indicate special installation mode.</param>
561 /// <returns>Returns true if installtion request is successful, false otherwise.</returns>
563 /// The 'true' means that the request for installation is successful.
564 /// To check the result of installation, the caller should check the progress using the InstallProgressChanged event or eventCallback.
566 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
567 /// <privlevel>platform</privlevel>
568 /// <since_tizen> 3 </since_tizen>
569 public static bool Install(string packagePath, string expansionPackagePath, PackageType type, RequestEventCallback eventCallback, InstallationMode installMode = InstallationMode.Normal)
571 SafePackageManagerRequestHandle RequestHandle;
572 var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
573 if (err != Interop.PackageManager.ErrorCode.None)
575 Log.Warn(LogTag, string.Format("Failed to install package {0}. Error in creating package manager request handle. err = {1}", packagePath, err));
581 if (type != PackageType.UNKNOWN)
583 err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
584 if (err != Interop.PackageManager.ErrorCode.None)
586 Log.Warn(LogTag, string.Format("Failed to install package {0}. Error in setting request package type. err = {1}", packagePath, err));
587 RequestHandle.Dispose();
592 if (!string.IsNullOrEmpty(expansionPackagePath))
594 err = Interop.PackageManager.PackageManagerRequestSetTepPath(RequestHandle, expansionPackagePath);
595 if (err != Interop.PackageManager.ErrorCode.None)
597 Log.Warn(LogTag, string.Format("Failed to install package {0}. Error in setting request package mode. err = {1}", packagePath, err));
598 RequestHandle.Dispose();
604 if (eventCallback != null)
606 InstallMethodWithCallback install;
607 if (installMode == InstallationMode.Mount)
609 install = Interop.PackageManager.PackageManagerRequestMountInstallWithCB;
613 install = Interop.PackageManager.PackageManagerRequestInstallWithCB;
615 err = install(RequestHandle, packagePath, internalRequestEventCallback, IntPtr.Zero, out requestId);
616 if (err == Interop.PackageManager.ErrorCode.None)
618 RequestCallbacks.Add(requestId, eventCallback);
619 RequestHandles.Add(requestId, RequestHandle);
623 Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePath, err));
624 RequestHandle.Dispose();
630 InstallMethod install;
631 if (installMode == InstallationMode.Mount)
633 install = Interop.PackageManager.PackageManagerRequestMountInstall;
637 install = Interop.PackageManager.PackageManagerRequestInstall;
639 err = install(RequestHandle, packagePath, out requestId);
640 if (err != Interop.PackageManager.ErrorCode.None)
642 Log.Warn(LogTag, string.Format("Failed to install package {0}. err = {1}", packagePath, err));
643 RequestHandle.Dispose();
646 // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
647 RequestHandle.Dispose();
653 Log.Warn(LogTag, e.Message);
654 RequestHandle.Dispose();
660 /// Uninstalls the package with the given name.
662 /// <param name="packageId">ID of the package to be uninstalled.</param>
663 /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
665 /// The 'true' means that the request for uninstallation is successful.
666 /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event.
668 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
669 /// <privlevel>platform</privlevel>
670 /// <since_tizen> 3 </since_tizen>
671 public static bool Uninstall(string packageId)
673 return Uninstall(packageId, PackageType.UNKNOWN, null);
677 /// Uninstalls package with the given names.
679 /// <param name="packageId">ID of the package to be uninstalled.</param>
680 /// <param name="type">Optional - Package type for the package to be uninstalled.</param>
681 /// <returns>Returns true if the uninstalltion request is successful, false otherwise.</returns>
683 /// The 'true' means that the request for uninstallation is successful.
684 /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event.
686 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
687 /// <privlevel>platform</privlevel>
688 /// <since_tizen> 3 </since_tizen>
689 public static bool Uninstall(string packageId, PackageType type)
691 return Uninstall(packageId, type, null);
695 /// Uninstalls the package with the given name.
697 /// <param name="packageId">ID of the package to be uninstalled.</param>
698 /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
699 /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
701 /// The 'true' means that the request for uninstallation is successful.
702 /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event or eventCallback.
704 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
705 /// <privlevel>platform</privlevel>
706 /// <since_tizen> 3 </since_tizen>
707 public static bool Uninstall(string packageId, RequestEventCallback eventCallback)
709 return Uninstall(packageId, PackageType.UNKNOWN, eventCallback);
713 /// Uninstalls the package with the given name.
715 /// <param name="packageId">ID of the package to be uninstalled</param>
716 /// <param name="type">Optional - Package type for the package to be uninstalled.</param>
717 /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
718 /// <returns>Returns true if the uninstallation request is successful, false otherwise.</returns>
720 /// The 'true' means that the request for uninstallation is successful.
721 /// To check the result of uninstallation, the caller should check the progress using the UninstallProgressChanged event or eventCallback.
723 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
724 /// <privlevel>platform</privlevel>
725 /// <since_tizen> 3 </since_tizen>
726 public static bool Uninstall(string packageId, PackageType type, RequestEventCallback eventCallback)
728 SafePackageManagerRequestHandle RequestHandle;
729 var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
730 if (err != Interop.PackageManager.ErrorCode.None)
732 Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. Error in creating package manager request handle. err = {1}", packageId, err));
738 err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
739 if (err != Interop.PackageManager.ErrorCode.None)
741 Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. Error in setting request package type. err = {1}", packageId, err));
742 RequestHandle.Dispose();
747 if (eventCallback != null)
749 err = Interop.PackageManager.PackageManagerRequestUninstallWithCB(RequestHandle, packageId, internalRequestEventCallback, IntPtr.Zero, out requestId);
750 if (err == Interop.PackageManager.ErrorCode.None)
752 RequestCallbacks.Add(requestId, eventCallback);
753 RequestHandles.Add(requestId, RequestHandle);
757 Log.Warn(LogTag, string.Format("Failed to uninstall package {0}. err = {1}", packageId, err));
758 RequestHandle.Dispose();
764 err = Interop.PackageManager.PackageManagerRequestUninstall(RequestHandle, packageId, out requestId);
765 if (err != Interop.PackageManager.ErrorCode.None)
767 Log.Warn(LogTag, string.Format("Failed to uninstall package. err = {0}", err));
768 RequestHandle.Dispose();
771 // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
772 RequestHandle.Dispose();
778 Log.Warn(LogTag, e.Message);
779 RequestHandle.Dispose();
785 /// Moves the package to the given storage.
787 /// <param name="packageId">ID of the package to be moved.</param>
788 /// <param name="newStorage">Storage package should be moved to.</param>
789 /// <returns>Returns true if the move request is successful, false otherwise.</returns>
791 /// The 'true' means that the request for move is successful.
792 /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
794 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
795 /// <privlevel>platform</privlevel>
796 /// <since_tizen> 3 </since_tizen>
797 public static bool Move(string packageId, StorageType newStorage)
799 return Move(packageId, PackageType.UNKNOWN, newStorage, null);
803 /// Moves the package to the given storage.
805 /// <param name="packageId">ID of the package to be moved.</param>
806 /// <param name="type">Optional - Package type for the package to be moved.</param>
807 /// <param name="newStorage">Storage package should be moved to.</param>
808 /// <returns>Returns true if the move request is successful, false otherwise.</returns>
810 /// The 'true' means that the request for move is successful.
811 /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
813 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
814 /// <privlevel>platform</privlevel>
815 /// <since_tizen> 3 </since_tizen>
816 public static bool Move(string packageId, PackageType type, StorageType newStorage)
818 return Move(packageId, type, newStorage, null);
822 /// Moves the package to the given storage.
824 /// <param name="packageId">ID of the package to be moved.</param>
825 /// <param name="newStorage">Storage package should be moved to.</param>
826 /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
827 /// <returns>Returns true if move request is successful, false otherwise.</returns>
829 /// The 'true' means that the request for move is successful.
830 /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
832 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
833 /// <privlevel>platform</privlevel>
834 /// <since_tizen> 3 </since_tizen>
835 public static bool Move(string packageId, StorageType newStorage, RequestEventCallback eventCallback)
837 return Move(packageId, PackageType.UNKNOWN, newStorage, eventCallback);
841 /// Moves the package to the given storage.
843 /// <param name="packageId">ID of the package to be moved.</param>
844 /// <param name="type">Optional - Package type for the package to be moved.</param>
845 /// <param name="newStorage">Storage, package should be moved to.</param>
846 /// <param name="eventCallback">Optional - The event callback will be invoked only for the current request.</param>
847 /// <returns>Returns true if move request is successful, false otherwise.</returns>
849 /// The 'true' means that the request for move is successful.
850 /// To check the result of move, the caller should check the progress using the MoveProgressChanged event.
852 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
853 /// <privlevel>platform</privlevel>
854 /// <since_tizen> 3 </since_tizen>
855 public static bool Move(string packageId, PackageType type, StorageType newStorage, RequestEventCallback eventCallback)
857 SafePackageManagerRequestHandle RequestHandle;
858 var err = Interop.PackageManager.PackageManagerRequestCreate(out RequestHandle);
859 if (err != Interop.PackageManager.ErrorCode.None)
861 Log.Warn(LogTag, string.Format("Failed to create package manager request handle. err = {0}", err));
868 err = Interop.PackageManager.PackageManagerRequestSetType(RequestHandle, type.ToString().ToLower());
869 if (err != Interop.PackageManager.ErrorCode.None)
871 Log.Warn(LogTag, string.Format("Failed to move package. Error in setting request package type. err = {0}", err));
872 RequestHandle.Dispose();
876 if (eventCallback != null)
879 err = Interop.PackageManager.PackageManagerRequestMoveWithCB(RequestHandle, packageId, (Interop.PackageManager.StorageType)newStorage, internalRequestEventCallback, IntPtr.Zero, out requestId);
880 if (err == Interop.PackageManager.ErrorCode.None)
882 RequestCallbacks.Add(requestId, eventCallback);
883 RequestHandles.Add(requestId, RequestHandle);
887 Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
888 RequestHandle.Dispose();
894 err = Interop.PackageManager.PackageManagerRequestMove(RequestHandle, packageId, (Interop.PackageManager.StorageType)newStorage);
895 if (err != Interop.PackageManager.ErrorCode.None)
897 Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
898 RequestHandle.Dispose();
901 // RequestHandle isn't necessary when this method is called without 'eventCallback' parameter.
902 RequestHandle.Dispose();
908 Log.Warn(LogTag, e.Message);
909 RequestHandle.Dispose();
915 /// Gets the permission type of the package which has a given application ID.
917 /// <param name="applicationId">ID of the application.</param>
918 /// <returns>Returns the permission type.</returns>
919 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
920 /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
921 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
922 /// <since_tizen> 3 </since_tizen>
923 public static PermissionType GetPermissionTypeByApplicationId(string applicationId)
925 Interop.PackageManager.PackageManagerPermissionType permissionType;
926 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetPermissionType(applicationId, out permissionType);
927 if (err != Interop.PackageManager.ErrorCode.None)
929 throw PackageManagerErrorFactory.GetException(err, "Failed to get permission type.");
932 return (PermissionType)permissionType;
936 /// Gets the package's preload attribute which contains a given application ID.
938 /// <param name="applicationId">ID of the application.</param>
939 /// <returns>Returns true if the package is preloaded, otherwise false.</returns>
940 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
941 /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
942 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
943 /// <since_tizen> 3 </since_tizen>
944 public static bool IsPreloadPackageByApplicationId(string applicationId)
946 bool isPreloadPackage;
947 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerIsPreloadPackageByApplicationId(applicationId, out isPreloadPackage);
948 if (err != Interop.PackageManager.ErrorCode.None)
950 throw PackageManagerErrorFactory.GetException(err, "Failed to get preload info");
953 return isPreloadPackage;
957 /// Compares the certificate of the two packages.
959 /// <param name="lhsPackageId">Package ID to compare.</param>
960 /// <param name="rhsPackageId">Package ID to be compared.</param>
961 /// <returns>Returns certificate comparison result.</returns>
962 /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
963 /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal I/O error.</exception>
964 /// <since_tizen> 3 </since_tizen>
965 public static CertCompareResultType CompareCertInfo(string lhsPackageId, string rhsPackageId)
967 Interop.PackageManager.CertCompareResultType compareResult;
968 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfo(lhsPackageId, rhsPackageId, out compareResult);
969 if (err != Interop.PackageManager.ErrorCode.None)
971 throw PackageManagerErrorFactory.GetException(err, "Failed to compare cert info");
974 return (CertCompareResultType)compareResult;
978 /// Compares the certificate of the two packages which contain each given application ID.
980 /// <param name="lhsApplicationId">Application ID to compare.</param>
981 /// <param name="rhsApplicationId">Application ID to be compared.</param>
982 /// <returns>Returns certificate comparison result.</returns>
983 /// <exception cref="ArgumentException">Thrown when the failed input package ID is invalid.</exception>
984 /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal I/O error.</exception>
985 /// <since_tizen> 3 </since_tizen>
986 public static CertCompareResultType CompareCertInfoByApplicationId(string lhsApplicationId, string rhsApplicationId)
988 Interop.PackageManager.CertCompareResultType compareResult;
989 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfoByApplicationId(lhsApplicationId, rhsApplicationId, out compareResult);
990 if (err != Interop.PackageManager.ErrorCode.None)
992 throw PackageManagerErrorFactory.GetException(err, "Failed to compare cert info by application id");
995 return (CertCompareResultType)compareResult;
999 /// Drm nested class. This class has the PackageManager's drm related methods.
1001 /// <since_tizen> 3 </since_tizen>
1002 public static class Drm
1005 /// Generates a request for getting the license.
1007 /// <param name="responseData">Response data string of the purchase request.</param>
1008 /// <returns>Returns the package DRM information of a given response data which contains the required data and license URL.</returns>
1009 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1010 /// <privlevel>platform</privlevel>
1011 /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1012 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1013 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1014 /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
1015 /// <since_tizen> 3 </since_tizen>
1016 public static PackageDrm GenerateLicenseRequest(string responseData)
1018 return PackageDrm.GenerateLicenseRequest(responseData);
1023 /// Registers the encrypted license.
1025 /// <param name="responseData">The response data string of the rights request.</param>
1026 /// <returns>Returns true if succeeds, otherwise false.</returns>
1027 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1028 /// <privlevel>platform</privlevel>
1029 /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1030 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1031 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1032 /// <exception cref="SystemException">Thrown when the method failed due to internal system error.</exception>
1033 /// <since_tizen> 3 </since_tizen>
1034 public static bool RegisterLicense(string responseData)
1036 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmRegisterLicense(responseData);
1037 if (err != Interop.PackageManager.ErrorCode.None)
1039 throw PackageManagerErrorFactory.GetException(err, "Failed to register drm license");
1046 /// Decrypts the contents which are encrypted.
1048 /// <param name="drmFilePath">Drm file path.</param>
1049 /// <param name="decryptedFilePath">Decrypted file path.</param>
1050 /// <returns>Returns true if succeeds, otherwise false.</returns>
1051 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
1052 /// <privlevel>platform</privlevel>
1053 /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid.</exception>
1054 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method.</exception>
1055 /// <exception cref="UnauthorizedAccessException">Thrown when an application does not have the privilege to access this method.</exception>
1056 /// <exception cref="SystemException">Thrown when the method failed due to an internal system error.</exception>
1057 /// <since_tizen> 3 </since_tizen>
1058 public static bool DecryptPackage(string drmFilePath, string decryptedFilePath)
1060 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerDrmDecryptPackage(drmFilePath, decryptedFilePath);
1061 if (err != Interop.PackageManager.ErrorCode.None)
1063 throw PackageManagerErrorFactory.GetException(err, "Failed to decrypt drm package");
1070 private static void SetPackageManagerEventStatus(Interop.PackageManager.EventStatus status)
1072 if (Handle.IsInvalid) return;
1074 Interop.PackageManager.EventStatus eventStatus = s_eventStatus;
1075 eventStatus |= status;
1076 if (eventStatus != Interop.PackageManager.EventStatus.All)
1077 eventStatus |= Interop.PackageManager.EventStatus.Progress;
1079 var err = Interop.PackageManager.ErrorCode.None;
1080 if (s_eventStatus != eventStatus)
1082 err = Interop.PackageManager.PackageManagerSetEvenStatus(Handle, eventStatus);
1083 if (err == Interop.PackageManager.ErrorCode.None)
1085 s_eventStatus = eventStatus;
1086 Log.Debug(LogTag, string.Format("New Event Status flag: {0}", s_eventStatus));
1089 Log.Debug(LogTag, string.Format("Failed to set flag for {0} event. err = {1}", eventStatus, err));
1093 private static void UnsetPackageManagerEventStatus()
1095 if (Handle.IsInvalid) return;
1097 Interop.PackageManager.EventStatus eventStatus = Interop.PackageManager.EventStatus.All;
1098 if (s_installEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Install;
1099 if (s_uninstallEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Uninstall;
1100 if (s_updateEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Upgrade;
1101 if (s_moveEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.Move;
1102 if (s_clearDataEventHandler != null) eventStatus |= Interop.PackageManager.EventStatus.ClearData;
1103 if (eventStatus != Interop.PackageManager.EventStatus.All)
1104 eventStatus |= Interop.PackageManager.EventStatus.Progress;
1106 var err = Interop.PackageManager.ErrorCode.None;
1107 if (s_eventStatus != eventStatus)
1109 err = Interop.PackageManager.PackageManagerSetEvenStatus(Handle, eventStatus);
1110 if (err == Interop.PackageManager.ErrorCode.None)
1112 s_eventStatus = eventStatus;
1113 Log.Debug(LogTag, string.Format("New Event Status flag: {0}", s_eventStatus));
1116 Log.Debug(LogTag, string.Format("Failed to set flag for {0} event. err = {1}", eventStatus, err));
1120 private static void RegisterPackageManagerEventIfNeeded()
1122 if (s_installEventHandler != null && s_uninstallEventHandler != null && s_updateEventHandler != null && s_moveEventHandler != null && s_clearDataEventHandler != null)
1125 var err = Interop.PackageManager.ErrorCode.None;
1126 s_packageManagerEventCallback = new Interop.PackageManager.PackageManagerEventCallback(InternalEventCallback);
1128 if (!Handle.IsInvalid)
1130 Log.Debug(LogTag, "Reset Package Event");
1131 err = Interop.PackageManager.PackageManagerUnsetEvent(Handle);
1132 if (err != Interop.PackageManager.ErrorCode.None)
1134 throw PackageManagerErrorFactory.GetException(err, "Failed to unregister package manager event event.");
1137 err = Interop.PackageManager.PackageManagerSetEvent(Handle, s_packageManagerEventCallback, IntPtr.Zero);
1139 if (err != Interop.PackageManager.ErrorCode.None)
1141 Log.Warn(LogTag, string.Format("Failed to register callback for package manager event. err = {0}", err));
1145 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)
1149 if (eventType == Interop.PackageManager.EventType.Install)
1151 s_installEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
1153 else if (eventType == Interop.PackageManager.EventType.Uninstall)
1155 s_uninstallEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
1157 else if (eventType == Interop.PackageManager.EventType.Update)
1159 s_updateEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
1161 else if (eventType == Interop.PackageManager.EventType.Move)
1163 s_moveEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
1165 else if (eventType == Interop.PackageManager.EventType.ClearData)
1167 s_clearDataEventHandler?.Invoke(null, new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress));
1172 Log.Warn(LogTag, e.Message);
1176 private static void UnregisterPackageManagerEventIfNeeded()
1178 if (s_packageManagerEventCallback == null || s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null || s_moveEventHandler != null || s_clearDataEventHandler != null)
1183 s_packageManagerEventCallback = null;
1185 var err = Interop.PackageManager.PackageManagerUnsetEvent(Handle);
1186 if (err != Interop.PackageManager.ErrorCode.None)
1188 throw PackageManagerErrorFactory.GetException(err, "Failed to unregister package manager event event.");
1193 internal static class PackageManagerErrorFactory
1195 internal static Exception GetException(Interop.PackageManager.ErrorCode err, string message)
1197 string errMessage = string.Format("{0} err = {1}", message, err);
1200 case Interop.PackageManager.ErrorCode.InvalidParameter:
1201 case Interop.PackageManager.ErrorCode.NoSuchPackage:
1202 return new ArgumentException(errMessage);
1203 case Interop.PackageManager.ErrorCode.PermissionDenied:
1204 return new UnauthorizedAccessException(errMessage);
1205 case Interop.PackageManager.ErrorCode.IoError:
1206 return new global::System.IO.IOException(errMessage);
1208 return new InvalidOperationException(errMessage);