diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/ShadowPluginLoader.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/ShadowPluginLoader.kt index 3cbc5e5b5..5a64bc24e 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/ShadowPluginLoader.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/ShadowPluginLoader.kt @@ -19,6 +19,7 @@ package com.tencent.shadow.core.loader import android.content.Context +import android.content.pm.PackageInfo import android.os.Handler import android.os.Looper import android.os.Parcel @@ -32,7 +33,6 @@ import com.tencent.shadow.core.loader.delegates.ShadowContentProviderDelegate import com.tencent.shadow.core.loader.delegates.ShadowDelegate import com.tencent.shadow.core.loader.exceptions.LoadPluginException import com.tencent.shadow.core.loader.infos.PluginParts -import com.tencent.shadow.core.loader.managers.CommonPluginPackageManager import com.tencent.shadow.core.loader.managers.ComponentManager import com.tencent.shadow.core.loader.managers.PluginContentProviderManager import com.tencent.shadow.core.loader.managers.PluginServiceManager @@ -75,7 +75,10 @@ abstract class ShadowPluginLoader(hostAppContext: Context) : DelegateProvider, D abstract val mExceptionReporter: Reporter - private val mCommonPluginPackageManager = CommonPluginPackageManager() + /** + * @GuardedBy("mLock") + */ + private val mPluginPackageInfoSet: MutableSet = hashSetOf() private lateinit var mPluginServiceManager: PluginServiceManager @@ -164,8 +167,8 @@ abstract class ShadowPluginLoader(hostAppContext: Context) : DelegateProvider, D return LoadPluginBloc.loadPlugin( mExecutorService, - mAbi, - mCommonPluginPackageManager, + mPluginPackageInfoSet, + ::allPluginPackageInfo, mComponentManager, mLock, mPluginPartsMap, @@ -175,6 +178,12 @@ abstract class ShadowPluginLoader(hostAppContext: Context) : DelegateProvider, D mShadowRemoteViewCreatorProvider) } + private fun allPluginPackageInfo(): Array { + mLock.withLock { + return mPluginPackageInfoSet.toTypedArray() + } + } + override fun getHostActivityDelegate(aClass: Class): HostActivityDelegate { return ShadowActivityDelegate(this) } diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/CreateApplicationBloc.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/CreateApplicationBloc.kt index 0776bd32d..f0ba4bd28 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/CreateApplicationBloc.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/CreateApplicationBloc.kt @@ -19,11 +19,12 @@ package com.tencent.shadow.core.loader.blocs import android.content.Context +import android.content.pm.ApplicationInfo import android.content.res.Resources import com.tencent.shadow.core.loader.classloaders.PluginClassLoader import com.tencent.shadow.core.loader.exceptions.CreateApplicationException +import com.tencent.shadow.core.loader.infos.PluginInfo import com.tencent.shadow.core.loader.managers.ComponentManager -import com.tencent.shadow.core.loader.managers.PluginPackageManager import com.tencent.shadow.core.runtime.ShadowApplication import com.tencent.shadow.core.runtime.remoteview.ShadowRemoteViewCreatorProvider @@ -36,14 +37,15 @@ object CreateApplicationBloc { @Throws(CreateApplicationException::class) fun createShadowApplication( pluginClassLoader: PluginClassLoader, - appClassName: String?, - pluginPackageManager: PluginPackageManager, + pluginInfo: PluginInfo, resources: Resources, hostAppContext: Context, componentManager: ComponentManager, - remoteViewCreatorProvider: ShadowRemoteViewCreatorProvider? + remoteViewCreatorProvider: ShadowRemoteViewCreatorProvider?, + applicationInfo: ApplicationInfo ): ShadowApplication { try { + val appClassName = pluginInfo.applicationClassName val shadowApplication : ShadowApplication; shadowApplication = if (appClassName != null) { val appClass = pluginClassLoader.loadClass(appClassName) @@ -51,15 +53,14 @@ object CreateApplicationBloc { } else { object : ShadowApplication(){} } - val partKey = pluginPackageManager.pluginInfo.partKey + val partKey = pluginInfo.partKey shadowApplication.setPluginResources(resources) shadowApplication.setPluginClassLoader(pluginClassLoader) shadowApplication.setPluginComponentLauncher(componentManager) shadowApplication.setHostApplicationContextAsBase(hostAppContext) shadowApplication.setBroadcasts(componentManager.getBroadcastsByPartKey(partKey)) - shadowApplication.setLibrarySearchPath(pluginClassLoader.getLibrarySearchPath()) - shadowApplication.setDexPath(pluginClassLoader.getDexPath()) - shadowApplication.setBusinessName(pluginPackageManager.pluginInfo.businessName) + shadowApplication.applicationInfo = applicationInfo + shadowApplication.setBusinessName(pluginInfo.businessName) shadowApplication.setPluginPartKey(partKey) shadowApplication.remoteViewCreatorProvider = remoteViewCreatorProvider return shadowApplication diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/LoadPluginBloc.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/LoadPluginBloc.kt index 29b0fe41e..5b04e439a 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/LoadPluginBloc.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/LoadPluginBloc.kt @@ -19,12 +19,12 @@ package com.tencent.shadow.core.loader.blocs import android.content.Context +import android.content.pm.PackageInfo import android.content.pm.PackageManager import com.tencent.shadow.core.common.InstalledApk import com.tencent.shadow.core.load_parameters.LoadParameters import com.tencent.shadow.core.loader.exceptions.LoadPluginException import com.tencent.shadow.core.loader.infos.PluginParts -import com.tencent.shadow.core.loader.managers.CommonPluginPackageManager import com.tencent.shadow.core.loader.managers.ComponentManager import com.tencent.shadow.core.loader.managers.PluginPackageManager import com.tencent.shadow.core.runtime.PluginPartInfo @@ -41,8 +41,8 @@ object LoadPluginBloc { @Throws(LoadPluginException::class) fun loadPlugin( executorService: ExecutorService, - abi: String, - commonPluginPackageManager: CommonPluginPackageManager, + pluginPackageInfoSet: MutableSet, + allPluginPackageInfo: () -> (Array), componentManager: ComponentManager, lock: ReentrantLock, pluginPartsMap: MutableMap, @@ -63,6 +63,7 @@ object LoadPluginBloc { val getPackageInfo = executorService.submit(Callable { val archiveFilePath = installedApk.apkFilePath val packageManager = hostAppContext.packageManager + val packageArchiveInfo = packageManager.getPackageArchiveInfo( archiveFilePath, PackageManager.GET_ACTIVITIES @@ -72,13 +73,21 @@ object LoadPluginBloc { or PackageManager.GET_SIGNATURES ) ?: throw NullPointerException("getPackageArchiveInfo return null.archiveFilePath==$archiveFilePath") + packageArchiveInfo.applicationInfo.nativeLibraryDir = installedApk.libraryPath + + lock.withLock { pluginPackageInfoSet.add(packageArchiveInfo) } packageArchiveInfo }) + val buildPluginInfo = executorService.submit(Callable { + val packageInfo = getPackageInfo.get() + ParsePluginApkBloc.parse(packageInfo, loadParameters, hostAppContext) + }) + val buildPackageManager = executorService.submit(Callable { val packageInfo = getPackageInfo.get() - val pluginInfo = ParsePluginApkBloc.parse(packageInfo, loadParameters, hostAppContext) - PluginPackageManager(commonPluginPackageManager, pluginInfo) + val hostPackageManager = hostAppContext.packageManager + PluginPackageManager(hostPackageManager, packageInfo, allPluginPackageInfo) }) val buildResources = executorService.submit(Callable { @@ -88,18 +97,18 @@ object LoadPluginBloc { val buildApplication = executorService.submit(Callable { val pluginClassLoader = buildClassLoader.get() - val pluginPackageManager = buildPackageManager.get() val resources = buildResources.get() - val pluginInfo = pluginPackageManager.pluginInfo + val pluginInfo = buildPluginInfo.get() + val packageInfo = getPackageInfo.get() CreateApplicationBloc.createShadowApplication( pluginClassLoader, - pluginInfo.applicationClassName, - pluginPackageManager, + pluginInfo, resources, hostAppContext, componentManager, - remoteViewCreatorProvider + remoteViewCreatorProvider, + packageInfo.applicationInfo ) }) @@ -110,7 +119,7 @@ object LoadPluginBloc { val pluginPackageManager = buildPackageManager.get() val pluginClassLoader = buildClassLoader.get() val resources = buildResources.get() - val pluginInfo = pluginPackageManager.pluginInfo + val pluginInfo = buildPluginInfo.get() val shadowApplication = buildApplication.get() lock.withLock { componentManager.addPluginApkInfo(pluginInfo) diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/ParsePluginApkBloc.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/ParsePluginApkBloc.kt index 06323b043..cd75db9c5 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/ParsePluginApkBloc.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/blocs/ParsePluginApkBloc.kt @@ -73,10 +73,6 @@ object ParsePluginApkBloc { , partKey , packageArchiveInfo.applicationInfo.packageName , packageArchiveInfo.applicationInfo.className - , packageArchiveInfo.applicationInfo.metaData - , packageArchiveInfo.versionCode - , packageArchiveInfo.versionName - , packageArchiveInfo.signatures ) packageArchiveInfo.activities?.forEach { pluginInfo.putActivityInfo(PluginActivityInfo(it.name, it.themeResource, it)) diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/classloaders/PluginClassLoader.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/classloaders/PluginClassLoader.kt index fc5835bc7..ce10657b9 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/classloaders/PluginClassLoader.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/classloaders/PluginClassLoader.kt @@ -37,9 +37,9 @@ import java.io.File * */ class PluginClassLoader( - private val dexPath: String, + dexPath: String, optimizedDirectory: File?, - private val librarySearchPath: String?, + librarySearchPath: String?, parent: ClassLoader, private val specialClassLoader: ClassLoader?, hostWhiteList: Array? ) : BaseDexClassLoader(dexPath, optimizedDirectory, librarySearchPath, parent) { @@ -94,9 +94,6 @@ class PluginClassLoader( } } - fun getLibrarySearchPath() = librarySearchPath - - private fun String.startWith(array: Array): Boolean { for (str in array) { if (startsWith(str)) { @@ -105,6 +102,5 @@ class PluginClassLoader( } return false } - - fun getDexPath() = dexPath } + diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/delegates/ShadowActivityDelegate.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/delegates/ShadowActivityDelegate.kt index aa69f476d..0ffc8964a 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/delegates/ShadowActivityDelegate.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/delegates/ShadowActivityDelegate.kt @@ -155,8 +155,7 @@ class ShadowActivityDelegate(private val mDI: DI) : HostActivityDelegate, Shadow pluginActivity.setPluginComponentLauncher(mComponentManager) pluginActivity.setPluginApplication(mPluginApplication) pluginActivity.setShadowApplication(mPluginApplication) - pluginActivity.setLibrarySearchPath(mPluginClassLoader.getLibrarySearchPath()) - pluginActivity.setDexPath(mPluginClassLoader.getDexPath()) + pluginActivity.applicationInfo = mPluginApplication.applicationInfo pluginActivity.setBusinessName(mBusinessName) pluginActivity.setPluginPartKey(mPartKey) pluginActivity.remoteViewCreatorProvider = mRemoteViewCreatorProvider diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/infos/PluginInfo.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/infos/PluginInfo.kt index dbe99b1f3..eb423bb7e 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/infos/PluginInfo.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/infos/PluginInfo.kt @@ -18,18 +18,11 @@ package com.tencent.shadow.core.loader.infos -import android.content.pm.Signature -import android.os.Bundle - class PluginInfo( val businessName: String?, val partKey: String, val packageName: String, - val applicationClassName: String?, - val metaData: Bundle?, - val versionCode: Int, - val versionName: String, - val signatures: Array + val applicationClassName: String? ) { private val _mActivities: MutableSet = HashSet() private val _mServices: MutableSet = HashSet() diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginPackageManager.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginPackageManager.kt index 0c79797ff..649dba69d 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginPackageManager.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginPackageManager.kt @@ -18,6 +18,7 @@ package com.tencent.shadow.core.loader.managers +import android.annotation.TargetApi import android.content.ComponentName import android.content.Intent import android.content.IntentFilter @@ -26,39 +27,59 @@ import android.content.res.Resources import android.content.res.XmlResourceParser import android.graphics.Rect import android.graphics.drawable.Drawable +import android.os.Build import android.os.UserHandle import com.tencent.shadow.core.loader.ImplementLater -import com.tencent.shadow.core.loader.infos.PluginInfo - -class PluginPackageManager(val commonPluginPackageManager: CommonPluginPackageManager, - val pluginInfo: PluginInfo) : PackageManager() { - override fun getApplicationInfo(packageName: String?, flags: Int): ApplicationInfo { - val applicationInfo = ApplicationInfo() - applicationInfo.metaData = pluginInfo.metaData - applicationInfo.className = pluginInfo.applicationClassName - return applicationInfo - } - - override fun getPackageInfo(packageName: String?, flags: Int): PackageInfo? { - if (pluginInfo.packageName == packageName) { - val info = PackageInfo() - info.versionCode = pluginInfo.versionCode - info.versionName = pluginInfo.versionName - info.signatures = pluginInfo.signatures - return info; - } - return null; - } + +class PluginPackageManager(private val hostPackageManager: PackageManager, + private val packageInfo: PackageInfo, + private val allPluginPackageInfo: () -> (Array)) + : PackageManager() { + override fun getApplicationInfo(packageName: String?, flags: Int): ApplicationInfo = + if (packageInfo.applicationInfo.packageName == packageName) { + packageInfo.applicationInfo + } else { + hostPackageManager.getApplicationInfo(packageName, flags) + } + + override fun getPackageInfo(packageName: String?, flags: Int): PackageInfo? = + if (packageInfo.applicationInfo.packageName == packageName) { + packageInfo + } else { + hostPackageManager.getPackageInfo(packageName, flags) + } + + @TargetApi(Build.VERSION_CODES.O) + override fun getPackageInfo(versionedPackage: VersionedPackage?, flags: Int): PackageInfo? = + if (packageInfo.applicationInfo.packageName == versionedPackage?.packageName) { + packageInfo + } else { + hostPackageManager.getPackageInfo(versionedPackage, flags) + } override fun getActivityInfo(component: ComponentName, flags: Int): ActivityInfo { - val find = pluginInfo.mActivities.find { - it.className == component.className + if (component.packageName == packageInfo.applicationInfo.packageName) { + val pluginActivityInfo = allPluginPackageInfo() + .flatMap { it.activities.asIterable() }.find { + it.name == component.className + } + if (pluginActivityInfo != null) { + return pluginActivityInfo + } } - if (find == null) { - return commonPluginPackageManager.getActivityInfo(component, flags) - } else { - return find.activityInfo + return hostPackageManager.getActivityInfo(component, flags) + } + + override fun resolveContentProvider(name: String?, flags: Int): ProviderInfo? { + val pluginProviderInfo = allPluginPackageInfo() + .flatMap { it.providers.asIterable() }.find { + it.authority == name + } + if (pluginProviderInfo != null) { + return pluginProviderInfo } + + return hostPackageManager.resolveContentProvider(name, flags) } override fun canonicalToCurrentPackageNames(names: Array?): Array { @@ -125,13 +146,6 @@ class PluginPackageManager(val commonPluginPackageManager: CommonPluginPackageMa ImplementLater() } - override fun resolveContentProvider(name: String?, flags: Int): ProviderInfo? { - val find = pluginInfo.mProviders.find { - it.authority == name - } - return find?.providerInfo - } - override fun getApplicationEnabledSetting(packageName: String?): Int { ImplementLater() } @@ -240,10 +254,6 @@ class PluginPackageManager(val commonPluginPackageManager: CommonPluginPackageMa ImplementLater() } - override fun getPackageInfo(versionedPackage: VersionedPackage?, flags: Int): PackageInfo { - ImplementLater() - } - override fun getPackagesHoldingPermissions(permissions: Array?, flags: Int): MutableList { ImplementLater() } diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginServiceManager.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginServiceManager.kt index 3b37c8c9e..464c43eb1 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginServiceManager.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/managers/PluginServiceManager.kt @@ -234,8 +234,7 @@ class PluginServiceManager(private val mPluginLoader: ShadowPluginLoader, privat service.setPluginClassLoader(tmpShadowDelegate.getPluginClassLoader()) service.setShadowApplication(tmpShadowDelegate.getPluginApplication()) service.setPluginComponentLauncher(tmpShadowDelegate.getComponentManager()) - service.setLibrarySearchPath(tmpShadowDelegate.getPluginClassLoader().getLibrarySearchPath()) - service.setDexPath(tmpShadowDelegate.getPluginClassLoader().getDexPath()) + service.applicationInfo = tmpShadowDelegate.getPluginApplication().applicationInfo service.setBusinessName(businessName) service.setPluginPartKey(partKey) diff --git a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/remoteview/ShadowRemoteViewCreatorImp.kt b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/remoteview/ShadowRemoteViewCreatorImp.kt index b2f6f19a5..4c48b3e93 100644 --- a/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/remoteview/ShadowRemoteViewCreatorImp.kt +++ b/projects/sdk/core/loader/src/main/kotlin/com/tencent/shadow/core/loader/remoteview/ShadowRemoteViewCreatorImp.kt @@ -49,8 +49,7 @@ internal class ShadowRemoteViewCreatorImp(private val context: Context, private shadowContext.setPluginPartKey(partKey) shadowContext.setPluginResources(pluginParts.resources) shadowContext.setShadowApplication(pluginParts.application) - shadowContext.setLibrarySearchPath(pluginParts.classLoader.getLibrarySearchPath()) - shadowContext.setDexPath(pluginParts.classLoader.getDexPath()) + shadowContext.applicationInfo = pluginParts.application.applicationInfo val view = View::class.java.cast(constructor.newInstance(shadowContext)) 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 new file mode 100644 index 000000000..b4be720ab --- /dev/null +++ b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PackageManagerInvokeRedirect.java @@ -0,0 +1,65 @@ +/* + * Tencent is pleased to support the open source community by making Tencent Shadow available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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. + * + */ + +package com.tencent.shadow.core.runtime; + +import android.annotation.TargetApi; +import android.content.ComponentName; +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.VersionedPackage; +import android.os.Build; + +/** + * PackageManagerTransform必须把对PackageManager的调用转到到这个处于Runtime层不被Transform作用的类上来, + * 而不能把这个类实现的方法直接写在Transform生成的方法体中,是为了避免这个类实现的代码再次被Transform, + * 形成循环调用。 + */ +public class PackageManagerInvokeRedirect { + + private static PackageManager getPluginPackageManager(ClassLoader classLoaderOfInvokeCode) { + return PluginPartInfoManager.getPluginInfo(classLoaderOfInvokeCode).packageManager; + } + + public static ApplicationInfo getApplicationInfo(ClassLoader classLoaderOfInvokeCode, String packageName, int flags) throws PackageManager.NameNotFoundException { + return getPluginPackageManager(classLoaderOfInvokeCode).getApplicationInfo(packageName, flags); + } + + public static ActivityInfo getActivityInfo(ClassLoader classLoaderOfInvokeCode, ComponentName component, int flags) throws PackageManager.NameNotFoundException { + return getPluginPackageManager(classLoaderOfInvokeCode).getActivityInfo(component, flags); + } + + public static PackageInfo getPackageInfo(ClassLoader classLoaderOfInvokeCode, String packageName, int flags) throws PackageManager.NameNotFoundException { + return getPluginPackageManager(classLoaderOfInvokeCode).getPackageInfo(packageName, flags); + } + + @TargetApi(Build.VERSION_CODES.O) + public static PackageInfo getPackageInfo(ClassLoader classLoaderOfInvokeCode, VersionedPackage versionedPackage, + int flags) throws PackageManager.NameNotFoundException{ + return getPluginPackageManager(classLoaderOfInvokeCode).getPackageInfo(versionedPackage, flags); + } + + public static ProviderInfo resolveContentProvider(ClassLoader classLoaderOfInvokeCode, String name, int flags) { + return getPluginPackageManager(classLoaderOfInvokeCode).resolveContentProvider(name, flags); + } + + +} diff --git a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PackageManagerWrapper.java b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PackageManagerWrapper.java deleted file mode 100644 index 883458352..000000000 --- a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/PackageManagerWrapper.java +++ /dev/null @@ -1,577 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Tencent Shadow available. - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use - * this file except in compliance with the License. You may obtain a copy of - * the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * 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. - * - */ - -package com.tencent.shadow.core.runtime; - -import android.annotation.TargetApi; -import android.content.ComponentName; -import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.ActivityInfo; -import android.content.pm.ApplicationInfo; -import android.content.pm.ChangedPackages; -import android.content.pm.FeatureInfo; -import android.content.pm.InstrumentationInfo; -import android.content.pm.PackageInfo; -import android.content.pm.PackageInstaller; -import android.content.pm.PackageManager; -import android.content.pm.PermissionGroupInfo; -import android.content.pm.PermissionInfo; -import android.content.pm.ProviderInfo; -import android.content.pm.ResolveInfo; -import android.content.pm.ServiceInfo; -import android.content.pm.SharedLibraryInfo; -import android.content.pm.VersionedPackage; -import android.content.res.Resources; -import android.content.res.XmlResourceParser; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.os.Build; -import android.os.UserHandle; - -import java.util.List; - -public class PackageManagerWrapper extends PackageManager { - final private PackageManager mBase; - - public PackageManagerWrapper(PackageManager base) { - this.mBase = base; - } - - @Override - public PackageInfo getPackageInfo(String packageName, int flags) throws NameNotFoundException { - return mBase.getPackageInfo(packageName, flags); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public PackageInfo getPackageInfo(VersionedPackage versionedPackage, int flags) throws NameNotFoundException { - return mBase.getPackageInfo(versionedPackage, flags); - } - - @Override - public String[] currentToCanonicalPackageNames(String[] names) { - return mBase.currentToCanonicalPackageNames(names); - } - - @Override - public String[] canonicalToCurrentPackageNames(String[] names) { - return mBase.canonicalToCurrentPackageNames(names); - } - - @Override - public Intent getLaunchIntentForPackage(String packageName) { - return mBase.getLaunchIntentForPackage(packageName); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public Intent getLeanbackLaunchIntentForPackage(String packageName) { - return mBase.getLeanbackLaunchIntentForPackage(packageName); - } - - @Override - public int[] getPackageGids(String packageName) throws NameNotFoundException { - return mBase.getPackageGids(packageName); - } - - @TargetApi(Build.VERSION_CODES.N) - @Override - public int[] getPackageGids(String packageName, int flags) throws NameNotFoundException { - return mBase.getPackageGids(packageName, flags); - } - - @TargetApi(Build.VERSION_CODES.N) - @Override - public int getPackageUid(String packageName, int flags) throws NameNotFoundException { - return mBase.getPackageUid(packageName, flags); - } - - @Override - public PermissionInfo getPermissionInfo(String name, int flags) throws NameNotFoundException { - return mBase.getPermissionInfo(name, flags); - } - - @Override - public List queryPermissionsByGroup(String group, int flags) throws NameNotFoundException { - return mBase.queryPermissionsByGroup(group, flags); - } - - @Override - public PermissionGroupInfo getPermissionGroupInfo(String name, int flags) throws NameNotFoundException { - return mBase.getPermissionGroupInfo(name, flags); - } - - @Override - public List getAllPermissionGroups(int flags) { - return mBase.getAllPermissionGroups(flags); - } - - @Override - public ApplicationInfo getApplicationInfo(String packageName, int flags) throws NameNotFoundException { - return mBase.getApplicationInfo(packageName, flags); - } - - @Override - public ActivityInfo getActivityInfo(ComponentName component, int flags) throws NameNotFoundException { - return mBase.getActivityInfo(component, flags); - } - - @Override - public ActivityInfo getReceiverInfo(ComponentName component, int flags) throws NameNotFoundException { - return mBase.getReceiverInfo(component, flags); - } - - @Override - public ServiceInfo getServiceInfo(ComponentName component, int flags) throws NameNotFoundException { - return mBase.getServiceInfo(component, flags); - } - - @Override - public ProviderInfo getProviderInfo(ComponentName component, int flags) throws NameNotFoundException { - return mBase.getProviderInfo(component, flags); - } - - @Override - public List getInstalledPackages(int flags) { - return mBase.getInstalledPackages(flags); - } - - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) - @Override - public List getPackagesHoldingPermissions(String[] permissions, int flags) { - return mBase.getPackagesHoldingPermissions(permissions, flags); - } - - @Override - public int checkPermission(String permName, String pkgName) { - return mBase.checkPermission(permName, pkgName); - } - - @TargetApi(Build.VERSION_CODES.M) - @Override - public boolean isPermissionRevokedByPolicy(String permName, String pkgName) { - return mBase.isPermissionRevokedByPolicy(permName, pkgName); - } - - @Override - public boolean addPermission(PermissionInfo info) { - return mBase.addPermission(info); - } - - @Override - public boolean addPermissionAsync(PermissionInfo info) { - return mBase.addPermissionAsync(info); - } - - @Override - public void removePermission(String name) { - mBase.removePermission(name); - } - - @Override - public int checkSignatures(String pkg1, String pkg2) { - return mBase.checkSignatures(pkg1, pkg2); - } - - @Override - public int checkSignatures(int uid1, int uid2) { - return mBase.checkSignatures(uid1, uid2); - } - - @Override - public String[] getPackagesForUid(int uid) { - return mBase.getPackagesForUid(uid); - } - - @Override - public String getNameForUid(int uid) { - return mBase.getNameForUid(uid); - } - - @Override - public List getInstalledApplications(int flags) { - return mBase.getInstalledApplications(flags); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public boolean isInstantApp() { - return mBase.isInstantApp(); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public boolean isInstantApp(String packageName) { - return mBase.isInstantApp(packageName); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public int getInstantAppCookieMaxBytes() { - return mBase.getInstantAppCookieMaxBytes(); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public byte[] getInstantAppCookie() { - return mBase.getInstantAppCookie(); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public void clearInstantAppCookie() { - mBase.clearInstantAppCookie(); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public void updateInstantAppCookie(byte[] cookie) { - mBase.updateInstantAppCookie(cookie); - } - - @Override - public String[] getSystemSharedLibraryNames() { - return mBase.getSystemSharedLibraryNames(); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public List getSharedLibraries(int flags) { - return mBase.getSharedLibraries(flags); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public ChangedPackages getChangedPackages(int sequenceNumber) { - return mBase.getChangedPackages(sequenceNumber); - } - - @Override - public FeatureInfo[] getSystemAvailableFeatures() { - return mBase.getSystemAvailableFeatures(); - } - - @Override - public boolean hasSystemFeature(String name) { - return mBase.hasSystemFeature(name); - } - - @TargetApi(Build.VERSION_CODES.N) - @Override - public boolean hasSystemFeature(String name, int version) { - return mBase.hasSystemFeature(name, version); - } - - @Override - public ResolveInfo resolveActivity(Intent intent, int flags) { - return mBase.resolveActivity(intent, flags); - } - - @Override - public List queryIntentActivities(Intent intent, int flags) { - return mBase.queryIntentActivities(intent, flags); - } - - @Override - public List queryIntentActivityOptions(ComponentName caller, Intent[] specifics, Intent intent, int flags) { - return mBase.queryIntentActivityOptions(caller, specifics, intent, flags); - } - - @Override - public List queryBroadcastReceivers(Intent intent, int flags) { - return mBase.queryBroadcastReceivers(intent, flags); - } - - @Override - public ResolveInfo resolveService(Intent intent, int flags) { - return mBase.resolveService(intent, flags); - } - - @Override - public List queryIntentServices(Intent intent, int flags) { - return mBase.queryIntentServices(intent, flags); - } - - @TargetApi(Build.VERSION_CODES.KITKAT) - @Override - public List queryIntentContentProviders(Intent intent, int flags) { - return mBase.queryIntentContentProviders(intent, flags); - } - - @Override - public ProviderInfo resolveContentProvider(String name, int flags) { - return mBase.resolveContentProvider(name, flags); - } - - @Override - public List queryContentProviders(String processName, int uid, int flags) { - return mBase.queryContentProviders(processName, uid, flags); - } - - @Override - public InstrumentationInfo getInstrumentationInfo(ComponentName className, int flags) throws NameNotFoundException { - return mBase.getInstrumentationInfo(className, flags); - } - - @Override - public List queryInstrumentation(String targetPackage, int flags) { - return mBase.queryInstrumentation(targetPackage, flags); - } - - @Override - public Drawable getDrawable(String packageName, int resid, ApplicationInfo appInfo) { - return mBase.getDrawable(packageName, resid, appInfo); - } - - @Override - public Drawable getActivityIcon(ComponentName activityName) throws NameNotFoundException { - return mBase.getActivityIcon(activityName); - } - - @Override - public Drawable getActivityIcon(Intent intent) throws NameNotFoundException { - return mBase.getActivityIcon(intent); - } - - @TargetApi(Build.VERSION_CODES.KITKAT_WATCH) - @Override - public Drawable getActivityBanner(ComponentName activityName) throws NameNotFoundException { - return mBase.getActivityBanner(activityName); - } - - @TargetApi(Build.VERSION_CODES.KITKAT_WATCH) - @Override - public Drawable getActivityBanner(Intent intent) throws NameNotFoundException { - return mBase.getActivityBanner(intent); - } - - @Override - public Drawable getDefaultActivityIcon() { - return mBase.getDefaultActivityIcon(); - } - - @Override - public Drawable getApplicationIcon(ApplicationInfo info) { - return mBase.getApplicationIcon(info); - } - - @Override - public Drawable getApplicationIcon(String packageName) throws NameNotFoundException { - return mBase.getApplicationIcon(packageName); - } - - @TargetApi(Build.VERSION_CODES.KITKAT_WATCH) - @Override - public Drawable getApplicationBanner(ApplicationInfo info) { - return mBase.getApplicationBanner(info); - } - - @TargetApi(Build.VERSION_CODES.KITKAT_WATCH) - @Override - public Drawable getApplicationBanner(String packageName) throws NameNotFoundException { - return mBase.getApplicationBanner(packageName); - } - - @Override - public Drawable getActivityLogo(ComponentName activityName) throws NameNotFoundException { - return mBase.getActivityLogo(activityName); - } - - @Override - public Drawable getActivityLogo(Intent intent) throws NameNotFoundException { - return mBase.getActivityLogo(intent); - } - - @Override - public Drawable getApplicationLogo(ApplicationInfo info) { - return mBase.getApplicationLogo(info); - } - - @Override - public Drawable getApplicationLogo(String packageName) throws NameNotFoundException { - return mBase.getApplicationLogo(packageName); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public Drawable getUserBadgedIcon(Drawable icon, UserHandle user) { - return mBase.getUserBadgedIcon(icon, user); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public Drawable getUserBadgedDrawableForDensity(Drawable drawable, UserHandle user, Rect badgeLocation, int badgeDensity) { - return mBase.getUserBadgedDrawableForDensity(drawable, user, badgeLocation, badgeDensity); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public CharSequence getUserBadgedLabel(CharSequence label, UserHandle user) { - return mBase.getUserBadgedLabel(label, user); - } - - @Override - public CharSequence getText(String packageName, int resid, ApplicationInfo appInfo) { - return mBase.getText(packageName, resid, appInfo); - } - - @Override - public XmlResourceParser getXml(String packageName, int resid, ApplicationInfo appInfo) { - return mBase.getXml(packageName, resid, appInfo); - } - - @Override - public CharSequence getApplicationLabel(ApplicationInfo info) { - return mBase.getApplicationLabel(info); - } - - @Override - public Resources getResourcesForActivity(ComponentName activityName) throws NameNotFoundException { - return mBase.getResourcesForActivity(activityName); - } - - @Override - public Resources getResourcesForApplication(ApplicationInfo app) throws NameNotFoundException { - return mBase.getResourcesForApplication(app); - } - - @Override - public Resources getResourcesForApplication(String appPackageName) throws NameNotFoundException { - return mBase.getResourcesForApplication(appPackageName); - } - - @Override - public void verifyPendingInstall(int id, int verificationCode) { - mBase.verifyPendingInstall(id, verificationCode); - } - - @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1) - @Override - public void extendVerificationTimeout(int id, int verificationCodeAtTimeout, long millisecondsToDelay) { - mBase.extendVerificationTimeout(id, verificationCodeAtTimeout, millisecondsToDelay); - } - - @Override - public void setInstallerPackageName(String targetPackage, String installerPackageName) { - mBase.setInstallerPackageName(targetPackage, installerPackageName); - } - - @Override - public String getInstallerPackageName(String packageName) { - return mBase.getInstallerPackageName(packageName); - } - - @Override - public void addPackageToPreferred(String packageName) { - mBase.addPackageToPreferred(packageName); - } - - @Override - public void removePackageFromPreferred(String packageName) { - mBase.removePackageFromPreferred(packageName); - } - - @Override - public List getPreferredPackages(int flags) { - return mBase.getPreferredPackages(flags); - } - - @Override - public void addPreferredActivity(IntentFilter filter, int match, ComponentName[] set, ComponentName activity) { - mBase.addPreferredActivity(filter, match, set, activity); - } - - @Override - public void clearPackagePreferredActivities(String packageName) { - mBase.clearPackagePreferredActivities(packageName); - } - - @Override - public int getPreferredActivities(List outFilters, List outActivities, String packageName) { - return mBase.getPreferredActivities(outFilters, outActivities, packageName); - } - - @Override - public void setComponentEnabledSetting(ComponentName componentName, int newState, int flags) { - mBase.setComponentEnabledSetting(componentName, newState, flags); - } - - @Override - public int getComponentEnabledSetting(ComponentName componentName) { - return mBase.getComponentEnabledSetting(componentName); - } - - @Override - public void setApplicationEnabledSetting(String packageName, int newState, int flags) { - mBase.setApplicationEnabledSetting(packageName, newState, flags); - } - - @Override - public int getApplicationEnabledSetting(String packageName) { - return mBase.getApplicationEnabledSetting(packageName); - } - - @Override - public boolean isSafeMode() { - return mBase.isSafeMode(); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public void setApplicationCategoryHint(String packageName, int categoryHint) { - mBase.setApplicationCategoryHint(packageName, categoryHint); - } - - @TargetApi(Build.VERSION_CODES.LOLLIPOP) - @Override - public PackageInstaller getPackageInstaller() { - return mBase.getPackageInstaller(); - } - - @TargetApi(Build.VERSION_CODES.O) - @Override - public boolean canRequestPackageInstalls() { - return mBase.canRequestPackageInstalls(); - } - - /** - * 覆盖hide方法,部分机型会调用到 - */ - public Drawable getUserBadgeForDensity(UserHandle user, int density){ - return null; - } - - /** - * 覆盖hide方法,部分机型会调用到 - */ - public Drawable getUserBadgeForDensityNoBackground(UserHandle user, int density){ - return null; - } - - //@Override oppo R15 - public boolean isClosedSuperFirewall(){ - return false; - } - - public ApplicationInfo getApplicationInfoAsUser(String packageName, - int flags, int userId) throws NameNotFoundException { - return getApplicationInfo(packageName, flags); - } - -} diff --git a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java index dc91a87ca..5ed20e0eb 100644 --- a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java +++ b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowContext.java @@ -40,8 +40,7 @@ public class ShadowContext extends SubDirContextThemeWrapper { Resources mPluginResources; Resources mMixResources; LayoutInflater mLayoutInflater; - String mLibrarySearchPath; - String mDexPath; + ApplicationInfo mApplicationInfo; protected String mPartKey; private String mBusinessName; private ShadowRemoteViewCreatorProvider mRemoteViewCreatorProvider; @@ -69,12 +68,10 @@ public void setShadowApplication(ShadowApplication shadowApplication) { mShadowApplication = shadowApplication; } - public void setLibrarySearchPath(String mLibrarySearchPath) { - this.mLibrarySearchPath = mLibrarySearchPath; - } - - public void setDexPath(String dexPath) { - mDexPath = dexPath; + public void setApplicationInfo(ApplicationInfo applicationInfo) { + ApplicationInfo copy = new ApplicationInfo(applicationInfo); + copy.metaData = null;//正常通过Context获得的ApplicationInfo就没有metaData + mApplicationInfo = copy; } public void setBusinessName(String businessName) { @@ -227,10 +224,7 @@ public ComponentName startService(Intent service) { @Override public ApplicationInfo getApplicationInfo() { - final ApplicationInfo applicationInfo = super.getApplicationInfo(); - applicationInfo.nativeLibraryDir = mLibrarySearchPath; - applicationInfo.sourceDir = mDexPath; - return applicationInfo; + return mApplicationInfo; } public PluginComponentLauncher getPendingIntentConverter() { diff --git a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowPackageManager.java b/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowPackageManager.java deleted file mode 100644 index 0b5d18a11..000000000 --- a/projects/sdk/core/runtime/src/main/java/com/tencent/shadow/core/runtime/ShadowPackageManager.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Tencent is pleased to support the open source community by making Tencent Shadow available. - * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. - * - * Licensed under the BSD 3-Clause License (the "License"); you may not use - * this file except in compliance with the License. You may obtain a copy of - * the License at - * - * https://opensource.org/licenses/BSD-3-Clause - * - * 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. - * - */ - -package com.tencent.shadow.core.runtime; - -import android.annotation.TargetApi; -import android.content.ComponentName; -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.VersionedPackage; -import android.os.Build; -import android.os.Bundle; - -/** - * 将插件中的PackageManager部分方法转调到本类上来,以达到修改PackageManager的行为 - */ -public class ShadowPackageManager { - - /** - * @param classLoader 对应插件所在的classLoader - * @param packageManager 宿主的packageManager - * @param packageName 包名 - * @param flags flag - * @return 如果包名为插件包名则返回插件对应的applicationInfo,否则返回宿主packageManager查询到的applicationInfo - * @throws PackageManager.NameNotFoundException - */ - public static ApplicationInfo getApplicationInfo(ClassLoader classLoader, PackageManager packageManager, String packageName, int flags) throws PackageManager.NameNotFoundException { - PluginPartInfo pluginPartInfo = PluginPartInfoManager.getPluginInfo(classLoader); - final ApplicationInfo applicationInfo = packageManager.getApplicationInfo(packageName, flags); - final ApplicationInfo pluginAppInfo = pluginPartInfo.packageManager.getApplicationInfo(packageName, flags); - if (pluginAppInfo.metaData != null) { - if (applicationInfo.metaData == null) { - applicationInfo.metaData = new Bundle(); - } - applicationInfo.metaData.putAll(pluginAppInfo.metaData); - } - applicationInfo.className = pluginAppInfo.className; - return applicationInfo; - } - - /** - * - * @param classLoader classLoader 对应插件所在的classLoader - * @param packageManager 宿主的packageManager - * @param component 要查询的component - * @param flags flags - * @return 从所有插件中查询对应component的ActivityInfo,查询不到则从宿主packageManager中继续查找 - * @throws PackageManager.NameNotFoundException - */ - public static ActivityInfo getActivityInfo(ClassLoader classLoader, PackageManager packageManager, ComponentName component, int flags) throws PackageManager.NameNotFoundException { - for (PluginPartInfo pluginPartInfo : PluginPartInfoManager.getAllPluginInfo()) { - try { - return pluginPartInfo.packageManager.getActivityInfo(component, flags); - } catch (PackageManager.NameNotFoundException ignored) { - } - } - return packageManager.getActivityInfo(component, flags); - } - - /** - * - * @param classLoader classLoader 对应插件所在的classLoader - * @param packageManager 宿主的packageManager - * @param packageName 要查询的packageName - * @param flags flags - * @return 如果包名为插件包名则包含当前插件的版本信息的PackageInfo - * @throws PackageManager.NameNotFoundException - */ - public static PackageInfo getPackageInfo(ClassLoader classLoader, PackageManager packageManager, String packageName, int flags) throws PackageManager.NameNotFoundException { - PluginPartInfo pluginPartInfo = PluginPartInfoManager.getPluginInfo(classLoader); - PackageManager pluginPackageManager = pluginPartInfo.packageManager; - PackageInfo hostInfo = packageManager.getPackageInfo(packageName, flags); - getPluginPackageInfo(packageName, flags, pluginPackageManager, hostInfo); - return hostInfo; - } - - /** - * - * @param classLoader classLoader 对应插件所在的classLoader - * @param packageManager 宿主的packageManager - * @param versionedPackage 要查询的versionedPackage - * @param flags flags - * @return 如果包名为插件包名则包含当前插件的版本信息的PackageInfo - * @throws PackageManager.NameNotFoundException - */ - @TargetApi(Build.VERSION_CODES.O) - public static PackageInfo getPackageInfo(ClassLoader classLoader, PackageManager packageManager, VersionedPackage versionedPackage, - int flags) throws PackageManager.NameNotFoundException{ - PluginPartInfo pluginPartInfo = PluginPartInfoManager.getPluginInfo(classLoader); - PackageManager pluginPackageManager = pluginPartInfo.packageManager; - PackageInfo hostInfo = packageManager.getPackageInfo(versionedPackage, flags); - getPluginPackageInfo(versionedPackage.getPackageName(), flags, pluginPackageManager, hostInfo); - return hostInfo; - } - - private static void getPluginPackageInfo(String packageName, int flags, PackageManager pluginPackageManager, PackageInfo hostInfo) throws PackageManager.NameNotFoundException { - PackageInfo pluginInfo = pluginPackageManager.getPackageInfo(packageName, flags); - if (pluginInfo != null) { - hostInfo.versionCode = pluginInfo.versionCode; - hostInfo.versionName = pluginInfo.versionName; - } - } - - /** - * @param classLoader 对应插件所在的classLoader - * @param packageManager 宿主的packageManager - * @param name 要查询的ProviderInfo - * @param flags flags - * @return 从所有插件中查询对应name的ProviderInfo,查询不到则从宿主packageManager中继续查找 - */ - public static ProviderInfo resolveContentProvider(ClassLoader classLoader, PackageManager packageManager, String name, int flags) { - for (PluginPartInfo pluginPartInfo : PluginPartInfoManager.getAllPluginInfo()) { - ProviderInfo providerInfo = pluginPartInfo.packageManager.resolveContentProvider(name, flags); - if (providerInfo != null) { - return providerInfo; - } - } - return packageManager.resolveContentProvider(name, flags); - } - - -} diff --git a/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/TransformManager.kt b/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/TransformManager.kt index cc8ad9e98..3234d4571 100644 --- a/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/TransformManager.kt +++ b/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/TransformManager.kt @@ -41,6 +41,7 @@ class TransformManager(ctClassInputMap: Map, WebViewTransform(), ContentProviderTransform(), PackageManagerTransform(), + PackageItemInfoTransform(), KeepHostContextTransform(useHostContext()) ) } \ No newline at end of file diff --git a/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/specific/PackageItemInfoTransform.kt b/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/specific/PackageItemInfoTransform.kt new file mode 100644 index 000000000..43a48d8a4 --- /dev/null +++ b/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/specific/PackageItemInfoTransform.kt @@ -0,0 +1,134 @@ +/* + * Tencent is pleased to support the open source community by making Tencent Shadow available. + * Copyright (C) 2019 THL A29 Limited, a Tencent company. All rights reserved. + * + * Licensed under the BSD 3-Clause License (the "License"); you may not use + * this file except in compliance with the License. You may obtain a copy of + * the License at + * + * https://opensource.org/licenses/BSD-3-Clause + * + * 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. + * + */ + +package com.tencent.shadow.core.transform.specific + +import com.tencent.shadow.core.transform_kit.CodeConverterExtension +import com.tencent.shadow.core.transform_kit.SpecificTransform +import com.tencent.shadow.core.transform_kit.TransformStep +import javassist.CtClass +import javassist.CtMethod +import javassist.CtNewMethod +import javassist.Modifier +import java.util.* + +class PackageItemInfoTransform : SpecificTransform() { + companion object { + const val AndroidProviderInfo = "android.content.pm.ProviderInfo" + const val AndroidActivityInfo = "android.content.pm.ActivityInfo" + const val AndroidApplicationInfo = "android.content.pm.ApplicationInfo" + const val AndroidServiceInfo = "android.content.pm.ServiceInfo" + const val AndroidPackageItemInfo = "android.content.pm.PackageItemInfo" + const val ShadowAndroidPackageItemInfo = "com.tencent.shadow.core.runtime.ShadowPackageItemInfo" + } + + private fun setup( + targetClassNames: Array, + targetMethodName: Array, + redirectRule: Pair + ) { + val targetMethods = getTargetMethods(targetClassNames, targetMethodName) + targetMethods.forEach { targetMethod -> + newStep(object : TransformStep { + override fun filter(allInputClass: Set) = + allCanRecompileAppClass( + allInputClass, + targetClassNames.asList() + ).filter { matchMethodCallInClass(targetMethod, it) }.toSet() + + override fun transform(ctClass: CtClass) { + System.out.println(ctClass.name + " matchMethodCallInClass :" + targetMethod.methodInfo.name + " =================") + try { + val targetClass = mClassPool[redirectRule.first] + val redirectClassName = redirectRule.second + val parameterTypes: Array = + Array(targetMethod.parameterTypes.size + 1) { index -> + if (index == 0) { + targetClass + } else { + targetMethod.parameterTypes[index - 1] + } + } + val newMethod = CtNewMethod.make( + Modifier.PUBLIC or Modifier.STATIC, + targetMethod.returnType, + targetMethod.name + "_shadow", + parameterTypes, + targetMethod.exceptionTypes, + null, + ctClass + ) + val newBodyBuilder = StringBuilder() + newBodyBuilder + .append("return ") + .append(redirectClassName) + .append(".") + .append(targetMethod.methodInfo.name) + .append("(") + .append(ctClass.name) + .append(".class.getClassLoader(),") + for (i in 1..newMethod.parameterTypes.size) { + if (i > 1) { + newBodyBuilder.append(',') + } + newBodyBuilder.append("\$${i}") + } + newBodyBuilder.append(");") + + newMethod.setBody(newBodyBuilder.toString()) + ctClass.addMethod(newMethod) + val codeConverter = CodeConverterExtension() + codeConverter.redirectMethodCallToStaticMethodCall(targetMethod, newMethod) + ctClass.instrument(codeConverter) + } catch (e: Exception) { + System.err.println("处理" + ctClass.name + "时出错:" + e) + throw e + } + } + }) + } + } + + /** + * 查找目标class对象的目标method + */ + private fun getTargetMethods( + targetClassNames: Array, + targetMethodName: Array + ): List { + val method_targets = ArrayList() + for (targetClassName in targetClassNames) { + val methods = mClassPool[targetClassName].methods + method_targets.addAll(methods.filter { targetMethodName.contains(it.name) }) + } + return method_targets + } + + override fun setup(allInputClass: Set) { + setup( + arrayOf( + AndroidProviderInfo, + AndroidServiceInfo, + AndroidApplicationInfo, + AndroidActivityInfo + ), + arrayOf("loadXmlMetaData"), + AndroidPackageItemInfo to ShadowAndroidPackageItemInfo + ) + } +} \ No newline at end of file diff --git a/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/specific/PackageManagerTransform.kt b/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/specific/PackageManagerTransform.kt index ab00faf0d..f6a64a358 100644 --- a/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/specific/PackageManagerTransform.kt +++ b/projects/sdk/core/transform/src/main/kotlin/com/tencent/shadow/core/transform/specific/PackageManagerTransform.kt @@ -30,34 +30,22 @@ import java.util.* class PackageManagerTransform : SpecificTransform() { companion object { const val AndroidPackageManagerClassname = "android.content.pm.PackageManager" - const val ShadowAndroidPackageManagerClassname = "com.tencent.shadow.core.runtime.ShadowPackageManager" - const val AndroidProviderInfo = "android.content.pm.ProviderInfo" - const val AndroidActivityInfo = "android.content.pm.ActivityInfo" - const val AndroidApplicationInfo = "android.content.pm.ApplicationInfo" - const val AndroidServiceInfo = "android.content.pm.ServiceInfo" - const val AndroidPackageItemInfo = "android.content.pm.PackageItemInfo" - const val ShadowAndroidPackageItemInfo = "com.tencent.shadow.core.runtime.ShadowPackageItemInfo" + const val ShadowAndroidPackageManagerClassname = "com.tencent.shadow.core.runtime.PackageManagerInvokeRedirect" } - private fun setup( - targetClassNames: Array, - targetMethodName: Array, - redirectRule: Pair - ) { - val targetMethods = getTargetMethods(targetClassNames, targetMethodName) + private fun setupPackageManagerTransform(targetMethodName: Array) { + val targetMethods = getTargetMethods(arrayOf(AndroidPackageManagerClassname), targetMethodName) targetMethods.forEach { targetMethod -> newStep(object : TransformStep { override fun filter(allInputClass: Set) = allCanRecompileAppClass( allInputClass, - targetClassNames.asList() + listOf(AndroidPackageManagerClassname) ).filter { matchMethodCallInClass(targetMethod, it) }.toSet() override fun transform(ctClass: CtClass) { - System.out.println(ctClass.name + " matchMethodCallInClass :" + targetMethod.methodInfo.name + " =================") try { - val targetClass = mClassPool[redirectRule.first] - val redirectClassName = redirectRule.second + val targetClass = mClassPool[AndroidPackageManagerClassname] val parameterTypes: Array = Array(targetMethod.parameterTypes.size + 1) { index -> if (index == 0) { @@ -78,14 +66,16 @@ class PackageManagerTransform : SpecificTransform() { val newBodyBuilder = StringBuilder() newBodyBuilder .append("return ") - .append(redirectClassName) + .append(ShadowAndroidPackageManagerClassname) .append(".") .append(targetMethod.methodInfo.name) .append("(") .append(ctClass.name) .append(".class.getClassLoader(),") - for (i in 1..newMethod.parameterTypes.size) { - if (i > 1) { + //下面放弃第0个和第1个参数,第0个是this, + //第1个是redirectMethodCallToStaticMethodCall时原本被调用的PackageManager对象。 + for (i in 2..newMethod.parameterTypes.size) { + if (i > 2) { newBodyBuilder.append(',') } newBodyBuilder.append("\$${i}") @@ -107,25 +97,13 @@ class PackageManagerTransform : SpecificTransform() { } override fun setup(allInputClass: Set) { - setup( - arrayOf(AndroidPackageManagerClassname), + setupPackageManagerTransform( arrayOf( "getApplicationInfo", "getActivityInfo", "getPackageInfo", "resolveContentProvider" - ), - AndroidPackageManagerClassname to ShadowAndroidPackageManagerClassname - ) - setup( - arrayOf( - AndroidProviderInfo, - AndroidServiceInfo, - AndroidApplicationInfo, - AndroidActivityInfo - ), - arrayOf("loadXmlMetaData"), - AndroidPackageItemInfo to ShadowAndroidPackageItemInfo + ) ) } diff --git a/projects/sdk/core/transform/src/test/java/com/tencent/shadow/core/runtime/ShadowPackageManager.java b/projects/sdk/core/transform/src/test/java/com/tencent/shadow/core/runtime/PackageManagerInvokeRedirect.java similarity index 73% rename from projects/sdk/core/transform/src/test/java/com/tencent/shadow/core/runtime/ShadowPackageManager.java rename to projects/sdk/core/transform/src/test/java/com/tencent/shadow/core/runtime/PackageManagerInvokeRedirect.java index 7dd2c55a2..ecdf35338 100644 --- a/projects/sdk/core/transform/src/test/java/com/tencent/shadow/core/runtime/ShadowPackageManager.java +++ b/projects/sdk/core/transform/src/test/java/com/tencent/shadow/core/runtime/PackageManagerInvokeRedirect.java @@ -22,32 +22,27 @@ 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; - -/** - * 将插件中的PackageManager部分方法转调到本类上来,以达到修改PackageManager的行为 - */ -public class ShadowPackageManager { +public class PackageManagerInvokeRedirect { - public static ApplicationInfo getApplicationInfo(ClassLoader classLoader, PackageManager packageManager, String packageName, int flags) { + public static ApplicationInfo getApplicationInfo(ClassLoader classLoader, String packageName, int flags) { return null; } - public static ActivityInfo getActivityInfo(ClassLoader classLoader, PackageManager packageManager, ComponentName component, int flags) { + public static ActivityInfo getActivityInfo(ClassLoader classLoader, ComponentName component, int flags) { return null; } - public static PackageInfo getPackageInfo(ClassLoader classLoader, PackageManager packageManager, String packageName, int flags) { + public static PackageInfo getPackageInfo(ClassLoader classLoader, String packageName, int flags) { return null; } - public static ProviderInfo resolveContentProvider(ClassLoader classLoader, PackageManager packageManager, String name, int flags) { + public static ProviderInfo resolveContentProvider(ClassLoader classLoader, String name, int flags) { return null; } diff --git a/projects/test/dynamic/host/test-dynamic-host/build.gradle b/projects/test/dynamic/host/test-dynamic-host/build.gradle index 598289c89..d954e9e08 100644 --- a/projects/test/dynamic/host/test-dynamic-host/build.gradle +++ b/projects/test/dynamic/host/test-dynamic-host/build.gradle @@ -57,6 +57,7 @@ dependencies { androidTestImplementation "androidx.test:runner:1.1.2-alpha02" implementation project(':plugin-use-host-code-lib') + implementation project(':test-manager') implementation project(':custom-view') } diff --git a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/PluginTest.java b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/PluginTest.java index 46d63abc1..043c148c0 100644 --- a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/PluginTest.java +++ b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/PluginTest.java @@ -61,6 +61,11 @@ public void matchTextWithViewTag(String tag,String text){ .check(ViewAssertions.matches(ViewMatchers.withText(text))); } + public void matchSubstringWithViewTag(String tag, String text) { + Espresso.onView(ViewMatchers.withTagValue(Matchers.is(tag))) + .check(ViewAssertions.matches(ViewMatchers.withSubstring(text))); + } + @Before public void launchActivity() { SimpleIdlingResource idlingResource = HostApplication.getApp().mIdlingResource; diff --git a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/PluginMainAppTest.java b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/PluginMainAppTest.java index 8762f259d..bc54b24c4 100644 --- a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/PluginMainAppTest.java +++ b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/PluginMainAppTest.java @@ -21,7 +21,7 @@ import com.tencent.shadow.test.PluginTest; import com.tencent.shadow.test.lib.constant.Constant; -abstract class PluginMainAppTest extends PluginTest { +public abstract class PluginMainAppTest extends PluginTest { @Override protected String getPartKey() { diff --git a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/ApplicationInfoTest.java b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/ApplicationInfoTest.java new file mode 100644 index 000000000..fefa7d2cd --- /dev/null +++ b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/ApplicationInfoTest.java @@ -0,0 +1,11 @@ +package com.tencent.shadow.test.cases.plugin_main.application_info; + +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@RunWith(Suite.class) +@Suite.SuiteClasses({ContextGetApplicationInfoTest.class, + PackageManagerGetSelfApplicationInfoTest.class, + PackageManagerGetOtherInstalledApplicationInfoTest.class}) +public class ApplicationInfoTest { +} diff --git a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/CommonApplicationInfoTest.java b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/CommonApplicationInfoTest.java new file mode 100644 index 000000000..78acb94a0 --- /dev/null +++ b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/CommonApplicationInfoTest.java @@ -0,0 +1,46 @@ +package com.tencent.shadow.test.cases.plugin_main.application_info; + +import android.content.Intent; + +import androidx.test.core.app.ApplicationProvider; + +import com.tencent.shadow.test.cases.plugin_main.PluginMainAppTest; +import com.tencent.shadow.test.lib.test_manager.TestManager; + +import org.junit.Test; + +abstract class CommonApplicationInfoTest extends PluginMainAppTest { + private static final String PLUGIN_APK_FILENAME = "test-plugin-general-cases-debug.apk"; + + protected abstract String getTag(); + + @Override + protected Intent getLaunchIntent() { + Intent pluginIntent = new Intent(); + String packageName = ApplicationProvider.getApplicationContext().getPackageName(); + pluginIntent.setClassName( + packageName, + "com.tencent.shadow.test.plugin.general_cases.lib.usecases.application.TestGetApplicationInfoActivity" + ); + return pluginIntent; + } + + @Test + public void testSourceDir() throws Exception { + matchSubstringWithViewTag("TAG_sourceDir_" + getTag(), PLUGIN_APK_FILENAME); + } + + @Test + public void testNativeLibraryDir() throws Exception { + matchSubstringWithViewTag("TAG_nativeLibraryDir_" + getTag(), TestManager.uuid + "_lib"); + } + + @Test + public abstract void testMetaData(); + + @Test + public void testClassName() throws Exception { + matchSubstringWithViewTag("TAG_className_" + getTag(), + "com.tencent.shadow.test.plugin.general_cases.lib.gallery.TestApplication"); + } +} diff --git a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/ContextGetApplicationInfoTest.java b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/ContextGetApplicationInfoTest.java new file mode 100644 index 000000000..b259d1441 --- /dev/null +++ b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/ContextGetApplicationInfoTest.java @@ -0,0 +1,19 @@ +package com.tencent.shadow.test.cases.plugin_main.application_info; + +/** + * 在插件中通过Context.getApplicationInfo()获得到的ApplicationInfo测试。 + * + * @author shifujun + */ +public class ContextGetApplicationInfoTest extends CommonApplicationInfoTest { + + @Override + protected String getTag() { + return "Context"; + } + + @Override + public void testMetaData() { + matchTextWithViewTag("TAG_metaData_" + getTag(), ""); + } +} diff --git a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/PackageManagerGetOtherInstalledApplicationInfoTest.java b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/PackageManagerGetOtherInstalledApplicationInfoTest.java new file mode 100644 index 000000000..e029bbebd --- /dev/null +++ b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/PackageManagerGetOtherInstalledApplicationInfoTest.java @@ -0,0 +1,50 @@ +package com.tencent.shadow.test.cases.plugin_main.application_info; + +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; + +import androidx.test.core.app.ApplicationProvider; + +import static android.content.pm.PackageManager.GET_META_DATA; + +/** + * 在插件中通过PackageManager.getApplicationInfo()获取其他正常安装应用的ApplicationInfo测试。 + * + * @author shifujun + */ +public class PackageManagerGetOtherInstalledApplicationInfoTest extends CommonApplicationInfoTest { + + @Override + protected String getTag() { + return "PackageManagerGetOtherInstalled"; + } + + private ApplicationInfo getApplicationInfoFromHost() throws PackageManager.NameNotFoundException { + PackageManager packageManager = ApplicationProvider.getApplicationContext().getPackageManager(); + return packageManager.getApplicationInfo("com.android.webview", GET_META_DATA); + } + + @Override + public void testSourceDir() throws Exception { + ApplicationInfo applicationInfoFromHost = getApplicationInfoFromHost(); + matchTextWithViewTag("TAG_sourceDir_" + getTag(), applicationInfoFromHost.sourceDir); + } + + @Override + public void testNativeLibraryDir() throws Exception { + ApplicationInfo applicationInfoFromHost = getApplicationInfoFromHost(); + matchTextWithViewTag("TAG_nativeLibraryDir_" + getTag(), applicationInfoFromHost.nativeLibraryDir); + } + + @Override + public void testMetaData() { + matchTextWithViewTag("TAG_metaData_" + getTag(), ""); + } + + @Override + public void testClassName() throws Exception { + ApplicationInfo applicationInfoFromHost = getApplicationInfoFromHost(); + matchTextWithViewTag("TAG_className_" + getTag(), + applicationInfoFromHost.className); + } +} diff --git a/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/PackageManagerGetSelfApplicationInfoTest.java b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/PackageManagerGetSelfApplicationInfoTest.java new file mode 100644 index 000000000..221494389 --- /dev/null +++ b/projects/test/dynamic/host/test-dynamic-host/src/androidTest/java/com/tencent/shadow/test/cases/plugin_main/application_info/PackageManagerGetSelfApplicationInfoTest.java @@ -0,0 +1,19 @@ +package com.tencent.shadow.test.cases.plugin_main.application_info; + +/** + * 在插件中通过PackageManager.getApplicationInfo()获取插件自己的ApplicationInfo测试。 + * + * @author shifujun + */ +public class PackageManagerGetSelfApplicationInfoTest extends CommonApplicationInfoTest { + + @Override + protected String getTag() { + return "PackageManagerGetSelf"; + } + + @Override + public void testMetaData() { + matchSubstringWithViewTag("TAG_metaData_" + getTag(), "test_value"); + } +} diff --git a/projects/test/dynamic/manager/test-dynamic-manager/build.gradle b/projects/test/dynamic/manager/test-dynamic-manager/build.gradle index d94bdf17f..813bd7125 100644 --- a/projects/test/dynamic/manager/test-dynamic-manager/build.gradle +++ b/projects/test/dynamic/manager/test-dynamic-manager/build.gradle @@ -36,6 +36,7 @@ dependencies { compileOnly 'com.tencent.shadow.core:common-debug' compileOnly 'com.tencent.shadow.dynamic:dynamic-host-debug' + compileOnly project(':test-manager') } afterEvaluate { diff --git a/projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/dynamic/impl/WhiteList.java b/projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/dynamic/impl/WhiteList.java index 1fb5f22ea..fe135c7aa 100644 --- a/projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/dynamic/impl/WhiteList.java +++ b/projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/dynamic/impl/WhiteList.java @@ -28,5 +28,6 @@ public interface WhiteList { { "com.tencent.host.shadow", "com.tencent.shadow.test.lib.constant", + "com.tencent.shadow.test.lib.test_manager", }; } diff --git a/projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/test/dynamic/manager/TestDynamicPluginManager.java b/projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/test/dynamic/manager/TestDynamicPluginManager.java index cc606e9fd..37fdb5caa 100644 --- a/projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/test/dynamic/manager/TestDynamicPluginManager.java +++ b/projects/test/dynamic/manager/test-dynamic-manager/src/main/java/com/tencent/shadow/test/dynamic/manager/TestDynamicPluginManager.java @@ -27,6 +27,7 @@ import com.tencent.shadow.core.manager.installplugin.InstalledPlugin; import com.tencent.shadow.dynamic.host.EnterCallback; import com.tencent.shadow.test.lib.constant.Constant; +import com.tencent.shadow.test.lib.test_manager.TestManager; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; @@ -97,6 +98,9 @@ private void onStartActivity(final Context context, Bundle bundle, final EnterCa public void run() { try { InstalledPlugin installedPlugin = installPlugin(pluginZipPath, null, true); + + TestManager.uuid = installedPlugin.UUID; + Intent pluginIntent = new Intent(); pluginIntent.setClassName( context.getPackageName(), diff --git a/projects/test/lib/test-manager/.gitignore b/projects/test/lib/test-manager/.gitignore new file mode 100644 index 000000000..796b96d1c --- /dev/null +++ b/projects/test/lib/test-manager/.gitignore @@ -0,0 +1 @@ +/build diff --git a/projects/test/lib/test-manager/build.gradle b/projects/test/lib/test-manager/build.gradle new file mode 100644 index 000000000..b3c26ac5d --- /dev/null +++ b/projects/test/lib/test-manager/build.gradle @@ -0,0 +1,9 @@ +apply plugin: 'java-library' + +group 'com.tencent.shadow.test.lib.test-manager' + +dependencies { + compileOnly 'com.tencent.shadow.dynamic:dynamic-host-debug' +} +sourceCompatibility = "7" +targetCompatibility = "7" diff --git a/projects/test/lib/test-manager/src/main/java/com/tencent/shadow/test/lib/test_manager/TestManager.java b/projects/test/lib/test-manager/src/main/java/com/tencent/shadow/test/lib/test_manager/TestManager.java new file mode 100644 index 000000000..008aebd24 --- /dev/null +++ b/projects/test/lib/test-manager/src/main/java/com/tencent/shadow/test/lib/test_manager/TestManager.java @@ -0,0 +1,5 @@ +package com.tencent.shadow.test.lib.test_manager; + +public class TestManager { + public static String uuid; +} diff --git a/projects/test/plugin/general-cases/general-cases-lib/src/main/AndroidManifest.xml b/projects/test/plugin/general-cases/general-cases-lib/src/main/AndroidManifest.xml index 33fcd0f8f..f854f7cf9 100644 --- a/projects/test/plugin/general-cases/general-cases-lib/src/main/AndroidManifest.xml +++ b/projects/test/plugin/general-cases/general-cases-lib/src/main/AndroidManifest.xml @@ -72,6 +72,7 @@ +