[Application] Add more method in ApplicationInfo class (#732)
[platform/core/csapi/tizenfx.git] / src / Tizen.Applications.PackageManager / Tizen.Applications / Package.cs
1 /*
2  * Copyright (c) 2018 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  * Licensed under the Apache License, Version 2.0 (the License);
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an AS IS BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 using System;
18 using System.Collections.Generic;
19 using System.Runtime.InteropServices;
20 using System.Threading.Tasks;
21
22 namespace Tizen.Applications
23 {
24     /// <summary>
25     /// This class provides the methods and properties to get information about the packages.
26     /// </summary>
27     /// <since_tizen> 3 </since_tizen>
28     public class Package
29     {
30         private const string LogTag = "Tizen.Applications";
31
32         private string _id = string.Empty;
33         private string _label = string.Empty;
34         private string _iconPath = string.Empty;
35         private string _version = string.Empty;
36         private PackageType _type;
37         private Interop.PackageManager.StorageType _installedStorageType;
38         private string _rootPath = string.Empty;
39         private string _expansionPackageName = string.Empty;
40         private bool _isSystemPackage;
41         private bool _isRemovable;
42         private bool _isPreloaded;
43         private bool _isAccessible;
44         private IReadOnlyDictionary<CertificateType, PackageCertificate> _certificates;
45         private List<string> _privileges;
46         private int _installedTime;
47
48         private Dictionary<IntPtr, Interop.PackageManager.PackageManagerSizeInfoCallback> _packageManagerSizeInfoCallbackDict = new Dictionary<IntPtr, Interop.PackageManager.PackageManagerSizeInfoCallback>();
49         private int _callbackId = 0;
50
51         private Package(string pkgId)
52         {
53             _id = pkgId;
54         }
55
56         /// <summary>
57         /// The package ID.
58         /// </summary>
59         /// <since_tizen> 3 </since_tizen>
60         public string Id { get { return _id; } }
61
62         /// <summary>
63         /// Label of the package.
64         /// </summary>
65         /// <since_tizen> 3 </since_tizen>
66         public string Label { get { return _label; } }
67
68         /// <summary>
69         /// Absolute path to the icon image.
70         /// </summary>
71         /// <since_tizen> 3 </since_tizen>
72         public string IconPath { get { return _iconPath; } }
73
74         /// <summary>
75         /// Version of the package.
76         /// </summary>
77         /// <since_tizen> 3 </since_tizen>
78         public string Version { get { return _version; } }
79
80         /// <summary>
81         /// Type of the package.
82         /// </summary>
83         /// <since_tizen> 3 </since_tizen>
84         public PackageType PackageType { get { return _type; } }
85
86         /// <summary>
87         /// Installed storage type for the package.
88         /// </summary>
89         /// <since_tizen> 3 </since_tizen>
90         public StorageType InstalledStorageType { get { return (StorageType)_installedStorageType; } }
91
92         /// <summary>
93         /// Root path for the package.
94         /// </summary>
95         /// <since_tizen> 3 </since_tizen>
96         public string RootPath { get { return _rootPath; } }
97
98         /// <summary>
99         /// Expansion package name for the package.
100         /// </summary>
101         /// <privilege>http://tizen.org/privilege/packagemanager.admin</privilege>
102         /// <privlevel>platform</privlevel>
103         /// <since_tizen> 3 </since_tizen>
104         public string TizenExpansionPackageName { get { return _expansionPackageName; } }
105
106         /// <summary>
107         /// Checks whether the package is a system package.
108         /// </summary>
109         /// <since_tizen> 3 </since_tizen>
110         public bool IsSystemPackage { get { return _isSystemPackage; } }
111
112         /// <summary>
113         /// Checks whether the package is removable.
114         /// </summary>
115         /// <since_tizen> 3 </since_tizen>
116         public bool IsRemovable { get { return _isRemovable; } }
117
118         /// <summary>
119         /// Checks whether the package is preloaded.
120         /// </summary>
121         /// <since_tizen> 3 </since_tizen>
122         public bool IsPreloaded { get { return _isPreloaded; } }
123
124         /// <summary>
125         /// Checks whether the current package is accessible.
126         /// </summary>
127         /// <since_tizen> 3 </since_tizen>
128         public bool IsAccessible { get { return _isAccessible; } }
129
130         /// <summary>
131         /// Certificate information for the package.
132         /// </summary>
133         /// <since_tizen> 3 </since_tizen>
134         public IReadOnlyDictionary<CertificateType, PackageCertificate> Certificates { get { return _certificates; } }
135
136         /// <summary>
137         /// Requested privilege for the package.
138         /// </summary>
139         /// <since_tizen> 3 </since_tizen>
140         public IEnumerable<string> Privileges { get { return _privileges; } }
141
142         /// <summary>
143         /// Installed time of the package.
144         /// </summary>
145         /// <since_tizen> 3 </since_tizen>
146         public int InstalledTime { get { return _installedTime; } }
147
148         /// <summary>
149         /// Retrieves all the application IDs of this package.
150         /// </summary>
151         /// <returns>Returns a dictionary containing all the application information for a given application type.</returns>
152         /// <since_tizen> 3 </since_tizen>
153         public IEnumerable<ApplicationInfo> GetApplications()
154         {
155             return GetApplications(ApplicationType.All);
156         }
157
158         /// <summary>
159         /// Retrieves all the application IDs of this package.
160         /// </summary>
161         /// <param name="type">Optional: AppType enumeration value.</param>
162         /// <returns>Returns a dictionary containing all the application information for a given application type.</returns>
163         /// <since_tizen> 3 </since_tizen>
164         public IEnumerable<ApplicationInfo> GetApplications(ApplicationType type)
165         {
166             List<ApplicationInfo> appInfoList = new List<ApplicationInfo>();
167             Interop.Package.PackageInfoAppInfoCallback cb = (Interop.Package.AppType appType, string appId, IntPtr userData) =>
168             {
169                 appInfoList.Add(new ApplicationInfo(appId));
170                 return true;
171             };
172
173             IntPtr packageInfoHandle;
174             Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoCreate(Id, out packageInfoHandle);
175             if (err != Interop.PackageManager.ErrorCode.None)
176             {
177                 Log.Warn(LogTag, string.Format("Failed to create native handle for package info of {0}. err = {1}", Id, err));
178             }
179
180             err = Interop.Package.PackageInfoForeachAppInfo(packageInfoHandle, (Interop.Package.AppType)type, cb, IntPtr.Zero);
181             if (err != Interop.PackageManager.ErrorCode.None)
182             {
183                 Log.Warn(LogTag, string.Format("Failed to application info of {0}. err = {1}", Id, err));
184             }
185
186             err = Interop.Package.PackageInfoDestroy(packageInfoHandle);
187             if (err != Interop.PackageManager.ErrorCode.None)
188             {
189                 Log.Warn(LogTag, string.Format("Failed to destroy native handle for package info of {0}. err = {1}", Id, err));
190             }
191             return appInfoList;
192         }
193
194         /// <summary>
195         /// Retrieves all the application IDs of this package.
196         /// </summary>
197         /// <param name="componentType">Optional: AppType enumeration value.</param>
198         /// <returns>Returns a dictionary containing all the application information for a given application type.</returns>
199         /// <since_tizen> 6 </since_tizen>
200         public IEnumerable<ApplicationInfo> GetApplications(ApplicationComponentType componentType)
201         {
202             return GetApplications(ToApplicationType(componentType));
203         }
204
205         /// <summary>
206         /// Gets the package size information.
207         /// </summary>
208         /// <returns>Package size information.</returns>
209         /// <privilege>http://tizen.org/privilege/packagemanager.info</privilege>
210         /// <since_tizen> 3 </since_tizen>
211         public async Task<PackageSizeInformation> GetSizeInformationAsync()
212         {
213             TaskCompletionSource<PackageSizeInformation> tcs = new TaskCompletionSource<PackageSizeInformation>();
214             Interop.PackageManager.PackageManagerSizeInfoCallback sizeInfoCb = (pkgId, sizeInfoHandle, userData) =>
215             {
216                 if (sizeInfoHandle != IntPtr.Zero && Id == pkgId)
217                 {
218                     var pkgSizeInfo = PackageSizeInformation.GetPackageSizeInformation(sizeInfoHandle);
219                     tcs.TrySetResult(pkgSizeInfo);
220                 }
221
222                 lock (_packageManagerSizeInfoCallbackDict)
223                 {
224                     _packageManagerSizeInfoCallbackDict.Remove(userData);
225                 }
226             };
227
228             IntPtr callbackId;
229             lock (_packageManagerSizeInfoCallbackDict)
230             {
231                 callbackId = (IntPtr)_callbackId++;
232                 _packageManagerSizeInfoCallbackDict[callbackId] = sizeInfoCb;
233             }
234
235             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerGetSizeInfo(Id, sizeInfoCb, callbackId);
236             if (err != Interop.PackageManager.ErrorCode.None)
237             {
238                 tcs.TrySetException(PackageManagerErrorFactory.GetException(err, "Failed to get total package size info of " + Id));
239             }
240             return await tcs.Task.ConfigureAwait(false);
241         }
242
243         /// <summary>
244         /// Compares the certificate information with the given package ID.
245         /// </summary>
246         /// <param name="packageId">ID of the package.</param>
247         /// <returns>Certificate comparison result.</returns>
248         /// <exception cref="ArgumentException">Thrown when a failed input package ID is invalid.</exception>
249         /// <exception cref="System.IO.IOException">Thrown when the method failed due to an internal I/O error.</exception>
250         /// <since_tizen> 3 </since_tizen>
251         public CertCompareResultType CompareCertInfo(string packageId)
252         {
253             Interop.PackageManager.CertCompareResultType compareResult;
254             Interop.PackageManager.ErrorCode err = Interop.PackageManager.PackageManagerCompareCertInfo(Id, packageId, out compareResult);
255             if (err != Interop.PackageManager.ErrorCode.None)
256             {
257                 throw PackageManagerErrorFactory.GetException(err, "Failed to compare package cert info");
258             }
259
260             return (CertCompareResultType)compareResult;
261         }
262
263         // This method assumes that given arguments are already validated and have valid values.
264         internal static Package CreatePackage(IntPtr handle, string pkgId)
265         {
266             Package package = new Package(pkgId);
267
268             var err = Interop.PackageManager.ErrorCode.None;
269             err = Interop.Package.PackageInfoGetLabel(handle, out package._label);
270             if (err != Interop.PackageManager.ErrorCode.None)
271             {
272                 Log.Warn(LogTag, "Failed to get package label of " + pkgId);
273             }
274             err = Interop.Package.PackageInfoGetIconPath(handle, out package._iconPath);
275             if (err != Interop.PackageManager.ErrorCode.None)
276             {
277                 Log.Warn(LogTag, "Failed to get package icon path of " + pkgId);
278             }
279             err = Interop.Package.PackageInfoGetVersion(handle, out package._version);
280             if (err != Interop.PackageManager.ErrorCode.None)
281             {
282                 Log.Warn(LogTag, "Failed to get package version of " + pkgId);
283             }
284
285             string type;
286             Interop.Package.PackageInfoGetType(handle, out type);
287             if (Enum.TryParse(type, true, out package._type) == false)
288             {
289                 Log.Warn(LogTag, "Failed to get package type of " + pkgId);
290             }
291             err = Interop.Package.PackageInfoGetRootPath(handle, out package._rootPath);
292             if (err != Interop.PackageManager.ErrorCode.None)
293             {
294                 Log.Warn(LogTag, "Failed to get package root directory of " + pkgId);
295             }
296             err = Interop.Package.PackageInfoGetTepName(handle, out package._expansionPackageName);
297             if (err != Interop.PackageManager.ErrorCode.None)
298             {
299                 Log.Warn(LogTag, "Failed to get expansion package name of " + pkgId);
300                 package._expansionPackageName = string.Empty;
301             }
302
303             err = Interop.Package.PackageInfoGetInstalledStorage(handle, out package._installedStorageType);
304             if (err != Interop.PackageManager.ErrorCode.None)
305             {
306                 Log.Warn(LogTag, "Failed to get installed storage type of " + pkgId);
307             }
308             Interop.Package.PackageInfoIsSystemPackage(handle, out package._isSystemPackage);
309             if (err != Interop.PackageManager.ErrorCode.None)
310             {
311                 Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is system package or not");
312             }
313             Interop.Package.PackageInfoIsRemovablePackage(handle, out package._isRemovable);
314             if (err != Interop.PackageManager.ErrorCode.None)
315             {
316                 Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is removable or not");
317             }
318             Interop.Package.PackageInfoIsPreloadPackage(handle, out package._isPreloaded);
319             if (err != Interop.PackageManager.ErrorCode.None)
320             {
321                 Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is preloaded or not");
322             }
323             Interop.Package.PackageInfoIsAccessible(handle, out package._isAccessible);
324             if (err != Interop.PackageManager.ErrorCode.None)
325             {
326                 Log.Warn(LogTag, "Failed to get whether package " + pkgId + " is accessible or not");
327             }
328             try
329             {
330                 Interop.Package.PackageInfoGetInstalledTime(handle, out package._installedTime);
331                 if (err != Interop.PackageManager.ErrorCode.None)
332                 {
333                     Log.Warn(LogTag, "Failed to get installed time of " + pkgId);
334                 }
335             }
336             catch (TypeLoadException)
337             {
338                 // To support in API vesion 3.0
339                 package._installedTime = 0;
340             }
341
342             package._certificates = PackageCertificate.GetPackageCertificates(handle);
343             package._privileges = GetPackagePrivilegeInformation(handle);
344             return package;
345         }
346
347         internal static Package GetPackage(string packageId)
348         {
349             IntPtr packageInfoHandle;
350             Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoCreate(packageId, out packageInfoHandle);
351             if (err != Interop.PackageManager.ErrorCode.None)
352             {
353                 throw PackageManagerErrorFactory.GetException(err, string.Format("Failed to create native handle for package info of {0}", packageId));
354             }
355
356             Package package = CreatePackage(packageInfoHandle, packageId);
357
358             err = Interop.Package.PackageInfoDestroy(packageInfoHandle);
359             if (err != Interop.PackageManager.ErrorCode.None)
360             {
361                 Log.Warn(LogTag, string.Format("Failed to destroy native handle for package info of {0}. err = {1}", packageId, err));
362             }
363             return package;
364         }
365
366         internal static Package GetPackage(IntPtr packageInfoHandle)
367         {
368             String packageId;
369             Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoGetPackage(packageInfoHandle, out packageId);
370             if (err != Interop.PackageManager.ErrorCode.None)
371             {
372                 throw PackageManagerErrorFactory.GetException(err, "Failed to get package id for given package handle.");
373             }
374             return CreatePackage(packageInfoHandle, packageId);
375         }
376
377         private static List<string> GetPackagePrivilegeInformation(IntPtr packageInfoHandle)
378         {
379             List<string> privileges = new List<string>();
380             Interop.Package.PackageInfoPrivilegeInfoCallback privilegeInfoCb = (privilege, userData) =>
381             {
382                 privileges.Add(privilege);
383                 return true;
384             };
385
386             Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoForeachPrivilegeInfo(packageInfoHandle, privilegeInfoCb, IntPtr.Zero);
387             if (err != Interop.PackageManager.ErrorCode.None)
388             {
389                 Log.Warn(LogTag, string.Format("Failed to get privilage info. err = {0}", err));
390             }
391             return privileges;
392         }
393
394         private ApplicationType ToApplicationType(ApplicationComponentType componentType)
395         {
396             ApplicationType applicationType = 0;
397             if (componentType == Tizen.Applications.ApplicationComponentType.UIApplication)
398                 applicationType = Tizen.Applications.ApplicationType.Ui;
399             else if (componentType == Tizen.Applications.ApplicationComponentType.ServiceApplication)
400                 applicationType = Tizen.Applications.ApplicationType.Service;
401             else if (componentType == Tizen.Applications.ApplicationComponentType.WidgetApplication)
402                 applicationType = Tizen.Applications.ApplicationType.Widget;
403             else if (componentType == Tizen.Applications.ApplicationComponentType.WatchApplication)
404                 applicationType = Tizen.Applications.ApplicationType.Watch;
405
406             return applicationType;
407         }
408     }
409 }