1
0
mirror of https://gitcode.com/github-mirrors/react-native-update-cli.git synced 2025-09-17 18:06:10 +08:00
Code Issues Packages Projects Releases Wiki Activity GitHub Gitee
Files
react-native-update-cli/src/utils/app-info-parser/xml-parser/manifest.js
sunnylqm 84e5e34820 v1.20.6
2024-03-07 11:16:19 +08:00

217 lines
6.7 KiB
JavaScript

// From https://github.com/openstf/adbkit-apkreader
const BinaryXmlParser = require('./binary')
const INTENT_MAIN = 'android.intent.action.MAIN'
const CATEGORY_LAUNCHER = 'android.intent.category.LAUNCHER'
class ManifestParser {
constructor (buffer, options = {}) {
this.buffer = buffer
this.xmlParser = new BinaryXmlParser(this.buffer, options)
}
collapseAttributes (element) {
const collapsed = Object.create(null)
for (let attr of Array.from(element.attributes)) {
collapsed[attr.name] = attr.typedValue.value
}
return collapsed
}
parseIntents (element, target) {
target.intentFilters = []
target.metaData = []
return element.childNodes.forEach(element => {
switch (element.nodeName) {
case 'intent-filter': {
const intentFilter = this.collapseAttributes(element)
intentFilter.actions = []
intentFilter.categories = []
intentFilter.data = []
element.childNodes.forEach(element => {
switch (element.nodeName) {
case 'action':
intentFilter.actions.push(this.collapseAttributes(element))
break
case 'category':
intentFilter.categories.push(this.collapseAttributes(element))
break
case 'data':
intentFilter.data.push(this.collapseAttributes(element))
break
}
})
target.intentFilters.push(intentFilter)
break
}
case 'meta-data':
target.metaData.push(this.collapseAttributes(element))
break
}
})
}
parseApplication (element) {
const app = this.collapseAttributes(element)
app.activities = []
app.activityAliases = []
app.launcherActivities = []
app.services = []
app.receivers = []
app.providers = []
app.usesLibraries = []
app.metaData = []
element.childNodes.forEach(element => {
switch (element.nodeName) {
case 'activity': {
const activity = this.collapseAttributes(element)
this.parseIntents(element, activity)
app.activities.push(activity)
if (this.isLauncherActivity(activity)) {
app.launcherActivities.push(activity)
}
break
}
case 'activity-alias': {
const activityAlias = this.collapseAttributes(element)
this.parseIntents(element, activityAlias)
app.activityAliases.push(activityAlias)
if (this.isLauncherActivity(activityAlias)) {
app.launcherActivities.push(activityAlias)
}
break
}
case 'service': {
const service = this.collapseAttributes(element)
this.parseIntents(element, service)
app.services.push(service)
break
}
case 'receiver': {
const receiver = this.collapseAttributes(element)
this.parseIntents(element, receiver)
app.receivers.push(receiver)
break
}
case 'provider': {
const provider = this.collapseAttributes(element)
provider.grantUriPermissions = []
provider.metaData = []
provider.pathPermissions = []
element.childNodes.forEach(element => {
switch (element.nodeName) {
case 'grant-uri-permission':
provider.grantUriPermissions.push(this.collapseAttributes(element))
break
case 'meta-data':
provider.metaData.push(this.collapseAttributes(element))
break
case 'path-permission':
provider.pathPermissions.push(this.collapseAttributes(element))
break
}
})
app.providers.push(provider)
break
}
case 'uses-library':
app.usesLibraries.push(this.collapseAttributes(element))
break
case 'meta-data':
app.metaData.push(this.collapseAttributes(element))
break
}
})
return app
}
isLauncherActivity (activity) {
return activity.intentFilters.some(function (filter) {
const hasMain = filter.actions.some(action => action.name === INTENT_MAIN)
if (!hasMain) {
return false
}
return filter.categories.some(category => category.name === CATEGORY_LAUNCHER)
})
}
parse () {
const document = this.xmlParser.parse()
const manifest = this.collapseAttributes(document)
manifest.usesPermissions = []
manifest.usesPermissionsSDK23 = []
manifest.permissions = []
manifest.permissionTrees = []
manifest.permissionGroups = []
manifest.instrumentation = null
manifest.usesSdk = null
manifest.usesConfiguration = null
manifest.usesFeatures = []
manifest.supportsScreens = null
manifest.compatibleScreens = []
manifest.supportsGlTextures = []
manifest.application = Object.create(null)
document.childNodes.forEach(element => {
switch (element.nodeName) {
case 'uses-permission':
manifest.usesPermissions.push(this.collapseAttributes(element))
break
case 'uses-permission-sdk-23':
manifest.usesPermissionsSDK23.push(this.collapseAttributes(element))
break
case 'permission':
manifest.permissions.push(this.collapseAttributes(element))
break
case 'permission-tree':
manifest.permissionTrees.push(this.collapseAttributes(element))
break
case 'permission-group':
manifest.permissionGroups.push(this.collapseAttributes(element))
break
case 'instrumentation':
manifest.instrumentation = this.collapseAttributes(element)
break
case 'uses-sdk':
manifest.usesSdk = this.collapseAttributes(element)
break
case 'uses-configuration':
manifest.usesConfiguration = this.collapseAttributes(element)
break
case 'uses-feature':
manifest.usesFeatures.push(this.collapseAttributes(element))
break
case 'supports-screens':
manifest.supportsScreens = this.collapseAttributes(element)
break
case 'compatible-screens':
element.childNodes.forEach(screen => {
return manifest.compatibleScreens.push(this.collapseAttributes(screen))
})
break
case 'supports-gl-texture':
manifest.supportsGlTextures.push(this.collapseAttributes(element))
break
case 'application':
manifest.application = this.parseApplication(element)
break
}
})
return manifest
}
}
module.exports = ManifestParser