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