[Packagemanager] Fix Tizen.Applications.Package for performance (#5794)
authorjeremy-jang <35089715+jeremy-jang@users.noreply.github.com>
Wed, 6 Dec 2023 06:19:43 +0000 (15:19 +0900)
committerGitHub <noreply@github.com>
Wed, 6 Dec 2023 06:19:43 +0000 (15:19 +0900)
Adjust lazy initialization on DependencyFrom, Certificate property.
These properties need additional IPC platform internally, so make these
property initialized lazily for performance.

Signed-off-by: Sangyoon Jang <jeremy.jang@samsung.com>
src/Tizen.Applications.PackageManager/Interop/Interop.Libraries.cs
src/Tizen.Applications.PackageManager/Interop/Interop.Package.cs
src/Tizen.Applications.PackageManager/Interop/Interop.PackageManagerInfoInternal.cs [new file with mode: 0755]
src/Tizen.Applications.PackageManager/Tizen.Applications/Package.cs
src/Tizen.Applications.PackageManager/Tizen.Applications/PackageCertificate.cs

index f486d8c..c093b03 100755 (executable)
@@ -20,5 +20,7 @@ internal static partial class Interop
     {
         public const string PackageManager = "libcapi-appfw-package-manager.so.0";
         public const string PackageManagerInternal = "libpkgmgr-client.so.0";
+        public const string PackageManagerInfoInternal = "libpkgmgr-info.so.0";
+        public const string Libc = "libc.so.6";
     }
 }
index 02b03b5..2e5ace5 100644 (file)
@@ -64,9 +64,6 @@ internal static partial class Interop
         [DllImport(Libraries.PackageManager, EntryPoint = "package_info_foreach_app_from_package")]
         internal static extern ErrorCode PackageInfoForeachAppInfo(IntPtr handle, AppType appType, PackageInfoAppInfoCallback callback, IntPtr userData);
 
-        [DllImport(Libraries.PackageManager, EntryPoint = "package_info_foreach_cert_info")]
-        internal static extern ErrorCode PackageInfoForeachCertificateInfo(IntPtr handle, PackageInfoCertificateInfoCallback callback, IntPtr user_data);
-
         [DllImport(Libraries.PackageManager, EntryPoint = "package_info_foreach_privilege_info")]
         internal static extern ErrorCode PackageInfoForeachPrivilegeInfo(IntPtr handle, PackageInfoPrivilegeInfoCallback callback, IntPtr userData);
 
diff --git a/src/Tizen.Applications.PackageManager/Interop/Interop.PackageManagerInfoInternal.cs b/src/Tizen.Applications.PackageManager/Interop/Interop.PackageManagerInfoInternal.cs
new file mode 100755 (executable)
index 0000000..edbcec6
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2023 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using CertificateType = Interop.Package.CertificateType;
+
+internal static partial class Interop
+{
+    internal static partial class PackageManagerInfoInternal
+    {
+        [DllImport(Libraries.PackageManagerInfoInternal, EntryPoint = "pkgmgrinfo_pkginfo_create_certinfo")]
+        internal static extern int PkgmgrinfoPkginfoCreateCertinfo(out IntPtr handle);
+
+        [DllImport(Libraries.PackageManagerInfoInternal, EntryPoint = "pkgmgrinfo_pkginfo_destroy_certinfo")]
+        internal static extern int PkgmgrinfoPkginfoDestroyCertinfo(IntPtr handle);
+
+        [DllImport(Libraries.PackageManagerInfoInternal, EntryPoint = "pkgmgrinfo_pkginfo_load_certinfo")]
+        internal static extern int PkgmgrinfoPkginfoLoadCertinfo(string pkgid, IntPtr handle, int uid);
+
+        [DllImport(Libraries.PackageManagerInfoInternal, EntryPoint = "pkgmgrinfo_pkginfo_get_cert_value")]
+        internal static extern int PkgmgrinfoPkginfoGetCertValue(IntPtr handle, CertificateType certType, out IntPtr value);
+
+        [DllImport(Libraries.PackageManagerInfoInternal, EntryPoint = "pkgmgrinfo_pkginfo_foreach_depends_on_by_pkgid")]
+        internal static extern int PkgmgrinfoPkginfoForeachDependsOnByPkgId(string pkgid, Interop.Package.PackageInfoDependencyInfoCallback callback, IntPtr userData, int uid);
+
+        [DllImport(Libraries.Libc, EntryPoint = "getuid")]
+        internal static extern int GetUID();
+    }
+}
index 7932ac4..5de2b1b 100644 (file)
@@ -42,14 +42,14 @@ namespace Tizen.Applications
         private bool _isRemovable;
         private bool _isPreloaded;
         private bool _isAccessible;
-        private IReadOnlyDictionary<CertificateType, PackageCertificate> _certificates;
+        private Lazy<IReadOnlyDictionary<CertificateType, PackageCertificate>> _certificates;
         private List<string> _privileges;
         private int _installedTime;
 
         private Dictionary<IntPtr, Interop.PackageManager.PackageManagerSizeInfoCallback> _packageManagerSizeInfoCallbackDict = new Dictionary<IntPtr, Interop.PackageManager.PackageManagerSizeInfoCallback>();
         private int _callbackId = 0;
         private List<PackageDependencyInformation> _dependencyTo;
-        private List<PackageDependencyInformation> _dependencyFrom;
+        private Lazy<List<PackageDependencyInformation>> _dependencyFrom;
         private IReadOnlyDictionary<string, IEnumerable<string>> _allowedPackagesAndPrivilegesList;
 
         private Package(string pkgId)
@@ -135,7 +135,7 @@ namespace Tizen.Applications
         /// Certificate information for the package.
         /// </summary>
         /// <since_tizen> 3 </since_tizen>
-        public IReadOnlyDictionary<CertificateType, PackageCertificate> Certificates { get { return _certificates; } }
+        public IReadOnlyDictionary<CertificateType, PackageCertificate> Certificates { get { return _certificates.Value; } }
 
         /// <summary>
         /// Requested privilege for the package.
@@ -229,7 +229,7 @@ namespace Tizen.Applications
         /// Packages that require this package
         /// </summary>
         /// <since_tizen> 6 </since_tizen>
-        public IEnumerable<PackageDependencyInformation> DependencyFrom { get { return _dependencyFrom; } }
+        public IEnumerable<PackageDependencyInformation> DependencyFrom { get { return _dependencyFrom.Value; } }
 
         /// <summary>
         /// Gets the package size information.
@@ -383,10 +383,10 @@ namespace Tizen.Applications
                 package._installedTime = 0;
             }
 
-            package._certificates = PackageCertificate.GetPackageCertificates(handle);
+            package._certificates = new Lazy<IReadOnlyDictionary<CertificateType, PackageCertificate>>(() => { return PackageCertificate.GetPackageCertificates(pkgId); });
             package._privileges = GetPackagePrivilegeInformation(handle);
             package._dependencyTo = GetPackageDependency(handle);
-            package._dependencyFrom = GetPackageDependencyDependsOn(handle);
+            package._dependencyFrom = new Lazy<List<PackageDependencyInformation>>(() => { return GetPackageDependencyDependsOn(pkgId); });
             package._allowedPackagesAndPrivilegesList = GetAllowedPackagesAndPrivileges(handle);
             return package;
         }
@@ -470,7 +470,7 @@ namespace Tizen.Applications
             return dependencies;
         }
 
-        private static List<PackageDependencyInformation> GetPackageDependencyDependsOn(IntPtr packageInfoHandle)
+        private static List<PackageDependencyInformation> GetPackageDependencyDependsOn(string packageId)
         {
             List<PackageDependencyInformation> dependencies = new List<PackageDependencyInformation>();
             Interop.Package.PackageInfoDependencyInfoCallback dependencyInfoCb = (from, to, type, requiredVersion, userData) =>
@@ -478,9 +478,8 @@ namespace Tizen.Applications
                 dependencies.Add(PackageDependencyInformation.GetPackageDependencyInformation(from, to, type, requiredVersion));
                 return true;
             };
-
-            Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoForeachDependencyInfoDependsOn(packageInfoHandle, dependencyInfoCb, IntPtr.Zero);
-            if (err != Interop.PackageManager.ErrorCode.None)
+            int err = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoForeachDependsOnByPkgId(packageId, dependencyInfoCb, IntPtr.Zero, Interop.PackageManagerInfoInternal.GetUID());
+            if (err != 0)
             {
                 Log.Warn(LogTag, string.Format("Failed to get dependency info. err = {0}", err));
             }
index ed68134..1fa88fd 100755 (executable)
@@ -57,53 +57,55 @@ namespace Tizen.Applications
         /// <since_tizen> 3 </since_tizen>
         public string Signer { get { return _signer; } }
 
-        internal static IReadOnlyDictionary<CertificateType, PackageCertificate> GetPackageCertificates(IntPtr packageInfoHandle)
+        internal static IReadOnlyDictionary<CertificateType, PackageCertificate> GetPackageCertificates(string packageId)
         {
-            Dictionary<Interop.Package.CertificateType, string> nativeCertificates = new Dictionary<Interop.Package.CertificateType, string>();
-            Interop.Package.PackageInfoCertificateInfoCallback certificateInfoCb = (handle, certType, certValue, userData) =>
+            Dictionary<CertificateType, PackageCertificate> certificates = new Dictionary<CertificateType, PackageCertificate>();
+
+            int ret = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoCreateCertinfo(out IntPtr handle);
+            if (ret != 0)
             {
-                if (certValue == null) certValue = string.Empty;
-                try
-                {
-                    nativeCertificates.Add(certType, certValue);
-                }
-                catch (ArgumentException ex)
-                {
-                    Log.Warn(LogTag, string.Format("Failed to add cert value. certType = {0}, err = {1}", certType, ex.Message));
-                }
-                return true;
-            };
+                Log.Error(LogTag, string.Format("Failed to create cert info handle"));
+                return certificates;
+            }
 
-            Interop.PackageManager.ErrorCode err = Interop.Package.PackageInfoForeachCertificateInfo(packageInfoHandle, certificateInfoCb, IntPtr.Zero);
-            if (err != Interop.PackageManager.ErrorCode.None)
+            ret = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoLoadCertinfo(packageId, handle, Interop.PackageManagerInfoInternal.GetUID());
+            if (ret != 0)
             {
-                Log.Warn(LogTag, string.Format("Failed to get certificate info. err = {0}", err));
+                Log.Error(LogTag, string.Format("Failed to load cert info of {0}", packageId));
+                return certificates;
             }
 
-            Dictionary<CertificateType, PackageCertificate> certificates = new Dictionary<CertificateType, PackageCertificate>();
-            string authorRootCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.AuthorRootCertificate);
-            string authorIntermediateCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.AuthorIntermediateCertificate);
-            string aurthorSignerCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.AuthorSignerCertificate);
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.AuthorRootCertificate, out IntPtr authorRootCertificatePtr);
+            string authorRootCertificate = authorRootCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(authorRootCertificatePtr) : string.Empty;
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.AuthorIntermediateCertificate, out IntPtr authorIntermediateCertificatePtr);
+            string authorIntermediateCertificate = authorIntermediateCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(authorIntermediateCertificatePtr) : string.Empty;
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.AuthorSignerCertificate, out IntPtr aurthorSignerCertificatePtr);
+            string aurthorSignerCertificate = aurthorSignerCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(aurthorSignerCertificatePtr) : string.Empty;
             certificates.Add(CertificateType.Author, new PackageCertificate(authorRootCertificate, authorIntermediateCertificate, aurthorSignerCertificate));
 
-            string distRootCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.DistributorRootCertificate);
-            string distIntermediateCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.DistributorIntermediateCertificate);
-            string distSignerCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.DistributorSignerCertificate);
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.DistributorRootCertificate, out IntPtr distRootCertificatePtr);
+            string distRootCertificate = distRootCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(distRootCertificatePtr) : string.Empty;
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.DistributorIntermediateCertificate, out IntPtr distIntermediateCertificatePtr);
+            string distIntermediateCertificate = distIntermediateCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(distIntermediateCertificatePtr) : string.Empty;
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.DistributorSignerCertificate, out IntPtr distSignerCertificatePtr);
+            string distSignerCertificate = distSignerCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(distSignerCertificatePtr) : string.Empty;
             certificates.Add(CertificateType.Distributor, new PackageCertificate(distRootCertificate, distIntermediateCertificate, distSignerCertificate));
 
-            string dist2RootCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.Distributor2RootCertificate);
-            string dist2IntermediateCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.Distributor2IntermediateCertificate);
-            string dist2SignerCertificate = GetValue(nativeCertificates, Interop.Package.CertificateType.Distributor2SignerCertificate);
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.Distributor2RootCertificate, out IntPtr dist2RootCertificatePtr);
+            string dist2RootCertificate = dist2RootCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(dist2RootCertificatePtr) : string.Empty;
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.Distributor2IntermediateCertificate, out IntPtr dist2IntermediateCertificatePtr);
+            string dist2IntermediateCertificate = dist2IntermediateCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(dist2IntermediateCertificatePtr) : string.Empty;
+            _ = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoGetCertValue(handle, Interop.Package.CertificateType.Distributor2SignerCertificate, out IntPtr dist2SignerCertificatePtr);
+            string dist2SignerCertificate = dist2SignerCertificatePtr != IntPtr.Zero ? Marshal.PtrToStringAnsi(dist2SignerCertificatePtr) : string.Empty;
             certificates.Add(CertificateType.Distributor2, new PackageCertificate(dist2RootCertificate, dist2IntermediateCertificate, dist2SignerCertificate));
 
-            return certificates;
-        }
+            ret = Interop.PackageManagerInfoInternal.PkgmgrinfoPkginfoDestroyCertinfo(handle);
+            if (ret != 0)
+            {
+                Log.Warn(LogTag, string.Format("Failed to destroy cert info handle"));
+            }
 
-        private static string GetValue(IDictionary<Interop.Package.CertificateType, string> dict, Interop.Package.CertificateType key)
-        {
-            string value;
-            dict.TryGetValue(key, out value);
-            return value;
+            return certificates;
         }
     }
-}
\ No newline at end of file
+}