/**
* Original work provided by defunct 'autoandroid-1.0-rc5': http://code.google.com/p/autoandroid/
* New Derivative work required to repackage for wider distribution and continued development.
* Copyright (C) SAS Institute
* General Public License: http://www.opensource.org/licenses/gpl-license.php
**/
package org.safs.android.auto.lib;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class AndroidTools extends ConsoleTool{
private static AndroidTools tool = null;
/** "ANDROID_HOME" */
public static final String ANDROID_HOME_ENV_VAR = "ANDROID_HOME";
/** "ANDROID_SDK" */
public static final String ANDROID_SDK_ENV_VAR = "ANDROID_SDK";
/** "android-home" as in VM argument "-Dandroid-home=..." */
public static final String ANDROID_HOME_SYS_PROP = "android-home";
private AndroidTools(){super();}
/**
* TODO Do we need to keep this tool as a singleton?
* If different users call {@link #setToolHome(String)} to set different tool-path, problem!!!<br>
* But on one machine, it is rarely that user has different path for one tool. Different version?<br>
* @return
*/
public static synchronized AndroidTools get(){
if(tool==null){
tool = new AndroidTools();
}
return tool;
}
/** "tools" subdirectory in Android SDK */
public static final String ANDROID_SDK_TOOLS_DIR = "tools";
/** "platform-tools" subdirectory in Android SDK */
public static final String ANDROID_SDK_PLATFORM_TOOLS_DIR = "platform-tools";
/** "build-tools" subdirectory in Android SDK */
public static final String ANDROID_SDK_BUILD_TOOLS_DIR = "build-tools";
/** "platform" subdirectory in Android SDK */
public static final String ANDROID_SDK_PLATFORM_DIR = "platforms";
/** called internally to set the List of tools directories to search for tools.
* @see #ANDROID_SDK_OLD_TOOLS_DIR
* @see AndroidTools#ANDROID_SDK_NEW_TOOLS_DIR */
protected void modifyBinDirectories() {
binDirectories.clear();
binDirectories.add(ANDROID_SDK_TOOLS_DIR);
binDirectories.add(ANDROID_SDK_PLATFORM_TOOLS_DIR);
binDirectories.add(ANDROID_SDK_BUILD_TOOLS_DIR);
}
/**
* called internally to get the list (1) VM argument name to search for the
* Android SDK home directory.
* @see #ANDROID_HOME_SYS_PROP
*/
protected List<String> getToolHomeProperties(){
List<String> properties = new ArrayList<String>();
properties.add(ANDROID_HOME_SYS_PROP);
return properties;
}
/**
* called internally to get the list of environment variable names to search for
* the Android SDK home directory.
* @see #ANDROID_HOME_ENV_VAR
* @see #ANDROID_SDK_ENV_VAR
*/
protected List<String> getToolHomeEnvs(){
List<String> envs = new ArrayList<String>();
envs.add(ANDROID_HOME_ENV_VAR);
envs.add(ANDROID_SDK_ENV_VAR);
return envs;
}
/**
* If the directory is {@value #ANDROID_SDK_BUILD_TOOLS_DIR}, needs to
* search in the sub-directories. Because Android will store the executables
* in the version-sub-folder something like '17.0.0'
*/
protected boolean needSearchRecursively(String directoryName){
return ANDROID_SDK_BUILD_TOOLS_DIR.equals(directoryName);
}
/**
* If you are sure about the tool's home, you can set it.<br>
* Because if you set it, {@link #getToolHome()} will not try to get the tool's home<br>
* from "JVM properties" or "System environment variables"<br>
* This method is deprecated, please use {@link #setToolHome(String)} instead.<br>
*
* @param toolHome
* @see #getToolHome()
* @see #setToolHome(String)
* @deprecated
*/
public void setAndroidHome(String androidHome){
setToolHome(androidHome);
}
/** "aapt.exe" */
public static final String ANDROID_SDK_AAPT_TOOL_WIN = "aapt.exe";
/** "aapt" */
public static final String ANDROID_SDK_AAPT_TOOL_UNX = "aapt";
public Process2 aapt(String... args) throws IOException{
if(isWindowsOS()){
return exec(ANDROID_SDK_AAPT_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_AAPT_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start aapt on " + tool.getOsFamilyName());
}
}
public Process2 aapt(List<String> args) throws IOException {
return aapt(args.toArray(new String [0]));
}
/** "aidl.exe" */
public static final String ANDROID_SDK_AIDL_TOOL_WIN = "aidl.exe";
/** "aidl" */
public static final String ANDROID_SDK_AIDL_TOOL_UNX = "aidl";
public Process2 aidl(String... args) throws IOException {
if(isWindowsOS()){
return exec(ANDROID_SDK_AIDL_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_AIDL_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start aidl on " + tool.getOsFamilyName());
}
}
public Process2 aidl(List<String> args) throws IOException {
return aidl(args.toArray(new String [0]));
}
/** "apkbuilder.bat" */
public static final String ANDROID_SDK_APKBUILDER_TOOL_WIN = "apkbuilder.bat";
/** "apkbuilder" */
public static final String ANDROID_SDK_APKBUILDER_TOOL_UNX = "apkbuilder";
public Process2 apkBuilder(String... args) throws IOException {
if(isWindowsOS()){
return batch(ANDROID_SDK_APKBUILDER_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_APKBUILDER_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start apkbuilder on " + tool.getOsFamilyName());
}
}
public Process2 apkBuilder(List<String> args) throws IOException {
return apkBuilder(args.toArray(new String [0]));
}
/** "adb.exe" */
public static final String ANDROID_SDK_ADB_TOOL_WIN = "adb.exe";
/** "adb" */
public static final String ANDROID_SDK_ADB_TOOL_UNX = "adb";
public Process2 adb(String... args) throws IOException {
if(isWindowsOS()){
return exec(ANDROID_SDK_ADB_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_ADB_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start adb on " + tool.getOsFamilyName());
}
}
public Process2 adb(List<String> args) throws IOException {
return adb(args.toArray(new String [0]));
}
/** "ddms.bat" */
public static final String ANDROID_SDK_DDMS_TOOL_WIN = "ddms.bat";
/** "ddms" */
public static final String ANDROID_SDK_DDMS_TOOL_UNX = "ddms";
public Process2 ddms(String... args) throws IOException {
if(isWindowsOS()){
return batch(ANDROID_SDK_DDMS_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_DDMS_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start ddms on " + tool.getOsFamilyName());
}
}
public Process2 ddms(List<String> args) throws IOException {
return ddms(args.toArray(new String [0]));
}
/** "dmtracedump.exe" */
public static final String ANDROID_SDK_DMTRACEDUMP_TOOL_WIN = "dmtracedump.exe";
/** "dmtracedump" */
public static final String ANDROID_SDK_DMTRACEDUMP_TOOL_UNX = "dmtracedump";
public Process2 dmtracedump(String... args) throws IOException {
if(isWindowsOS()){
return exec(ANDROID_SDK_DMTRACEDUMP_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_DMTRACEDUMP_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start dmtracedump on " + tool.getOsFamilyName());
}
}
public Process2 dmtracedump(List<String> args) throws IOException {
return dmtracedump(args.toArray(new String [0]));
}
/** "dx.bat" */
public static final String ANDROID_SDK_DX_TOOL_WIN = "dx.bat";
/** "dx" */
public static final String ANDROID_SDK_DX_TOOL_UNX = "dx";
public Process2 dx(String... args) throws IOException {
if(isWindowsOS()){
return batch(ANDROID_SDK_DX_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_DX_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start dx on " + tool.getOsFamilyName());
}
}
public Process2 dx(List<String> args) throws IOException {
return dx(args.toArray(new String [0]));
}
/** "emulator.exe" */
public static final String ANDROID_SDK_EMULATOR_TOOL_WIN = "emulator.exe";
/** "emulator" */
public static final String ANDROID_SDK_EMULATOR_TOOL_UNX = "emulator";
public Process2 emulator(String... args) throws IOException {
Process2 proc = null;
if(isWindowsOS()){
proc = exec(ANDROID_SDK_EMULATOR_TOOL_WIN, args);
// allow 2nd (hidden) emulator-arm.exe process time to get started
try{Thread.sleep(5000);}catch(Exception x){}
return proc;
}else if(isUnixOS()){
proc = exec(ANDROID_SDK_EMULATOR_TOOL_UNX, args);
try{Thread.sleep(5000);}catch(Exception x){}
return proc;
}else{
throw new UnsupportedOperationException("Don't know how to start emulator on " + tool.getOsFamilyName());
}
}
public Process2 emulator(List<String> args) throws IOException {
return emulator(args.toArray(new String [0]));
}
/** "mksdcard.exe" */
public static final String ANDROID_SDK_MKSDCARD_TOOL_WIN = "mksdcard.exe";
/** "mksdcard" */
public static final String ANDROID_SDK_MKSDCARD_TOOL_UNX = "mksdcard";
public Process2 mksdcard(String... args) throws IOException {
if(isWindowsOS()){
return exec(ANDROID_SDK_MKSDCARD_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_MKSDCARD_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start mksdcard on " + tool.getOsFamilyName());
}
}
public Process2 mksdcard(List<String> args) throws IOException {
return mksdcard(args.toArray(new String [0]));
}
/** "sqlite3.exe" */
public static final String ANDROID_SDK_SQLITE3_TOOL_WIN = "sqlite3.exe";
/** "sqlite3" */
public static final String ANDROID_SDK_SQLITE3_TOOL_UNX = "sqlite3";
public Process2 sqlite3(String... args) throws IOException {
if(isWindowsOS()){
return exec(ANDROID_SDK_SQLITE3_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_SQLITE3_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start sqlite3 on " + tool.getOsFamilyName());
}
}
public Process2 sqlite3(List<String> args) throws IOException {
return sqlite3(args.toArray(new String [0]));
}
/** "traceview.bat" */
public static final String ANDROID_SDK_TRACEVIEW_TOOL_WIN = "traceview.bat";
/** "traceview" */
public static final String ANDROID_SDK_TRACEVIEW_TOOL_UNX = "traceview";
public Process2 traceview(String... args) throws IOException {
if(isWindowsOS()){
return batch(ANDROID_SDK_TRACEVIEW_TOOL_WIN, args);
}else if(isUnixOS()){
return exec(ANDROID_SDK_TRACEVIEW_TOOL_UNX, args);
}else{
throw new UnsupportedOperationException("Don't know how to start traceview on " + tool.getOsFamilyName());
}
}
public Process2 traceview(List<String> args) throws IOException {
return traceview(args.toArray(new String [0]));
}
public List<Integer> getInstalledSKDLevel(){
List<Integer> levels = new ArrayList<Integer>();
String toolHome = getToolHome();
String subdirPrefix = "android-";
File directory = new File(toolHome, ANDROID_SDK_PLATFORM_DIR);
if(directory.exists() && directory.isDirectory()){
int level = 0;
String childName = null;
File[] children = directory.listFiles();
for(File child: children){
childName = child.getName();
if(child.isDirectory() && childName.startsWith(subdirPrefix)){
try{
level = Integer.parseInt(childName.substring(subdirPrefix.length()));
levels.add(level);
}catch(NumberFormatException ignore){}
}
}
}
return levels;
}
}