
org.arquillian.droidium.container.impl.AndroidApplicationHelper Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of arquillian-droidium-container
Show all versions of arquillian-droidium-container
Arquillian Droidium Container
The newest version!
/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and/or its affiliates, and individual
* contributors by the @authors tag. See the copyright.txt in the
* distribution for a full listing of individual contributors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* 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 org.arquillian.droidium.container.impl;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.arquillian.droidium.container.api.AndroidExecutionException;
import org.arquillian.droidium.container.configuration.AndroidSDK;
import org.arquillian.droidium.container.configuration.Validate;
import org.arquillian.spacelift.Spacelift;
import org.arquillian.spacelift.process.Command;
import org.arquillian.spacelift.process.CommandBuilder;
import org.arquillian.spacelift.task.os.CommandTool;
/**
* Provides various helper methods for Android packages.
*
* @author Stefan Miklosovic
*
*/
public class AndroidApplicationHelper {
private static final Logger logger = Logger.getLogger(AndroidApplicationHelper.class.getName());
private final AndroidSDK sdk;
/**
*
* @param sdk
* @throws IllegalArgumentException if either {@code Executor} or {@code sdk} is a null object
*/
public AndroidApplicationHelper(AndroidSDK sdk) {
Validate.notNull(sdk, "Android SDK to set can not be a null object!");
this.sdk = sdk;
}
/**
*
* @param apk apk file to get the name of main activity from
* @return name of main activity of application
*/
public String getApplicationMainActivity(File apk) {
return getAAPTBadgingOutput(apk).getSingleProperty("launchable-activity", "name");
}
/**
*
* @param apk apk file name to get the name of main activity from
* @return name of main activity of application
*/
public String getApplicationMainActivity(String apk) {
return getApplicationMainActivity(new File(apk));
}
/**
*
* @param apk apk file to get the name of application base package of
* @return name of application base package
*/
public String getApplicationBasePackage(File apk) {
return getAAPTBadgingOutput(apk).getSingleProperty("package", "name");
}
/**
*
* @param apk apk file to get the name of application base package of
* @return name of application base package
*/
public String getApplicationVersion(File apk) {
return getAAPTBadgingOutput(apk).getSingleProperty("package", "versionName");
}
/**
*
* @param apk file to get the list of activities of
* @return list of activities which are in the package with fully qualified class name
*/
public List getActivities(File apk) {
List activities = new ArrayList();
try {
activities = filterActivities(getAAPTXmlTreeOutput(apk));
} catch (AndroidExecutionException e) {
logger.log(Level.SEVERE, "Unable to get list of activities for file: " + apk.getAbsolutePath(), e);
}
return activities;
}
/**
*
* @param apkFile file to get the list of activities of
* @return list of activities which are in the package with fully qualified class name
*/
public List getActivities(String apkFile) {
return getActivities(new File(apkFile));
}
/**
*
* @param apk apk file name to get the name of application base package of
* @return name of application base package
*/
public String getApplicationBasePackage(String apk) {
return getApplicationBasePackage(new File(apk));
}
private BadgingOutput getAAPTBadgingOutput(File apk) {
final Command command = new CommandBuilder(sdk.getAaptPath())
.parameter("dump")
.parameter("badging")
.parameter(apk.getAbsolutePath())
.build();
return new BadgingOutput(Spacelift.task(CommandTool.class)
.addEnvironment(sdk.getPlatformConfiguration().getAndroidSystemEnvironmentProperties())
.command(command)
.execute()
.await()
.output());
}
private List getAAPTXmlTreeOutput(File apkFile) {
final Command command = new CommandBuilder(sdk.getAaptPath())
.parameter("dump")
.parameter("xmltree")
.parameter(apkFile.getAbsolutePath())
.parameter("AndroidManifest.xml")
.build();
return Spacelift.task(CommandTool.class)
.addEnvironment(sdk.getPlatformConfiguration().getAndroidSystemEnvironmentProperties())
.command(command)
.execute()
.await()
.output();
}
private List filterActivities(List output) {
String packageName;
List activities = new ArrayList();
packageName = getPackageName(output);
for (int i = 0; i < output.size(); i++) {
if (output.get(i).trim().startsWith("E: activity")) {
while (!output.get(++i).trim().contains("A: android:name")) {
}
String activityName = getActivityName(output.get(i));
if (activityName.startsWith(".")) {
activities.add(packageName + activityName);
} else if (!activityName.startsWith(".") && !activityName.contains(".")) {
activities.add(packageName + "." + activityName);
} else {
activities.add(activityName);
}
}
}
return activities;
}
private String getPackageName(List output) {
for (String line : output) {
if (line.contains("package")) {
Pattern packagePattern = Pattern.compile("package=[\'\"]([^\'\"]+)[\'\"]");
Matcher m = packagePattern.matcher(line);
if (m.find()) {
return m.group(1);
}
}
}
throw new IllegalStateException("no package name found in dump xmltree for AndroidManifest.xml");
}
private String getActivityName(String line) {
Pattern activityPattern = Pattern.compile("=[\"]([^\"]+)[\"]");
Matcher m = activityPattern.matcher(line);
if (m.find()) {
return m.group(1);
}
throw new IllegalStateException("no activity name found in AndroidManifest.xml on line: " + line);
}
/**
* A wrapper on top of aapt d badging output
* @author kpiwko
*
*/
static final class BadgingOutput {
private final List badgingOutput;
public BadgingOutput(List output) {
this.badgingOutput = output;
}
/**
* Retrieves all properties that start with given propertyName. Output is expected in format:
* propertyName:? value
* @param propertyName
* @return Returns a collection with all values that matched output
*/
public List getProperty(String propertyName) {
List output = new ArrayList();
Pattern propertyPattern = Pattern.compile("^(\\s*)" + propertyName + "(:?)(.*)$");
for (String line : badgingOutput) {
Matcher m = propertyPattern.matcher(line);
if (m.find()) {
output.add(m.group(3));
}
}
return output;
}
/**
* Retrieves all properties that start with given propertyName and parses all values there that start with propertySubName. Output is expected in format:
* propertyName:? propertySubName='value'
* @param propertyName
* @param propertySubName
* @return Returns a collection with all values that matched output
*/
public List getProperty(String propertyName, String propertySubName) {
List partialResults = getProperty(propertyName);
List output = new ArrayList(partialResults.size());
Pattern subPropertyPattern = Pattern.compile(propertySubName + "=[\'\"]([^\'\"]+)[\'\"]");
for (String line : partialResults) {
Matcher m = subPropertyPattern.matcher(line);
if (m.find()) {
output.add(m.group(1));
}
}
return output;
}
/**
* Transforms list of properties to a single list or returns empty string if the list was empty
* @param propertyName
* @return
*/
public String getSingleProperty(String propertyName) {
List output = getProperty(propertyName);
if (output.size() > 0) {
return output.iterator().next();
}
logger.log(Level.SEVERE, "Unable to get {0} from aapt output: {1}", new Object[] {propertyName, badgingOutput});
return "";
}
/**
* Transforms list of properties to a single list or returns empty string if the list was empty
* @param propertyName
* @param propertySubName
* @return
*/
public String getSingleProperty(String propertyName, String propertySubName) {
List output = getProperty(propertyName, propertySubName);
if (output.size() > 0) {
return output.iterator().next();
}
logger.log(Level.SEVERE, "Unable to get {0}:{1} from aapt output: {2}", new Object[] {propertyName, propertySubName, badgingOutput});
return "";
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy