1 // Copyright 2016 by Samsung Electronics, Inc.,
3 // This software is the confidential and proprietary information
4 // of Samsung Electronics, Inc. ("Confidential Information"). You
5 // shall not disclose such Confidential Information and shall use
6 // it only in accordance with the terms of the license agreement
7 // you entered into with Samsung.
10 using System.Collections.Generic;
11 using System.Threading.Tasks;
13 namespace Tizen.Applications
16 /// PackageManager class. This class has the methods and events of the PackageManager.
19 /// The package manager is one of the core modules of Tizen application framework, and responsible for getting their information.
20 /// You can also retrieve information related to the packages that are installed on the device.
22 public static class PackageManager
24 private const string LogTag = "Tizen.Applications";
25 private static SafePackageManagerHandle s_handle = new SafePackageManagerHandle();
27 private static Interop.PackageManager.EventStatus s_eventStatus;
28 private static event EventHandler<PackageManagerEventArgs> s_installEventHandler;
29 private static event EventHandler<PackageManagerEventArgs> s_uninstallEventHandler;
30 private static event EventHandler<PackageManagerEventArgs> s_updateEventHandler;
32 private static Interop.PackageManager.PackageManagerEventCallback s_packageManagerEventCallback;
35 /// InstallProgressChanged event. This event is occurred when a package is getting installed and the progress of the request to the package manager changes.
37 public static event EventHandler<PackageManagerEventArgs> InstallProgressChanged
41 RegisterPackageManagerEventIfNeeded(GetFlaggedEventStatus(Interop.PackageManager.EventStatus.Install));
42 s_installEventHandler += value;
46 s_installEventHandler -= value;
47 UnregisterPackageManagerEventIfNeeded(GetUnflaggedEventStatus(Interop.PackageManager.EventStatus.Install));
52 /// UninstallProgressChanged event. This event is occurred when a package is getting uninstalled and the progress of the request to the package manager changes.
54 public static event EventHandler<PackageManagerEventArgs> UninstallProgressChanged
58 RegisterPackageManagerEventIfNeeded(GetFlaggedEventStatus(Interop.PackageManager.EventStatus.Unstall));
59 s_uninstallEventHandler += value;
63 s_uninstallEventHandler -= value;
64 UnregisterPackageManagerEventIfNeeded(GetUnflaggedEventStatus(Interop.PackageManager.EventStatus.Unstall));
69 /// UpdateProgressChanged event. This event is occurred when a package is getting updated and the progress of the request to the package manager changes.
71 public static event EventHandler<PackageManagerEventArgs> UpdateProgressChanged
75 RegisterPackageManagerEventIfNeeded(GetFlaggedEventStatus(Interop.PackageManager.EventStatus.Upgrade));
76 s_updateEventHandler += value;
80 s_updateEventHandler -= value;
81 UnregisterPackageManagerEventIfNeeded(GetFlaggedEventStatus(Interop.PackageManager.EventStatus.Upgrade));
86 /// Gets the package ID for the given app ID.
88 /// <param name="applicationId">The ID of the application</param>
89 /// <returns>Returns the ID of the package. Empty string if App ID does not exist</returns>
90 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
91 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
92 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
93 public static string GetPackageIdByApplicationId(string applicationId)
95 string packageId = string.Empty;
96 var err = Interop.PackageManager.PackageManageGetPackageIdByAppId(applicationId, out packageId);
97 if (err != Interop.PackageManager.ErrorCode.None)
99 Log.Warn(LogTag, string.Format("Failed to get package Id. err = {0}", err));
100 if (err != Interop.PackageManager.ErrorCode.InvalidParameter)
102 throw PackageManagerErrorFactory.GetException(err, "Failed to get package Id");
109 /// Gets the package information for the given package.
111 /// <param name="packageId">The ID of the package</param>
112 /// <returns>Returns the package information for the given package ID.</returns>
113 /// <exception cref="ArgumentException">Thrown when failed when input package ID is invalid</exception>
114 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
115 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
116 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
117 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
118 public static Package GetPackage(string packageId)
120 return Package.GetPackage(packageId);
124 /// Clears all application's internal and external cache directory.
126 /// <exception cref="OutOfMemoryException">Thrown when there is not enough memory to continue the execution of the method</exception>
127 /// <exception cref="System.IO.IOException">Thrown when method failed due to internal IO error</exception>
128 /// <exception cref="UnauthorizedAccessException">Thrown when app does not have privilege to access this method</exception>
129 /// <exception cref="SystemException">Thrown when method failed due to internal system error</exception>
130 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
131 public static void ClearAllCacheDirectory()
133 var err = Interop.PackageManager.PackageManagerClearAllCacheDir();
134 if (err != Interop.PackageManager.ErrorCode.None)
136 Log.Warn(LogTag, string.Format("Failed to clear all cache directories. err = {0}", err));
137 throw PackageManagerErrorFactory.GetException(err, "Failed to clear all cache directories");
142 /// Retrieves package information of all packages satisfying filter conditions.
144 /// <returns>Returns the list of packages asynchronously.</returns>
145 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
146 public static IEnumerable<Package> GetPackages()
148 return GetPackages(null);
152 /// Retrieves package information of all packages satisfying filter conditions.
154 /// <param name="filter">Optional - package filters</param>
155 /// <returns>Returns the list of packages asynchronously.</returns>
156 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
157 public static IEnumerable<Package> GetPackages(PackageFilter filter)
159 List<Package> packageList = new List<Package>();
162 var err = Interop.PackageManager.PackageManagerFilterCreate(out filterHandle);
163 if (err != Interop.PackageManager.ErrorCode.None)
165 Log.Warn(LogTag, string.Format("Failed to create package filter handle. err = {0}", err));
169 if (filter != null && filter.Filters != null)
171 foreach (KeyValuePair<string, bool> entry in filter?.Filters)
173 err = Interop.PackageManager.PackageManagerFilterAdd(filterHandle, entry.Key, entry.Value);
174 if (err != Interop.PackageManager.ErrorCode.None)
176 Log.Warn(LogTag, string.Format("Failed to configure package filter. err = {0}", err));
182 if (err == Interop.PackageManager.ErrorCode.None)
184 Interop.PackageManager.PackageManagerPackageInfoCallback cb = (handle, userData) =>
186 packageList.Add(Package.GetPackage(handle));
190 err = Interop.PackageManager.PackageManagerFilterForeachPackageInfo(filterHandle, cb, IntPtr.Zero);
191 if (err != Interop.PackageManager.ErrorCode.None)
193 Log.Warn(LogTag, string.Format("Failed to get package Informations. err = {0}", err));
197 err = Interop.PackageManager.PackageManagerFilterDestroy(filterHandle);
198 if (err != Interop.PackageManager.ErrorCode.None)
200 Log.Warn(LogTag, string.Format("Failed to destroy package filter handle. err = {0}", err));
206 /// Gets the total package size information.
208 /// <returns>Returns the total package size information asynchronously.</returns>
209 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
210 public static async Task<PackageSizeInformation> GetTotalSizeInformationAsync()
212 TaskCompletionSource<PackageSizeInformation> tcs = new TaskCompletionSource<PackageSizeInformation>();
213 Interop.PackageManager.PackageManagerTotalSizeInfoCallback cb = (handle, userData) =>
215 if (handle != IntPtr.Zero)
217 tcs.TrySetResult(PackageSizeInformation.GetPackageSizeInformation(handle));
221 var err = Interop.PackageManager.PackageManagerGetTotalSizeInfo(cb, IntPtr.Zero);
222 if (err != Interop.PackageManager.ErrorCode.None)
224 tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info"));
226 return await tcs.Task.ConfigureAwait(false);
230 /// Installs package located at the given path
232 /// <param name="packagePath">Absolute path for the package to be installed</param>
233 /// <returns>Returns true if installtion is successful, false otherwise.</returns>
234 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
235 public static bool Install(string packagePath)
237 return Install(packagePath, null);
241 /// Installs package located at the given path
243 /// <param name="packagePath">Absolute path for the package to be installed</param>
244 /// <param name="expansionPackagePath">Optional - Absolute path for the expansion package to be installed</param>
245 /// <returns>Returns true if installtion is successful, false otherwise.</returns>
246 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
247 public static bool Install(string packagePath, string expansionPackagePath)
249 IntPtr requestHandle;
250 var err = Interop.PackageManager.PackageManagerRequestCreate(out requestHandle);
251 if (err != Interop.PackageManager.ErrorCode.None)
253 Log.Warn(LogTag, string.Format("Failed to install package. Error in creating request handle. err = {0}", err));
257 if (!string.IsNullOrEmpty(expansionPackagePath))
259 err = Interop.PackageManager.PackageManagerRequestSetTepPath(requestHandle, expansionPackagePath);
260 if (err != Interop.PackageManager.ErrorCode.None)
262 Log.Warn(LogTag, string.Format("Failed to install package. Error in setting request package mode. err = {0}", err));
263 Interop.PackageManager.PackageManagerRequestDestroy(requestHandle);
269 err = Interop.PackageManager.PackageManagerRequestInstall(requestHandle, packagePath, out requestId);
270 if (err != Interop.PackageManager.ErrorCode.None)
272 Log.Warn(LogTag, string.Format("Failed to install package. err = {0}", err));
273 Interop.PackageManager.PackageManagerRequestDestroy(requestHandle);
277 err = Interop.PackageManager.PackageManagerRequestDestroy(requestHandle);
278 if (err != Interop.PackageManager.ErrorCode.None)
280 Log.Warn(LogTag, string.Format("Failed to destroy package manager request handle. err = {0}", err));
281 // This method returns true if all other operations are completed and error occured in destroying request handle.
287 /// Uninstalls package with the given name.
289 /// <param name="packageId">Id of the package to be uninstalled</param>
290 /// <param name="type">Package type for the package to be uninstalled</param>
291 /// <returns>Returns true if installtion is successful, false otherwise.</returns>
292 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
293 public static bool Uninstall(string packageId, PackageType type)
295 IntPtr requestHandle;
296 var err = Interop.PackageManager.PackageManagerRequestCreate(out requestHandle);
297 if (err != Interop.PackageManager.ErrorCode.None)
299 Log.Warn(LogTag, string.Format("Failed to uninstall package. Error in creating request handle. err = {0}", err));
303 err = Interop.PackageManager.PackageManagerRequestSetType(requestHandle, type.ToString().ToLower());
304 if (err != Interop.PackageManager.ErrorCode.None)
306 Log.Warn(LogTag, string.Format("Failed to uninstall package. Error in setting request package type. err = {0}", err));
307 Interop.PackageManager.PackageManagerRequestDestroy(requestHandle);
312 err = Interop.PackageManager.PackageManagerRequestUninstall(requestHandle, packageId, out requestId);
313 if (err != Interop.PackageManager.ErrorCode.None)
315 Log.Warn(LogTag, string.Format("Failed to uninstall package. err = {0}", err));
316 Interop.PackageManager.PackageManagerRequestDestroy(requestHandle);
320 err = Interop.PackageManager.PackageManagerRequestDestroy(requestHandle);
321 if (err != Interop.PackageManager.ErrorCode.None)
323 Log.Warn(LogTag, string.Format("Failed to destroy package manager request handle. err = {0}", err));
324 // This method returns true if all other operations are completed and error occured in destroying request handle.
330 /// Move package to given storage.
332 /// <param name="packageId">Id of the package to be moved</param>
333 /// <param name="type">Package type for the package to be moved</param>
334 /// <param name="newStorage">Storage, package should be moved to</param>
335 /// <returns>Returns true if installtion is successful, false otherwise.</returns>
336 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
337 public static bool Move(string packageId, PackageType type, StorageType newStorage)
340 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerRequestCreate(out request);
341 if (err != Interop.PackageManager.ErrorCode.None)
343 Log.Warn(LogTag, string.Format("Failed to create request handle. err = {0}", err));
347 err = Interop.PackageManager.PackageManagerRequestSetType(request, type.ToString().ToLower());
348 if (err != Interop.PackageManager.ErrorCode.None)
350 Log.Warn(LogTag, string.Format("Failed to move package. Error in setting request package type. err = {0}", err));
351 Interop.PackageManager.PackageManagerRequestDestroy(request);
356 err = Interop.PackageManager.PackageManagerRequestMove(request, packageId, (Interop.PackageManager.StorageType)newStorage);
357 if (err != Interop.PackageManager.ErrorCode.None)
359 Log.Warn(LogTag, string.Format("Failed to move package to requested location. err = {0}", err));
363 err = Interop.PackageManager.PackageManagerRequestDestroy(request);
364 if (err != Interop.PackageManager.ErrorCode.None)
366 Log.Warn(LogTag, string.Format("Failed to destroy package manager request handle. err = {0}", err));
367 // This method returns true if all other operations are completed and error occured in destroying request handle.
373 private static Interop.PackageManager.EventStatus GetFlaggedEventStatus(Interop.PackageManager.EventStatus newEvent)
375 return s_eventStatus | newEvent;
378 private static Interop.PackageManager.EventStatus GetUnflaggedEventStatus(Interop.PackageManager.EventStatus oldEvent)
380 return s_eventStatus & (~oldEvent);
383 private static void RegisterPackageManagerEventIfNeeded(Interop.PackageManager.EventStatus eventStatus)
385 if (s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null)
390 var err = Interop.PackageManager.ErrorCode.None;
391 s_packageManagerEventCallback = (packageType, packageId, eventType, eventState, progress, error, user_data) =>
395 PackageManagerEventArgs eventArgs = new PackageManagerEventArgs(packageType, packageId, (PackageEventState)eventState, progress);
396 if (eventType == Interop.PackageManager.EventType.Install)
398 s_installEventHandler?.Invoke(null, eventArgs);
400 else if (eventType == Interop.PackageManager.EventType.Uninstall)
402 s_uninstallEventHandler?.Invoke(null, eventArgs);
404 else if (eventType == Interop.PackageManager.EventType.Update)
406 s_updateEventHandler?.Invoke(null, eventArgs);
411 Log.Warn(LogTag, e.Message);
415 if (s_handle.IsInvalid)
417 err = Interop.PackageManager.PackageManagerCreate(out s_handle);
418 if (err != Interop.PackageManager.ErrorCode.None)
420 Log.Warn(LogTag, string.Format("Failed to create package manager handle. err = {0}", err));
424 if (!s_handle.IsInvalid)
426 if (s_eventStatus != eventStatus)
428 err = Interop.PackageManager.PackageManagerSetEvenStatus(s_handle, eventStatus);
429 if (err == Interop.PackageManager.ErrorCode.None)
431 s_eventStatus = eventStatus;
434 err = Interop.PackageManager.PackageManagerSetEvent(s_handle, s_packageManagerEventCallback, IntPtr.Zero);
436 if (err != Interop.PackageManager.ErrorCode.None)
438 Log.Warn(LogTag, string.Format("Failed to register callback for package manager event. err = {0}", err));
442 private static void UnregisterPackageManagerEventIfNeeded(Interop.PackageManager.EventStatus eventStatus)
444 if (s_installEventHandler != null || s_uninstallEventHandler != null || s_updateEventHandler != null)
449 if (s_handle.IsInvalid)
454 var err = Interop.PackageManager.PackageManagerUnsetEvent(s_handle);
455 if (s_eventStatus != eventStatus)
457 err = Interop.PackageManager.PackageManagerSetEvenStatus(s_handle, eventStatus);
458 if (err == Interop.PackageManager.ErrorCode.None)
460 s_eventStatus = eventStatus;
463 if (err != Interop.PackageManager.ErrorCode.None)
465 throw PackageManagerErrorFactory.GetException(err, "Failed to unregister package manager event event.");
470 internal static class PackageManagerErrorFactory
472 internal static Exception GetException(Interop.PackageManager.ErrorCode err, string message)
474 string errMessage = string.Format("{0} err = {1}", message, err);
477 case Interop.PackageManager.ErrorCode.InvalidParameter:
478 case Interop.PackageManager.ErrorCode.NoSuchPackage:
479 return new ArgumentException(errMessage);
480 case Interop.PackageManager.ErrorCode.PermissionDenied:
481 return new UnauthorizedAccessException(errMessage);
482 case Interop.PackageManager.ErrorCode.IoError:
483 return new System.IO.IOException(errMessage);
485 return new InvalidOperationException(errMessage);