1
+ package com.tencent.shadow.core.loader.blocs
2
+
3
+ import android.content.Context
4
+ import android.content.IntentFilter
5
+ import android.content.res.Resources
6
+ import com.tencent.shadow.core.common.InstalledApk
7
+ import com.tencent.shadow.core.loader.infos.ManifestInfo
8
+ import com.tencent.shadow.core.loader.infos.ManifestInfo.Receiver
9
+ import com.tencent.shadow.core.loader.infos.ManifestInfo.ReceiverIntentInfo
10
+ import org.xmlpull.v1.XmlPullParser
11
+
12
+ /* *
13
+ * 解析插件的AndroidManifest.xml文件
14
+ * 由于系统开放接口不提供广播的action信息,此处采用手动解析的方式处理,减少插件化的适配工作
15
+ * 后续对于AndroidManifest.xml的处理可在此基础上扩展
16
+ *
17
+
18
+ */
19
+ object ParseManifestBloc {
20
+
21
+ private const val ANDROID_RESOURCES = " http://schemas.android.com/apk/res/android"
22
+ private const val TAG_RECEIVER = " receiver"
23
+ private const val TAG_INTENT_FILTER = " intent-filter"
24
+ private const val TAG_ACTION = " action"
25
+ private const val ATTR_NAME = " name"
26
+
27
+ @Throws(Exception ::class )
28
+ fun parse (context : Context , installedApk : InstalledApk ): ManifestInfo = ManifestInfo ().apply {
29
+ val resources: Resources = newResource(context, installedApk)
30
+ val parser = resources.assets.openXmlResourceParser(" AndroidManifest.xml" )
31
+ val outerDepth = parser.depth
32
+ var type: Int
33
+ while (parser.next().also { type = it } != XmlPullParser .END_DOCUMENT
34
+ && (type != XmlPullParser .END_TAG || parser.depth > outerDepth)
35
+ ) {
36
+ if (type == XmlPullParser .START_TAG ) {
37
+ parseBroadcastReceiver(parser, this )
38
+ }
39
+ }
40
+ }
41
+
42
+ /* *
43
+ * 此处如果使用[LoadPluginBloc.loadPlugin]构建的resources,将包含WebView的resources,故需要重新创建
44
+ */
45
+ private fun newResource (context : Context , installedApk : InstalledApk ): Resources {
46
+ val packageArchiveInfo =
47
+ context.packageManager.getPackageArchiveInfo(installedApk.apkFilePath, 0 )!!
48
+ val packageManager = context.packageManager
49
+ packageArchiveInfo.applicationInfo?.publicSourceDir = installedApk.apkFilePath
50
+ packageArchiveInfo.applicationInfo?.sourceDir = installedApk.apkFilePath
51
+ return packageManager.getResourcesForApplication(packageArchiveInfo.applicationInfo)
52
+ }
53
+
54
+ private fun parseBroadcastReceiver (parser : XmlPullParser , manifestInfo : ManifestInfo ) {
55
+ if (TAG_RECEIVER == parser.name) {
56
+ val receiver = Receiver (parser.getAttributeValue(ANDROID_RESOURCES , ATTR_NAME ))
57
+ val outerDepth = parser.depth
58
+ var type: Int
59
+ while (parser.next().also { type = it } != XmlPullParser .END_DOCUMENT
60
+ && (type != XmlPullParser .END_TAG
61
+ || parser.depth > outerDepth)) {
62
+ if (type == XmlPullParser .END_TAG || type == XmlPullParser .TEXT ) {
63
+ continue
64
+ }
65
+ if (TAG_INTENT_FILTER == parser.name) {
66
+ val receiverInfo = ReceiverIntentInfo ()
67
+ parserIntent(parser, receiverInfo)
68
+ receiver.intents.add(receiverInfo)
69
+ }
70
+ }
71
+ manifestInfo.receivers.add(receiver)
72
+ }
73
+ }
74
+
75
+ private fun parserIntent (parser : XmlPullParser , intentFilter : IntentFilter ) {
76
+ val outerDepth = parser.depth
77
+ var type: Int
78
+ while (parser.next().also { type = it } != XmlPullParser .END_DOCUMENT
79
+ && (type != XmlPullParser .END_TAG || parser.depth > outerDepth)
80
+ ) {
81
+ if (type == XmlPullParser .END_TAG || type == XmlPullParser .TEXT ) {
82
+ continue
83
+ }
84
+ if (TAG_ACTION == parser.name) {
85
+ val value = parser.getAttributeValue(ANDROID_RESOURCES , ATTR_NAME )
86
+ intentFilter.addAction(value)
87
+ }
88
+ }
89
+ }
90
+ }
0 commit comments