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.Runtime.InteropServices;
20 using System.Threading.Tasks;
22 namespace Tizen.Applications
25 /// This class provides the methods and properties to get information about the packages.
27 /// <since_tizen> 3 </since_tizen>
30 private const string LogTag = "Tizen.Applications";
32 private string _id = string.Empty;
33 private string _mainAppId = string.Empty;
34 private string _label = string.Empty;
35 private string _iconPath = string.Empty;
36 private string _version = string.Empty;
37 private PackageType _type;
38 private Interop.PackageManager.StorageType _installedStorageType;
39 private string _rootPath = string.Empty;
40 private string _expansionPackageName = string.Empty;
41 private bool _isSystemPackage;
42 private bool _isRemovable;
43 private bool _isPreloaded;
44 private bool _isAccessible;
45 private IReadOnlyDictionary<CertificateType, PackageCertificate> _certificates;
46 private List<string> _privileges;
47 private int _installedTime;
49 private Dictionary<IntPtr, Interop.PackageManager.PackageManagerSizeInfoCallback> _packageManagerSizeInfoCallbackDict = new Dictionary<IntPtr, Interop.PackageManager.PackageManagerSizeInfoCallback>();
50 private int _callbackId = 0;
51 private List<PackageDependencyInformation> _dependencyTo;
52 private List<PackageDependencyInformation> _dependencyFrom;
53 private IReadOnlyDictionary<string, IEnumerable<string>> _allowedPackagesAndPrivilegesList;
55 private Package(string pkgId)
63 /// <since_tizen> 3 </since_tizen>
64 public string Id { get { return _id; } }
67 /// Label of the package.
69 /// <since_tizen> 3 </since_tizen>
70 public string Label { get { return _label; } }
73 /// Absolute path to the icon image.
75 /// <since_tizen> 3 </since_tizen>
76 public string IconPath { get { return _iconPath; } }
79 /// Version of the package.
81 /// <since_tizen> 3 </since_tizen>
82 public string Version { get { return _version; } }
85 /// Type of the package.
87 /// <since_tizen> 3 </since_tizen>
88 public PackageType PackageType { get { return _type; } }
91 /// Installed storage type for the package.
93 /// <since_tizen> 3 </since_tizen>
94 public StorageType InstalledStorageType { get { return (StorageType)_installedStorageType; } }
97 /// Root path for the package.
99 /// <since_tizen> 3 </since_tizen>
100 public string RootPath { get { return _rootPath; } }
103 /// Expansion package name for the package.
105 /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
106 /// <privlevel>platform</privlevel>
107 /// <since_tizen> 3 </since_tizen>
108 public string TizenExpansionPackageName { get { return _expansionPackageName; } }
111 /// Checks whether the package is a system package.
113 /// <since_tizen> 3 </since_tizen>
114 public bool IsSystemPackage { get { return _isSystemPackage; } }
117 /// Checks whether the package is removable.
119 /// <since_tizen> 3 </since_tizen>
120 public bool IsRemovable { get { return _isRemovable; } }
123 /// Checks whether the package is preloaded.
125 /// <since_tizen> 3 </since_tizen>
126 public bool IsPreloaded { get { return _isPreloaded; } }
129 /// Checks whether the current package is accessible.
131 /// <since_tizen> 3 </since_tizen>
132 public bool IsAccessible { get { return _isAccessible; } }
135 /// Certificate information for the package.
137 /// <since_tizen> 3 </since_tizen>
138 public IReadOnlyDictionary<CertificateType, PackageCertificate> Certificates { get { return _certificates; } }
141 /// Requested privilege for the package.
143 /// <since_tizen> 3 </since_tizen>
144 public IEnumerable<string> Privileges { get { return _privileges; } }
147 /// Installed time of the package.
149 /// <since_tizen> 3 </since_tizen>
150 public int InstalledTime { get { return _installedTime; } }
153 /// Main application info of the package.
155 /// <since_tizen> 6 </since_tizen>
156 public ApplicationInfo MainApplication
160 ApplicationInfo applicaionInfo = new ApplicationInfo(_mainAppId);
161 return applicaionInfo;
166 /// Retrieves all the application IDs of this package.
168 /// <returns>Returns a dictionary containing all the application information for a given application type.</returns>
169 /// <since_tizen> 3 </since_tizen>
170 public IEnumerable<ApplicationInfo> GetApplications()
172 return GetApplications(ApplicationType.All);
176 /// Retrieves all the application IDs of this package.
178 /// <param name="type">Optional: AppType enumeration value.</param>
179 /// <returns>Returns a dictionary containing all the application information for a given application type.</returns>
180 /// <since_tizen> 3 </since_tizen>
181 public IEnumerable<ApplicationInfo> GetApplications(ApplicationType type)
183 List<ApplicationInfo> appInfoList = new List<ApplicationInfo>();
184 Interop.Package.PackageInfoAppInfoCallback cb = (Interop.Package.AppType appType, string appId, IntPtr userData) =>
186 appInfoList.Add(new ApplicationInfo(appId));
190 IntPtr packageInfoHandle;
191 Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoCreate(Id, out packageInfoHandle);
192 if (err != Interop.PackageManager.ErrorCode.None)
194 Log.Warn(LogTag, string.Format("Failed to create native handle for package info of {0}. err = {1}", Id, err));
197 err = Interop.Package.PackageInfoForeachAppInfo(packageInfoHandle, (Interop.Package.AppType)type, cb, IntPtr.Zero);
198 if (err != Interop.PackageManager.ErrorCode.None)
200 Log.Warn(LogTag, string.Format("Failed to application info of {0}. err = {1}", Id, err));
203 err = Interop.Package.PackageInfoDestroy(packageInfoHandle);
204 if (err != Interop.PackageManager.ErrorCode.None)
206 Log.Warn(LogTag, string.Format("Failed to destroy native handle for package info of {0}. err = {1}", Id, err));
212 /// Retrieves all the application IDs of this package.
214 /// <param name="componentType">Optional: AppType enumeration value.</param>
215 /// <returns>Returns a dictionary containing all the application information for a given application type.</returns>
216 /// <since_tizen> 6 </since_tizen>
217 public IEnumerable<ApplicationInfo> GetApplications(ApplicationComponentType componentType)
219 return GetApplications(ToApplicationType(componentType));
223 /// Packages required by this package
225 /// <since_tizen> 6 </since_tizen>
226 public IEnumerable<PackageDependencyInformation> DependencyTo { get { return _dependencyTo; } }
229 /// Packages that require this package
231 /// <since_tizen> 6 </since_tizen>
232 public IEnumerable<PackageDependencyInformation> DependencyFrom { get { return _dependencyFrom; } }
235 /// Gets the package size information.
237 /// <returns>Package size information.</returns>
238 /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
239 /// <since_tizen> 3 </since_tizen>
240 public async Task<PackageSizeInformation> GetSizeInformationAsync()
242 TaskCompletionSource<PackageSizeInformation> tcs = new TaskCompletionSource<PackageSizeInformation>();
243 Interop.PackageManager.PackageManagerSizeInfoCallback sizeInfoCb = (pkgId, sizeInfoHandle, userData) =>
245 if (sizeInfoHandle != IntPtr.Zero && Id == pkgId)
247 var pkgSizeInfo = PackageSizeInformation.GetPackageSizeInformation(sizeInfoHandle);
248 tcs.TrySetResult(pkgSizeInfo);
251 lock (_packageManagerSizeInfoCallbackDict)
253 _packageManagerSizeInfoCallbackDict.Remove(userData);
258 lock (_packageManagerSizeInfoCallbackDict)
260 callbackId = (IntPtr)_callbackId++;
261 _packageManagerSizeInfoCallbackDict[callbackId] = sizeInfoCb;
264 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetSizeInfo(Id, sizeInfoCb, callbackId);
265 if (err != Interop.PackageManager.ErrorCode.None)
267 tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info of " + Id));
269 return await tcs.Task.ConfigureAwait(false);
273 /// Compares the certificate information with the given package ID.
275 /// <param name="packageId">ID of the package.</param>
276 /// <returns>Certificate comparison result.</returns>
277 /// <exception cref="ArgumentException">Thrown when a failed input package ID is invalid.</exception>
278 /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal I/O error.</exception>
279 /// <since_tizen> 3 </since_tizen>
280 public CertCompareResultType CompareCertInfo(string packageId)
282 Interop.PackageManager.CertCompareResultType compareResult;
283 Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfo(Id, packageId, out compareResult);
284 if (err != Interop.PackageManager.ErrorCode.None)
286 throw PackageManagerErrorFactory.GetException(err, "Failed to compare package cert info");
289 return (CertCompareResultType)compareResult;
293 /// The allowed packages and required privileges information.
295 /// <remarks> The dictionary contains application IDs as the keys, and a collection of privileges related to that application as the value.</remarks>
296 /// <since_tizen> 9 </since_tizen>
297 public IReadOnlyDictionary<string, IEnumerable<string>> AllowedPackagesAndPrivileges
299 get { return _allowedPackagesAndPrivilegesList; }
302 // This method assumes that given arguments are already validated and have valid values.
303 internal static Package CreatePackage(IntPtr handle, string pkgId)
305 Package package = new Package(pkgId);
307 var err = Interop.PackageManager.ErrorCode.None;
308 err = Interop.Package.PackageInfoGetMainAppId(handle, out package._mainAppId);
309 if (err != Interop.PackageManager.ErrorCode.None)
311 Log.Warn(LogTag, "Failed to get package main app id of " + pkgId);
313 err = Interop.Package.PackageInfoGetLabel(handle, out package._label);
314 if (err != Interop.PackageManager.ErrorCode.None)
316 Log.Warn(LogTag, "Failed to get package label of " + pkgId);
318 err = Interop.Package.PackageInfoGetIconPath(handle, out package._iconPath);
319 if (err != Interop.PackageManager.ErrorCode.None)
321 Log.Warn(LogTag, "Failed to get package icon path of " + pkgId);
323 err = Interop.Package.PackageInfoGetVersion(handle, out package._version);
324 if (err != Interop.PackageManager.ErrorCode.None)
326 Log.Warn(LogTag, "Failed to get package version of " + pkgId);
330 Interop.Package.PackageInfoGetType(handle, out type);
331 if (Enum.TryParse(type, true, out package._type) == false)
333 Log.Warn(LogTag, "Failed to get package type of " + pkgId);
335 err = Interop.Package.PackageInfoGetRootPath(handle, out package._rootPath);
336 if (err != Interop.PackageManager.ErrorCode.None)
338 Log.Warn(LogTag, "Failed to get package root directory of " + pkgId);
340 err = Interop.Package.PackageInfoGetTepName(handle, out package._expansionPackageName);
341 if (err != Interop.PackageManager.ErrorCode.None)
343 Log.Warn(LogTag, "Failed to get expansion package name of " + pkgId);
344 package._expansionPackageName = string.Empty;
347 err = Interop.Package.PackageInfoGetInstalledStorage(handle, out package._installedStorageType);
348 if (err != Interop.PackageManager.ErrorCode.None)
350 Log.Warn(LogTag, "Failed to get installed storage type of " + pkgId);
352 Interop.Package.PackageInfoIsSystemPackage(handle, out package._isSystemPackage);
353 if (err != Interop.PackageManager.ErrorCode.None)
355 Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is system package or not");
357 Interop.Package.PackageInfoIsRemovablePackage(handle, out package._isRemovable);
358 if (err != Interop.PackageManager.ErrorCode.None)
360 Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is removable or not");
362 Interop.Package.PackageInfoIsPreloadPackage(handle, out package._isPreloaded);
363 if (err != Interop.PackageManager.ErrorCode.None)
365 Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is preloaded or not");
367 Interop.Package.PackageInfoIsAccessible(handle, out package._isAccessible);
368 if (err != Interop.PackageManager.ErrorCode.None)
370 Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is accessible or not");
374 Interop.Package.PackageInfoGetInstalledTime(handle, out package._installedTime);
375 if (err != Interop.PackageManager.ErrorCode.None)
377 Log.Warn(LogTag, "Failed to get installed time of " + pkgId);
380 catch (TypeLoadException)
382 // To support in API vesion 3.0
383 package._installedTime = 0;
386 package._certificates = PackageCertificate.GetPackageCertificates(handle);
387 package._privileges = GetPackagePrivilegeInformation(handle);
388 package._dependencyTo = GetPackageDependency(handle);
389 package._dependencyFrom = GetPackageDependencyDependsOn(handle);
390 package._allowedPackagesAndPrivilegesList = GetAllowedPackagesAndPrivileges(handle);
394 internal static Package GetPackage(string packageId)
396 IntPtr packageInfoHandle;
397 Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoCreate(packageId, out packageInfoHandle);
398 if (err != Interop.PackageManager.ErrorCode.None)
400 throw PackageManagerErrorFactory.GetException(err, string.Format("Failed to create native handle for package info of {0}", packageId));
403 Package package = CreatePackage(packageInfoHandle, packageId);
405 err = Interop.Package.PackageInfoDestroy(packageInfoHandle);
406 if (err != Interop.PackageManager.ErrorCode.None)
408 Log.Warn(LogTag, string.Format("Failed to destroy native handle for package info of {0}. err = {1}", packageId, err));
413 internal static Package GetPackage(IntPtr packageInfoHandle)
416 Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoGetPackage(packageInfoHandle, out packageId);
417 if (err != Interop.PackageManager.ErrorCode.None)
419 throw PackageManagerErrorFactory.GetException(err, "Failed to get package id for given package handle.");
421 return CreatePackage(packageInfoHandle, packageId);
424 private static List<string> GetPackagePrivilegeInformation(IntPtr packageInfoHandle)
426 List<string> privileges = new List<string>();
427 Interop.Package.PackageInfoPrivilegeInfoCallback privilegeInfoCb = (privilege, userData) =>
429 privileges.Add(privilege);
433 Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoForeachPrivilegeInfo(packageInfoHandle, privilegeInfoCb, IntPtr.Zero);
434 if (err != Interop.PackageManager.ErrorCode.None)
436 Log.Warn(LogTag, string.Format("Failed to get privilage info. err = {0}", err));
441 private ApplicationType ToApplicationType(ApplicationComponentType componentType)
443 ApplicationType applicationType = 0;
444 if (componentType == Tizen.Applications.ApplicationComponentType.UIApplication)
445 applicationType = Tizen.Applications.ApplicationType.Ui;
446 else if (componentType == Tizen.Applications.ApplicationComponentType.ServiceApplication)
447 applicationType = Tizen.Applications.ApplicationType.Service;
448 else if (componentType == Tizen.Applications.ApplicationComponentType.WidgetApplication)
449 applicationType = Tizen.Applications.ApplicationType.Widget;
450 else if (componentType == Tizen.Applications.ApplicationComponentType.WatchApplication)
451 applicationType = Tizen.Applications.ApplicationType.Watch;
453 return applicationType;
456 private static List<PackageDependencyInformation> GetPackageDependency(IntPtr packageInfoHandle)
458 List<PackageDependencyInformation> dependencies = new List<PackageDependencyInformation>();
459 Interop.Package.PackageInfoDependencyInfoCallback dependencyInfoCb = (from, to, type, requiredVersion, userData) =>
461 dependencies.Add(PackageDependencyInformation.GetPackageDependencyInformation(from, to, type, requiredVersion));
465 Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoForeachDependencyInfo(packageInfoHandle, dependencyInfoCb, IntPtr.Zero);
466 if (err != Interop.PackageManager.ErrorCode.None)
468 Log.Warn(LogTag, string.Format("Failed to get dependency info. err = {0}", err));
473 private static List<PackageDependencyInformation> GetPackageDependencyDependsOn(IntPtr packageInfoHandle)
475 List<PackageDependencyInformation> dependencies = new List<PackageDependencyInformation>();
476 Interop.Package.PackageInfoDependencyInfoCallback dependencyInfoCb = (from, to, type, requiredVersion, userData) =>
478 dependencies.Add(PackageDependencyInformation.GetPackageDependencyInformation(from, to, type, requiredVersion));
482 Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoForeachDependencyInfoDependsOn(packageInfoHandle, dependencyInfoCb, IntPtr.Zero);
483 if (err != Interop.PackageManager.ErrorCode.None)
485 Log.Warn(LogTag, string.Format("Failed to get dependency info. err = {0}", err));
490 private static Dictionary<string, IEnumerable<string>> GetAllowedPackagesAndPrivileges(IntPtr packageInfoHandle)
492 Interop.PackageManager.ErrorCode err;
493 Dictionary<string, IEnumerable<string>> allowedPackagesAndPrivileges = new Dictionary<string, IEnumerable<string>>();
494 Interop.Package.PackageInfoResAllowedPackageCallback allowedPackageCallback = (allowedPackage, requiredPrivileges, userData) =>
496 List<string> requiredPrivilegesList = new List<string>();
497 Interop.Package.PackageInfoPrivilegeInfoCallback requiredPrivCallback = (priv, requiredPrivCbUserData) =>
499 requiredPrivilegesList.Add(priv);
502 err = Interop.Package.PackageInfoForeachRequiredPrivilege(requiredPrivileges, requiredPrivCallback, IntPtr.Zero);
503 if (err != Interop.PackageManager.ErrorCode.None)
505 Log.Warn(LogTag, string.Format("Failed to get required privileges of allowed packages info. err = {0}", err));
509 allowedPackagesAndPrivileges.Add(allowedPackage, requiredPrivilegesList);
514 err = Interop.Package.PackageInfoForeachResAllowedPackage(packageInfoHandle, allowedPackageCallback, IntPtr.Zero);
515 if (err != Interop.PackageManager.ErrorCode.None)
517 Log.Warn(LogTag, string.Format("Failed to get allowed packages info. err = {0}", err));
519 return allowedPackagesAndPrivileges;