io.imqa.injector.AndroidManifestParser Maven / Gradle / Ivy
package io.imqa.injector;
import io.imqa.injector.util.BuildOption;
import io.imqa.injector.util.Logger;
import io.imqa.injector.util.PathBuilder;
import io.imqa.injector.util.StringUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import static io.imqa.injector.util.BuildOption.gradleVersion;
import static io.imqa.injector.util.FileUtil.execCmd;
public class AndroidManifestParser {
private String manifestFullLocation;
private ArrayList activityList = new ArrayList<>();
private String projectName = "";
private String flavor = "";
private String buildType = "";
private String packageName = "";
private String[] packageNameArr = null;
private String sourceSet = "";
private String manifestLocation = "";
public AndroidManifestParser(String projectName, String flavor, String buildType, String packageName) {
this.projectName = projectName;
this.buildType = buildType;
this.flavor = flavor;
this.packageName = packageName;
if (BuildOption.manifestLocation == null || BuildOption.manifestLocation.equals("")) {
if (gradleVersion.majorVersion == 3) {
if (gradleVersion.minorVersion >= 3) {
PathBuilder builder = PathBuilder.getBuilder("/build/intermediates/merged_manifests/");
if (!flavor.equals("")) {
builder.addPath(flavor + StringUtil.toCapitalize(buildType));
} else {
builder.addPath(buildType);
}
this.manifestLocation = builder.toString();
} else if (gradleVersion.minorVersion >= 2) {
PathBuilder builder = PathBuilder.getBuilder("/build/intermediates/merged_manifests/");
if (!flavor.equals("")) {
builder.addPath(flavor + StringUtil.toCapitalize(buildType));
} else {
builder.addPath(buildType);
}
builder.addPath("process" + StringUtil.toCapitalize(flavor) + StringUtil.toCapitalize(buildType) + "Manifest")
.addPath("merged");
this.manifestLocation = builder.toString();
} else {
PathBuilder builder = PathBuilder.getBuilder("/build/intermediates/manifests/full/");
if (!flavor.equals("")) {
builder.addPath(flavor).addPath(buildType);
} else {
builder.addPath(buildType);
}
this.manifestLocation = builder.toString();
}
} else if (gradleVersion.majorVersion == 2
&& gradleVersion.minorVersion == 2
&& gradleVersion.microVersion.equals("3")){
PathBuilder builder = PathBuilder.getBuilder("/build/intermediates/manifests/full/");
if (!flavor.equals("")) {
builder.addPath(flavor).addPath(buildType);
} else {
builder.addPath(buildType);
}
this.manifestLocation = builder.toString();
} else {
this.manifestLocation = PathBuilder.getBuilder("/build/intermediates/manifests/full/").toString();
}
this.manifestLocation = findManifestLocation(PathBuilder.getBuilder(projectName)
.addPath(this.manifestLocation).toString());
} else {
this.manifestLocation = BuildOption.manifestLocation;
if (!flavor.equals("")) {
this.manifestLocation = PathBuilder.getBuilder(this.manifestLocation).addPath(flavor).toString();
}
this.manifestLocation = findManifestLocation(PathBuilder.getBuilder(projectName)
.addPath(this.manifestLocation)
.addPath(buildType).toString());
}
findActivityList(this.manifestLocation);
}
public AndroidManifestParser(String manifestCommand) {
Logger.d("Manifest Command", manifestCommand);
try {
String manifestRaw = execCmd(manifestCommand);
// Logger.d("Manifest", manifestRaw);
String[] manifestRawArr = manifestRaw.split("Android manifest:")[1].split("\\s.:");
boolean isActivity = false;
for (String manifestRawItem : manifestRawArr) {
manifestRawItem = manifestRawItem.trim();
if (manifestRawItem.lastIndexOf("package=\"") != -1) {
packageNameArr = manifestRawItem.substring(
manifestRawItem.lastIndexOf("package=\"")+9,
manifestRawItem.lastIndexOf("\" (")).split("\\.");
}
if (manifestRawItem.lastIndexOf("activity (line") != -1) {
isActivity = true;
}
if (isActivity
&& manifestRawItem.lastIndexOf("android:name") != -1) {
int begin = manifestRawItem.indexOf("=\"")+2;
int end = manifestRawItem.lastIndexOf("\" (Raw:");
String manifestAnalyzed = manifestRawItem.substring(begin, end);
activityList.add(manifestAnalyzed);
isActivity = false;
}
}
for (String packageName : packageNameArr) {
this.packageName = this.packageName + "." + packageName;
this.sourceSet = this.packageName + "/" + packageName;
}
} catch (IOException e) {
e.printStackTrace();
}
}
public ArrayList getActivityList() {
return activityList;
}
public String getPackageName() {
return this.packageName;
}
public String[] getPackageNameArray() {
return this.packageNameArr;
}
public String getSourceSet() {
return this.sourceSet;
}
private String findManifestLocation(String fileName) {
fileName = PathBuilder.getBuilder(fileName).addPath("/AndroidManifest.xml").toString();
Logger.d("Manifest Location", fileName);
return fileName;
}
private void findActivityList(String fileName) {
// Get Activity List on Manifest.xml
//String fileName = "app/build/intermediates/manifests/full/debug/AndroidManifest.xml";
NodeList nodeList = null;
try {
File fXmlFile = new File(fileName);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
String beforePackageName = doc.getDocumentElement().getAttribute("package");
beforePackageName = beforePackageName.replace(".", "/");
sourceSet = beforePackageName;
// Search Element name that have 'activity' in 'application'
NodeList applicationList = doc.getElementsByTagName("application");
nodeList = applicationList.item(0).getChildNodes();
// This find 'activity'
for (int index = 0; index < nodeList.getLength(); index++) {
Node nNode = nodeList.item(index);
if (nNode.getNodeType() == Node.ELEMENT_NODE
&& nNode.getNodeName().equals("activity")) {
// If found activity node do change .class file
Element eElement = (Element) nNode;
String activityName = findActivityName(eElement);
if (activityName != null) {
activityName = activityName.replace(".", "/");
activityList.add(activityName);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
private String findActivityName(Element eElement) {
//Logger.d(eElement.getAttributes());
String sTag = "android:name";
String enabled = "android:enabled";
if (eElement.getAttribute(enabled).equals("false"))
return null;
else
return eElement.getAttribute(sTag);
}
public static boolean checkActivityManifest(String fileName, String targetPackageName) {
try {
File fXmlFile = new File(fileName);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
String libPackageName = doc.getDocumentElement().getAttribute("package");
libPackageName = libPackageName.replace(".", "/");
Logger.d("Check library manifest", targetPackageName + " / " + libPackageName);
return targetPackageName.equals(libPackageName);
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
}