children = new ArrayList<>();
for (int i = 0; i < node.getChildNodes().getLength(); i++) {
Node childNode = node.getChildNodes().item(i);
if (childNode.getNodeName().equalsIgnoreCase(tagName)) {
children.add(childNode);
}
}
return children;
}
private Integer getTagAttributeIntValue(final Document doc, final String tag, final String attribute) {
return getTagAttributeIntValue(doc, tag, attribute, null);
}
private Integer getTagAttributeIntValue(final Document doc, final String tag, final String attribute, final Integer defaultValue) {
String valueString = getTagAttributeText(doc, tag, attribute);
if (valueString != null) {
return Integer.parseInt(valueString);
}
return defaultValue;
}
public String getApplicationName() {
parseAndroidManifest();
return applicationName;
}
public String getActivityLabel(String activityClassName) {
parseAndroidManifest();
ActivityData data = getActivityData(activityClassName);
return (data != null && data.getLabel() != null) ? data.getLabel() : applicationLabel;
}
public String getPackageName() {
parseAndroidManifest();
return packageName;
}
public int getVersionCode() {
return versionCode;
}
public String getVersionName() {
return versionName;
}
public String getLabelRef() {
return labelRef;
}
/**
* Returns the minimum Android SDK version that this package expects to be runnable on, as
* specified in the manifest.
*
* Note that if `targetSdkVersion` isn't set, this value changes the behavior of some Android
* code (notably {@link android.content.SharedPreferences}) to emulate old bugs.
*
* @return the minimum SDK version, or Jelly Bean (16) by default
*/
@Override
public int getMinSdkVersion() {
parseAndroidManifest();
return minSdkVersion == null ? 16 : minSdkVersion;
}
/**
* Returns the Android SDK version that this package prefers to be run on, as specified in the
* manifest.
*
*
Note that this value changes the behavior of some Android code (notably {@link
* android.content.SharedPreferences}) to emulate old bugs.
*
* @return the minimum SDK version, or Jelly Bean (16) by default
*/
@Override
public int getTargetSdkVersion() {
parseAndroidManifest();
return targetSdkVersion == null ? getMinSdkVersion() : targetSdkVersion;
}
@Override
public Integer getMaxSdkVersion() {
parseAndroidManifest();
return maxSdkVersion;
}
public Map getApplicationAttributes() {
parseAndroidManifest();
return applicationAttributes;
}
public String getProcessName() {
parseAndroidManifest();
return processName;
}
public Map getApplicationMetaData() {
parseAndroidManifest();
if (applicationMetaData == null) {
applicationMetaData = new MetaData(Collections.emptyList());
}
return applicationMetaData.getValueMap();
}
public ResourcePath getResourcePath() {
return new ResourcePath(getRClass(), resDirectory, assetsDirectory);
}
public List getIncludedResourcePaths() {
Collection resourcePaths = new LinkedHashSet<>(); // Needs stable ordering and no duplicates
resourcePaths.add(getResourcePath());
for (AndroidManifest libraryManifest : getLibraryManifests()) {
resourcePaths.addAll(libraryManifest.getIncludedResourcePaths());
}
return new ArrayList<>(resourcePaths);
}
public List getContentProviders() {
parseAndroidManifest();
return providers;
}
public List getLibraryManifests() {
assert(libraryManifests != null);
return Collections.unmodifiableList(libraryManifests);
}
/**
* Returns all transitively reachable manifests, including this one, in order and without
* duplicates.
*/
public List getAllManifests() {
Set seenManifests = new HashSet<>();
List uniqueManifests = new ArrayList<>();
addTransitiveManifests(seenManifests, uniqueManifests);
return uniqueManifests;
}
private void addTransitiveManifests(Set unique, List list) {
if (unique.add(this)) {
list.add(this);
for (AndroidManifest androidManifest : getLibraryManifests()) {
androidManifest.addTransitiveManifests(unique, list);
}
}
}
public FsFile getResDirectory() {
return resDirectory;
}
public FsFile getAssetsDirectory() {
return assetsDirectory;
}
public FsFile getAndroidManifestFile() {
return androidManifestFile;
}
public List getBroadcastReceivers() {
parseAndroidManifest();
return receivers;
}
public List getServices() {
parseAndroidManifest();
return new ArrayList<>(serviceDatas.values());
}
public ServiceData getServiceData(String serviceClassName) {
parseAndroidManifest();
return serviceDatas.get(serviceClassName);
}
private static String getTagAttributeText(final Document doc, final String tag, final String attribute) {
NodeList elementsByTagName = doc.getElementsByTagName(tag);
for (int i = 0; i < elementsByTagName.getLength(); ++i) {
Node item = elementsByTagName.item(i);
Node namedItem = item.getAttributes().getNamedItem(attribute);
if (namedItem != null) {
return namedItem.getTextContent();
}
}
return null;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
AndroidManifest that = (AndroidManifest) o;
if (androidManifestFile != null ? !androidManifestFile.equals(that.androidManifestFile)
: that.androidManifestFile != null) {
return false;
}
if (resDirectory != null ? !resDirectory.equals(that.resDirectory)
: that.resDirectory != null) {
return false;
}
if (assetsDirectory != null ? !assetsDirectory.equals(that.assetsDirectory)
: that.assetsDirectory != null) {
return false;
}
if (overridePackageName != null ? !overridePackageName.equals(that.overridePackageName)
: that.overridePackageName != null) {
return false;
}
if (libraryManifests != null ? !libraryManifests.equals(that.libraryManifests)
: that.libraryManifests != null) {
return false;
}
return apkFile != null ? apkFile.equals(that.apkFile) : that.apkFile == null;
}
@Override
public int hashCode() {
int result = androidManifestFile != null ? androidManifestFile.hashCode() : 0;
result = 31 * result + (resDirectory != null ? resDirectory.hashCode() : 0);
result = 31 * result + (assetsDirectory != null ? assetsDirectory.hashCode() : 0);
result = 31 * result + (overridePackageName != null ? overridePackageName.hashCode() : 0);
result = 31 * result + (libraryManifests != null ? libraryManifests.hashCode() : 0);
result = 31 * result + (apkFile != null ? apkFile.hashCode() : 0);
return result;
}
public ActivityData getActivityData(String activityClassName) {
parseAndroidManifest();
return activityDatas.get(activityClassName);
}
public String getThemeRef() {
return themeRef;
}
public Map getActivityDatas() {
parseAndroidManifest();
return activityDatas;
}
public List getUsedPermissions() {
parseAndroidManifest();
return usedPermissions;
}
public Map getPermissions() {
parseAndroidManifest();
return permissions;
}
public Map getPermissionGroups() {
parseAndroidManifest();
return permissionGroups;
}
/**
* Returns data for the broadcast receiver with the provided name from this manifest. If no
* receiver with the class name can be found, returns null.
*
* @param className the fully resolved class name of the receiver
* @return data for the receiver or null if it cannot be found
*/
public @Nullable BroadcastReceiverData getBroadcastReceiver(String className) {
parseAndroidManifest();
for (BroadcastReceiverData receiver : receivers) {
if (receiver.getName().equals(className)) {
return receiver;
}
}
return null;
}
public FsFile getApkFile() {
return apkFile;
}
/** @deprecated Do not use. */
@Deprecated
public boolean supportsLegacyResourcesMode() {
return true;
}
/** @deprecated Do not use. */
@Deprecated
synchronized public boolean supportsBinaryResourcesMode() {
if (supportsBinaryResourcesMode == null) {
supportsBinaryResourcesMode = apkFile != null && apkFile.exists();
}
return supportsBinaryResourcesMode;
}
}