From 000ae0cbfbb46fdc2fa27d8d45ea948d99d4c669 Mon Sep 17 00:00:00 2001
From: aprz512 <aprz512@163.com>
Date: Fri, 22 Nov 2024 13:04:55 +0800
Subject: [PATCH] =?UTF-8?q?feat(core):=20=E6=94=AF=E6=8C=81=E6=96=B0?=
 =?UTF-8?q?=E5=A2=9EAPI33=E6=96=B0=E5=A2=9E=E7=9A=84getPackageInfo?=
 =?UTF-8?q?=E6=96=B9=E6=B3=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

androidx.profileinstaller.ProfileVerifier中有使用。

#1277
---
 buildScripts/gradle/versions.properties       |  2 +-
 .../managers/PluginPackageManagerImpl.kt      | 50 ++++++++++++++++++-
 .../runtime/PackageManagerInvokeRedirect.java | 14 +++++-
 .../core/runtime/PluginPackageManager.java    | 12 +++++
 .../cases/plugin_main/PackageManagerTest.java | 20 ++++++++
 .../TestPackageManagerActivity.java           | 18 ++++++-
 6 files changed, 111 insertions(+), 5 deletions(-)

diff --git a/buildScripts/gradle/versions.properties b/buildScripts/gradle/versions.properties
index cd827dcef..a2efa2e26 100644
--- a/buildScripts/gradle/versions.properties
+++ b/buildScripts/gradle/versions.properties
@@ -1,4 +1,4 @@
-COMPILE_SDK_VERSION=31
+COMPILE_SDK_VERSION=33
 MIN_SDK_VERSION=14
 TARGET_SDK_VERSION=28
 VERSION_CODE=1
diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginPackageManagerImpl.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginPackageManagerImpl.kt
index 5e57f62f3..63752e24b 100644
--- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginPackageManagerImpl.kt
+++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginPackageManagerImpl.kt
@@ -38,8 +38,18 @@ internal class PluginPackageManagerImpl(
             hostPackageManager.getApplicationInfo(packageName, flags)
         }
 
-    override fun getPackageInfo(packageName: String, flags: Int): PackageInfo? {
-        val hostPackageInfo = hostPackageManager.getPackageInfo(packageName, flags)
+    /**
+     * 所有插件中的各种方法签名的getPackageInfo方法汇总到这里。
+     * 如果包名是插件的,优先返回插件的PackageInfo。
+     * 否则返回从宿主(系统)查询到的PackageInfo。
+     * 直接由getPackageArchiveInfo构造的PackageInfo和从getPackageInfo得到的正常的PackageInfo不完全一致。
+     * 在这里修改它使其尽可能像系统返回的。
+     */
+    private fun getPluginPackageInfoIfPossible(
+        packageName: String,
+        flags: Int,
+        hostPackageInfo: PackageInfo,
+    ): PackageInfo? {
         return if (packageName.isPlugin()) {
             val packageInfo = hostPackageManager.getPackageArchiveInfo(pluginArchiveFilePath, flags)
             if (packageInfo != null) {
@@ -53,6 +63,42 @@ internal class PluginPackageManagerImpl(
         }
     }
 
+    @Suppress("DEPRECATION")
+    override fun getPackageInfo(packageName: String, flags: Int) =
+        getPluginPackageInfoIfPossible(
+            packageName,
+            flags,
+            hostPackageManager.getPackageInfo(packageName, flags)
+        )
+
+    @Suppress("DEPRECATION")
+    @SuppressLint("NewApi")
+    override fun getPackageInfo(versionedPackage: VersionedPackage, flags: Int) =
+        getPluginPackageInfoIfPossible(
+            versionedPackage.packageName,
+            flags,
+            hostPackageManager.getPackageInfo(versionedPackage, flags)
+        )
+
+    @SuppressLint("NewApi")
+    override fun getPackageInfo(packageName: String, flags: PackageManager.PackageInfoFlags) =
+        getPluginPackageInfoIfPossible(
+            packageName,
+            flags.value.toInt(),//FIXME 这里会丢失flags升级到Long新增的标志位
+            hostPackageManager.getPackageInfo(packageName, flags)
+        )
+
+    @SuppressLint("NewApi")
+    override fun getPackageInfo(
+        versionedPackage: VersionedPackage,
+        flags: PackageManager.PackageInfoFlags
+    ) =
+        getPluginPackageInfoIfPossible(
+            versionedPackage.packageName,
+            flags.value.toInt(),//FIXME 这里会丢失flags升级到Long新增的标志位
+            hostPackageManager.getPackageInfo(versionedPackage, flags)
+        )
+
     override fun getActivityInfo(component: ComponentName, flags: Int): ActivityInfo? =
         getComponentInfo(
             component,
diff --git a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PackageManagerInvokeRedirect.java b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PackageManagerInvokeRedirect.java
index 208fb900c..748934b8b 100644
--- a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PackageManagerInvokeRedirect.java
+++ b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PackageManagerInvokeRedirect.java
@@ -67,7 +67,19 @@ public static PackageInfo getPackageInfo(ClassLoader classLoaderOfInvokeCode, St
     @TargetApi(Build.VERSION_CODES.O)
     public static PackageInfo getPackageInfo(ClassLoader classLoaderOfInvokeCode, VersionedPackage versionedPackage,
                                              int flags) throws PackageManager.NameNotFoundException {
-        return getPluginPackageManager(classLoaderOfInvokeCode).getPackageInfo(versionedPackage.getPackageName(), flags);
+        return getPluginPackageManager(classLoaderOfInvokeCode).getPackageInfo(versionedPackage, flags);
+    }
+
+    @TargetApi(Build.VERSION_CODES.TIRAMISU)
+    public static PackageInfo getPackageInfo(ClassLoader classLoaderOfInvokeCode, String packageName,
+                                             PackageManager.PackageInfoFlags flags) throws PackageManager.NameNotFoundException {
+        return getPluginPackageManager(classLoaderOfInvokeCode).getPackageInfo(packageName, flags);
+    }
+
+    @TargetApi(Build.VERSION_CODES.TIRAMISU)
+    public static PackageInfo getPackageInfo(ClassLoader classLoaderOfInvokeCode, VersionedPackage versionedPackage,
+                                             PackageManager.PackageInfoFlags flags) throws PackageManager.NameNotFoundException {
+        return getPluginPackageManager(classLoaderOfInvokeCode).getPackageInfo(versionedPackage, flags);
     }
 
     public static ProviderInfo resolveContentProvider(ClassLoader classLoaderOfInvokeCode, String name, int flags) {
diff --git a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PluginPackageManager.java b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PluginPackageManager.java
index 1fbea4787..e6ae51b09 100644
--- a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PluginPackageManager.java
+++ b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PluginPackageManager.java
@@ -1,13 +1,17 @@
 package com.tencent.shadow.core.runtime;
 
+import android.annotation.TargetApi;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
 import android.content.pm.ApplicationInfo;
 import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.VersionedPackage;
+import android.os.Build;
 
 import java.util.List;
 
@@ -22,6 +26,14 @@ public interface PluginPackageManager {
 
     PackageInfo getPackageInfo(String packageName, int flags);
 
+    PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags);
+
+    @TargetApi(Build.VERSION_CODES.TIRAMISU)
+    PackageInfo getPackageInfo(VersionedPackage versionedPackage, PackageManager.PackageInfoFlags flags);
+
+    @TargetApi(Build.VERSION_CODES.TIRAMISU)
+    PackageInfo getPackageInfo(String packageName, PackageManager.PackageInfoFlags flags);
+
     ProviderInfo resolveContentProvider(String name, int flags);
 
     List<ProviderInfo> queryContentProviders(String processName, int uid, int flags);
diff --git a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/PackageManagerTest.java b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/PackageManagerTest.java
index 5b6b0c844..5f430554c 100644
--- a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/PackageManagerTest.java
+++ b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/PackageManagerTest.java
@@ -1,6 +1,9 @@
 package com.tencent.shadow.test.cases.plugin_main;
 
+import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
 
 import androidx.test.core.app.ApplicationProvider;
 
@@ -55,4 +58,21 @@ public void testGetServiceInfoName() {
     public void testGetServiceInfoPackageName() {
         matchTextWithViewTag("getServiceInfo/packageName", "com.tencent.shadow.test.hostapp");
     }
+
+    @Test
+    public void testGetPackageInfoVersionName() throws PackageManager.NameNotFoundException {
+        Context applicationContext = ApplicationProvider.getApplicationContext();
+        String packageName = applicationContext.getPackageName();
+        PackageInfo packageInfo = applicationContext.getPackageManager().getPackageInfo(packageName, 0);
+        matchTextWithViewTag("getPackageInfo/versionName", packageInfo.versionName);
+    }
+
+    @Test
+    public void testGetPackageInfoVersionCode() throws PackageManager.NameNotFoundException {
+        Context applicationContext = ApplicationProvider.getApplicationContext();
+        String packageName = applicationContext.getPackageName();
+        PackageInfo packageInfo = applicationContext.getPackageManager().getPackageInfo(packageName, 0);
+        matchTextWithViewTag("getPackageInfo/versionCode", Integer.toString(packageInfo.versionCode));
+    }
+
 }
diff --git a/projects/test/plugin/general-cases/test-plugin-general-cases/src/main/java/com/tencent/shadow/test/plugin/general_cases/lib/usecases/packagemanager/TestPackageManagerActivity.java b/projects/test/plugin/general-cases/test-plugin-general-cases/src/main/java/com/tencent/shadow/test/plugin/general_cases/lib/usecases/packagemanager/TestPackageManagerActivity.java
index ef715a4bf..96a1f342e 100644
--- a/projects/test/plugin/general-cases/test-plugin-general-cases/src/main/java/com/tencent/shadow/test/plugin/general_cases/lib/usecases/packagemanager/TestPackageManagerActivity.java
+++ b/projects/test/plugin/general-cases/test-plugin-general-cases/src/main/java/com/tencent/shadow/test/plugin/general_cases/lib/usecases/packagemanager/TestPackageManagerActivity.java
@@ -30,6 +30,8 @@
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
 import android.content.pm.ServiceInfo;
+import android.content.pm.VersionedPackage;
+import android.os.Build;
 import android.os.Bundle;
 import android.view.ViewGroup;
 
@@ -151,7 +153,21 @@ private void getPackageInfo(ViewGroup viewGroup) {
         String versionName;
         String versionCode;
         try {
-            PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0);
+            PackageManager packageManager = getPackageManager();
+            String packageName = getPackageName();
+            PackageInfo packageInfo;
+
+            //'getPackageInfo(java.lang.String, int)' is deprecated as of API 33 ("Tiramisu"; Android 13.0)
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+                packageInfo = packageManager.getPackageInfo(packageName, PackageManager.PackageInfoFlags.of(0));
+
+                //再测试调用一下传VersionedPackage的方法
+                VersionedPackage versionedPackage = new VersionedPackage(packageInfo.packageName, packageInfo.getLongVersionCode());
+                packageInfo = packageManager.getPackageInfo(versionedPackage, PackageManager.PackageInfoFlags.of(0));
+            } else {
+                packageInfo = packageManager.getPackageInfo(packageName, 0);
+            }
+
             versionName = packageInfo.versionName;
             versionCode = Integer.toString(packageInfo.versionCode);
         } catch (PackageManager.NameNotFoundException e) {