Merge korg/donut into korg/master

Conflicts:

	tools/eclipse/plugins/README.txt
	tools/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java
This commit is contained in:
Jean-Baptiste Queru
2009-07-25 17:25:52 -07:00
2132 changed files with 100935 additions and 9901 deletions

2
tools/androidprefs/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
bin

2
tools/anttasks/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
bin

View File

@@ -16,9 +16,9 @@
package com.android.ant;
import com.android.sdklib.project.ApkConfigurationHelper;
import com.android.sdklib.project.ProjectProperties;
import com.android.sdklib.project.ProjectProperties.PropertyType;
import com.android.sdklib.internal.project.ApkConfigurationHelper;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

View File

@@ -16,11 +16,12 @@
package com.android.ant;
import com.android.apkbuilder.ApkBuilder;
import com.android.apkbuilder.ApkBuilder.ApkFile;
import com.android.sdklib.project.ApkConfigurationHelper;
import com.android.sdklib.project.ProjectProperties;
import com.android.sdklib.project.ProjectProperties.PropertyType;
import com.android.apkbuilder.ApkBuilder.ApkCreationException;
import com.android.apkbuilder.internal.ApkBuilderImpl;
import com.android.apkbuilder.internal.ApkBuilderImpl.ApkFile;
import com.android.sdklib.internal.project.ApkConfigurationHelper;
import com.android.sdklib.internal.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -37,7 +38,7 @@ import java.util.Set;
import java.util.Map.Entry;
public class ApkBuilderTask extends Task {
/**
* Class to represent nested elements. Since they all have only one attribute ('path'), the
* same class can be used for all the nested elements (zip, file, sourcefolder, jarfolder,
@@ -45,7 +46,7 @@ public class ApkBuilderTask extends Task {
*/
public final static class Value extends ProjectComponent {
String mPath;
/**
* Sets the value of the "path" attribute.
* @param path the value.
@@ -59,7 +60,7 @@ public class ApkBuilderTask extends Task {
private String mBaseName;
private boolean mVerbose = false;
private boolean mSigned = true;
private final ArrayList<Value> mZipList = new ArrayList<Value>();
private final ArrayList<Value> mFileList = new ArrayList<Value>();
private final ArrayList<Value> mSourceList = new ArrayList<Value>();
@@ -79,7 +80,7 @@ public class ApkBuilderTask extends Task {
public void setOutfolder(Path outFolder) {
mOutFolder = outFolder.toString();
}
/**
* Sets the value of the "basename" attribute.
* @param baseName the value.
@@ -87,7 +88,7 @@ public class ApkBuilderTask extends Task {
public void setBasename(String baseName) {
mBaseName = baseName;
}
/**
* Sets the value of the "verbose" attribute.
* @param verbose the value.
@@ -95,7 +96,7 @@ public class ApkBuilderTask extends Task {
public void setVerbose(boolean verbose) {
mVerbose = verbose;
}
/**
* Sets the value of the "signed" attribute.
* @param signed the value.
@@ -103,7 +104,7 @@ public class ApkBuilderTask extends Task {
public void setSigned(boolean signed) {
mSigned = signed;
}
/**
* Returns an object representing a nested <var>zip</var> element.
*/
@@ -112,7 +113,7 @@ public class ApkBuilderTask extends Task {
mZipList.add(zip);
return zip;
}
/**
* Returns an object representing a nested <var>file</var> element.
*/
@@ -139,7 +140,7 @@ public class ApkBuilderTask extends Task {
mJarList.add(file);
return file;
}
/**
* Returns an object representing a nested <var>nativefolder</var> element.
*/
@@ -148,64 +149,64 @@ public class ApkBuilderTask extends Task {
mNativeList.add(file);
return file;
}
@Override
public void execute() throws BuildException {
Project taskProject = getProject();
ApkBuilder apkBuilder = new ApkBuilder();
ApkBuilderImpl apkBuilder = new ApkBuilderImpl();
apkBuilder.setVerbose(mVerbose);
apkBuilder.setSignedPackage(mSigned);
try {
// setup the list of everything that needs to go in the archive.
// go through the list of zip files to add. This will not include
// the resource package, which is handled separaly for each apk to create.
for (Value v : mZipList) {
FileInputStream input = new FileInputStream(v.mPath);
mZipArchives.add(input);
}
// now go through the list of file to directly add the to the list.
for (Value v : mFileList) {
mArchiveFiles.add(ApkBuilder.getInputFile(v.mPath));
mArchiveFiles.add(ApkBuilderImpl.getInputFile(v.mPath));
}
// now go through the list of file to directly add the to the list.
for (Value v : mSourceList) {
ApkBuilder.processSourceFolderForResource(v.mPath, mJavaResources);
ApkBuilderImpl.processSourceFolderForResource(v.mPath, mJavaResources);
}
// now go through the list of jar folders.
for (Value v : mJarList) {
ApkBuilder.processJarFolder(v.mPath, mResourcesJars);
ApkBuilderImpl.processJarFolder(v.mPath, mResourcesJars);
}
// now the native lib folder.
for (Value v : mNativeList) {
String parameter = v.mPath;
File f = new File(parameter);
// compute the offset to get the relative path
int offset = parameter.length();
if (parameter.endsWith(File.separator) == false) {
offset++;
}
ApkBuilder.processNativeFolder(offset, f, mNativeLibraries);
ApkBuilderImpl.processNativeFolder(offset, f, mNativeLibraries);
}
// first do a full resource package
createApk(apkBuilder, null /*configName*/, null /*resourceFilter*/);
// now see if we need to create file with filtered resources.
// Get the project base directory.
File baseDir = taskProject.getBaseDir();
ProjectProperties properties = ProjectProperties.load(baseDir.getAbsolutePath(),
PropertyType.DEFAULT);
Map<String, String> apkConfigs = ApkConfigurationHelper.getConfigs(properties);
if (apkConfigs.size() > 0) {
Set<Entry<String, String>> entrySet = apkConfigs.entrySet();
@@ -217,20 +218,23 @@ public class ApkBuilderTask extends Task {
throw new BuildException(e);
} catch (IllegalArgumentException e) {
throw new BuildException(e);
} catch (ApkCreationException e) {
throw new BuildException(e);
}
}
/**
* Creates an application package.
* @param apkBuilder
* @param apkBuilder
* @param configName the name of the filter config. Can be null in which case a full resource
* package will be generated.
* @param resourceFilter the resource configuration filter to pass to aapt (if configName is
* non null)
* @throws FileNotFoundException
* @throws FileNotFoundException
* @throws ApkCreationException
*/
private void createApk(ApkBuilder apkBuilder, String configName, String resourceFilter)
throws FileNotFoundException {
private void createApk(ApkBuilderImpl apkBuilder, String configName, String resourceFilter)
throws FileNotFoundException, ApkCreationException {
// All the files to be included in the archive have already been prep'ed up, except
// the resource package.
// figure out its name.
@@ -240,20 +244,20 @@ public class ApkBuilderTask extends Task {
} else {
filename = mBaseName + ".ap_";
}
// now we add it to the list of zip archive (it's just a zip file).
// it's used as a zip archive input
FileInputStream resoucePackageZipFile = new FileInputStream(new File(mOutFolder, filename));
mZipArchives.add(resoucePackageZipFile);
// prepare the filename to generate. Same thing as the resource file.
if (configName != null && resourceFilter != null) {
filename = mBaseName + "-" + configName;
} else {
filename = mBaseName;
}
if (mSigned) {
filename = filename + "-debug.apk";
} else {
@@ -279,13 +283,13 @@ public class ApkBuilderTask extends Task {
filename, resourceFilter));
}
}
File f = new File(mOutFolder, filename);
// and generate the apk
apkBuilder.createPackage(f.getAbsoluteFile(), mZipArchives,
mArchiveFiles, mJavaResources, mResourcesJars, mNativeLibraries);
// we are done. We need to remove the resource package from the list of zip archives
// in case we have another apk to generate.
mZipArchives.remove(resoucePackageZipFile);

View File

@@ -20,7 +20,7 @@ import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkManager;
import com.android.sdklib.IAndroidTarget.IOptionalLibrary;
import com.android.sdklib.project.ProjectProperties;
import com.android.sdklib.internal.project.ProjectProperties;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;

2
tools/apkbuilder/.gitignore vendored Normal file
View File

@@ -0,0 +1,2 @@
bin

View File

@@ -16,419 +16,69 @@
package com.android.apkbuilder;
import com.android.jarutils.DebugKeyProvider;
import com.android.jarutils.JavaResourceFilter;
import com.android.jarutils.SignedJarBuilder;
import com.android.jarutils.DebugKeyProvider.KeytoolException;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.apkbuilder.internal.ApkBuilderImpl;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.regex.Pattern;
/**
* Command line APK builder with signing support.
*/
public final class ApkBuilder {
private final static Pattern PATTERN_JAR_EXT = Pattern.compile("^.+\\.jar$",
Pattern.CASE_INSENSITIVE);
private final static Pattern PATTERN_NATIVELIB_EXT = Pattern.compile("^.+\\.so$",
Pattern.CASE_INSENSITIVE);
private final static String NATIVE_LIB_ROOT = "lib/";
/**
* A File to be added to the APK archive.
* <p/>This includes the {@link File} representing the file and its path in the archive.
*/
public final static class ApkFile {
String archivePath;
File file;
public final static class WrongOptionException extends Exception {
private static final long serialVersionUID = 1L;
ApkFile(File file, String path) {
this.file = file;
this.archivePath = path;
public WrongOptionException(String message) {
super(message);
}
}
private JavaResourceFilter mResourceFilter = new JavaResourceFilter();
private boolean mVerbose = false;
private boolean mSignedPackage = true;
/** the optional type of the debug keystore. If <code>null</code>, the default */
private String mStoreType = null;
public final static class ApkCreationException extends Exception {
private static final long serialVersionUID = 1L;
public ApkCreationException(String message) {
super(message);
}
public ApkCreationException(Throwable throwable) {
super(throwable);
}
}
/**
* @param args
* Main method. This is meant to be called from the command line through an exec.
* <p/>WARNING: this will call {@link System#exit(int)} if anything goes wrong.
* @param args command line arguments.
*/
public static void main(String[] args) {
new ApkBuilder().run(args);
}
public void setVerbose(boolean verbose) {
mVerbose = verbose;
}
public void setSignedPackage(boolean signedPackage) {
mSignedPackage = signedPackage;
}
private void run(String[] args) {
if (args.length < 1) {
printUsageAndQuit();
}
try {
// read the first args that should be a file path
File outFile = getOutFile(args[0]);
ArrayList<FileInputStream> zipArchives = new ArrayList<FileInputStream>();
ArrayList<File> archiveFiles = new ArrayList<File>();
ArrayList<ApkFile> javaResources = new ArrayList<ApkFile>();
ArrayList<FileInputStream> resourcesJars = new ArrayList<FileInputStream>();
ArrayList<ApkFile> nativeLibraries = new ArrayList<ApkFile>();
int index = 1;
do {
String argument = args[index++];
if ("-v".equals(argument)) {
mVerbose = true;
} else if ("-u".equals(argument)) {
mSignedPackage = false;
} else if ("-z".equals(argument)) {
// quick check on the next argument.
if (index == args.length) printUsageAndQuit();
try {
FileInputStream input = new FileInputStream(args[index++]);
zipArchives.add(input);
} catch (FileNotFoundException e) {
printAndExit(e.getMessage());
}
} else if ("-f". equals(argument)) {
// quick check on the next argument.
if (index == args.length) printUsageAndQuit();
archiveFiles.add(getInputFile(args[index++]));
} else if ("-rf". equals(argument)) {
// quick check on the next argument.
if (index == args.length) printUsageAndQuit();
processSourceFolderForResource(args[index++], javaResources);
} else if ("-rj". equals(argument)) {
// quick check on the next argument.
if (index == args.length) printUsageAndQuit();
processJarFolder(args[index++], resourcesJars);
} else if ("-nf".equals(argument)) {
// quick check on the next argument.
if (index == args.length) printUsageAndQuit();
String parameter = args[index++];
File f = new File(parameter);
// compute the offset to get the relative path
int offset = parameter.length();
if (parameter.endsWith(File.separator) == false) {
offset++;
}
processNativeFolder(offset, f, nativeLibraries);
} else if ("-storetype".equals(argument)) {
// quick check on the next argument.
if (index == args.length) printUsageAndQuit();
mStoreType = args[index++];
} else {
printAndExit("Unknown argument: " + argument);
}
} while (index < args.length);
createPackage(outFile, zipArchives, archiveFiles, javaResources, resourcesJars,
nativeLibraries);
} catch (IllegalArgumentException e) {
printAndExit(e.getMessage());
new ApkBuilderImpl().run(args);
} catch (WrongOptionException e) {
printUsageAndQuit();
} catch (FileNotFoundException e) {
printAndExit(e.getMessage());
}
}
private File getOutFile(String filepath) {
File f = new File(filepath);
if (f.isDirectory()) {
printAndExit(filepath + " is a directory!");
}
if (f.exists()) { // will be a file in this case.
if (f.canWrite() == false) {
printAndExit("Cannot write " + filepath);
}
} else {
try {
if (f.createNewFile() == false) {
printAndExit("Failed to create " + filepath);
}
} catch (IOException e) {
printAndExit("Failed to create '" + filepath + "' : " + e.getMessage());
}
}
return f;
}
public static File getInputFile(String filepath) throws IllegalArgumentException {
File f = new File(filepath);
if (f.isDirectory()) {
throw new IllegalArgumentException(filepath + " is a directory!");
}
if (f.exists()) {
if (f.canRead() == false) {
throw new IllegalArgumentException("Cannot read " + filepath);
}
} else {
throw new IllegalArgumentException(filepath + " does not exists!");
}
return f;
}
/**
* Processes a source folder and adds its java resources to a given list of {@link ApkFile}.
* @param folderPath the path to the source folder.
* @param javaResources the list of {@link ApkFile} to fill.
*/
public static void processSourceFolderForResource(String folderPath,
ArrayList<ApkFile> javaResources) {
File folder = new File(folderPath);
if (folder.isDirectory()) {
// file is a directory, process its content.
File[] files = folder.listFiles();
for (File file : files) {
processFileForResource(file, null, javaResources);
}
} else {
// not a directory? output error and quit.
if (folder.exists()) {
throw new IllegalArgumentException(folderPath + " is not a folder!");
} else {
throw new IllegalArgumentException(folderPath + " does not exist!");
}
}
}
public static void processJarFolder(String parameter, ArrayList<FileInputStream> resourcesJars)
throws FileNotFoundException {
File f = new File(parameter);
if (f.isDirectory()) {
String[] files = f.list(new FilenameFilter() {
public boolean accept(File dir, String name) {
return PATTERN_JAR_EXT.matcher(name).matches();
}
});
for (String file : files) {
String path = f.getAbsolutePath() + File.separator + file;
FileInputStream input = new FileInputStream(path);
resourcesJars.add(input);
}
} else {
FileInputStream input = new FileInputStream(parameter);
resourcesJars.add(input);
}
}
/**
* Processes a {@link File} that could be a {@link ApkFile}, or a folder containing
* java resources.
* @param file the {@link File} to process.
* @param path the relative path of this file to the source folder. Can be <code>null</code> to
* identify a root file.
* @param javaResources the list of {@link ApkFile} object to fill.
*/
private static void processFileForResource(File file, String path,
ArrayList<ApkFile> javaResources) {
if (file.isDirectory()) {
// a directory? we check it
if (JavaResourceFilter.checkFolderForPackaging(file.getName())) {
// if it's valid, we append its name to the current path.
if (path == null) {
path = file.getName();
} else {
path = path + "/" + file.getName();
}
// and process its content.
File[] files = file.listFiles();
for (File contentFile : files) {
processFileForResource(contentFile, path, javaResources);
}
}
} else {
// a file? we check it
if (JavaResourceFilter.checkFileForPackaging(file.getName())) {
// we append its name to the current path
if (path == null) {
path = file.getName();
} else {
path = path + "/" + file.getName();
}
// and add it to the list.
javaResources.add(new ApkFile(file, path));
}
}
}
/**
* Process a {@link File} for native library inclusion.
* @param offset the length of the root folder (used to compute relative path)
* @param f the {@link File} to process
* @param nativeLibraries the array to add native libraries.
*/
public static void processNativeFolder(int offset, File f, ArrayList<ApkFile> nativeLibraries) {
if (f.isDirectory()) {
File[] children = f.listFiles();
if (children != null) {
for (File child : children) {
processNativeFolder(offset, child, nativeLibraries);
}
}
} else if (f.isFile()) {
if (PATTERN_NATIVELIB_EXT.matcher(f.getName()).matches()) {
String path = NATIVE_LIB_ROOT +
f.getAbsolutePath().substring(offset).replace('\\', '/');
nativeLibraries.add(new ApkFile(f, path));
}
} catch (ApkCreationException e) {
printAndExit(e.getMessage());
}
}
/**
* Creates the application package
* @param outFile
* @param zipArchives
* @param resourcesJars
* @param files
* @param javaResources
* keystore type of the Java VM is used.
* API entry point similar to the {@link #main(String[])} method.
* <p/>Unlike {@link #main(String[])}, this will not call {@link System#exit(int)} and instead
* will throw exceptions.
* @param args command line arguments.
* @throws WrongOptionException if the command line arguments are incorrect.
* @throws FileNotFoundException if a required file was not found.
* @throws ApkCreationException if an error happened during the creation of the APK.
*/
public void createPackage(File outFile, ArrayList<FileInputStream> zipArchives,
ArrayList<File> files, ArrayList<ApkFile> javaResources,
ArrayList<FileInputStream> resourcesJars, ArrayList<ApkFile> nativeLibraries) {
// get the debug key
try {
SignedJarBuilder builder;
if (mSignedPackage) {
System.err.println(String.format("Using keystore: %s",
DebugKeyProvider.getDefaultKeyStoreOsPath()));
DebugKeyProvider keyProvider = new DebugKeyProvider(
null /* osKeyPath: use default */,
mStoreType, null /* IKeyGenOutput */);
PrivateKey key = keyProvider.getDebugKey();
X509Certificate certificate = (X509Certificate)keyProvider.getCertificate();
if (key == null) {
throw new IllegalArgumentException("Unable to get debug signature key");
}
// compare the certificate expiration date
if (certificate != null && certificate.getNotAfter().compareTo(new Date()) < 0) {
// TODO, regenerate a new one.
throw new IllegalArgumentException("Debug Certificate expired on " +
DateFormat.getInstance().format(certificate.getNotAfter()));
}
builder = new SignedJarBuilder(
new FileOutputStream(outFile.getAbsolutePath(), false /* append */), key,
certificate);
} else {
builder = new SignedJarBuilder(
new FileOutputStream(outFile.getAbsolutePath(), false /* append */),
null /* key */, null /* certificate */);
}
// add the archives
for (FileInputStream input : zipArchives) {
builder.writeZip(input, null /* filter */);
}
// add the single files
for (File input : files) {
// always put the file at the root of the archive in this case
builder.writeFile(input, input.getName());
if (mVerbose) {
System.err.println(String.format("%1$s => %2$s", input.getAbsolutePath(),
input.getName()));
}
}
// add the java resource from the source folders.
for (ApkFile resource : javaResources) {
builder.writeFile(resource.file, resource.archivePath);
if (mVerbose) {
System.err.println(String.format("%1$s => %2$s",
resource.file.getAbsolutePath(), resource.archivePath));
}
}
// add the java resource from jar files.
for (FileInputStream input : resourcesJars) {
builder.writeZip(input, mResourceFilter);
}
// add the native files
for (ApkFile file : nativeLibraries) {
builder.writeFile(file.file, file.archivePath);
if (mVerbose) {
System.err.println(String.format("%1$s => %2$s", file.file.getAbsolutePath(),
file.archivePath));
}
}
// close and sign the application package.
builder.close();
} catch (KeytoolException e) {
if (e.getJavaHome() == null) {
throw new IllegalArgumentException(e.getMessage() +
"\nJAVA_HOME seems undefined, setting it will help locating keytool automatically\n" +
"You can also manually execute the following command\n:" +
e.getCommandLine());
} else {
throw new IllegalArgumentException(e.getMessage() +
"\nJAVA_HOME is set to: " + e.getJavaHome() +
"\nUpdate it if necessary, or manually execute the following command:\n" +
e.getCommandLine());
}
} catch (AndroidLocationException e) {
throw new IllegalArgumentException(e);
} catch (Exception e) {
throw new IllegalArgumentException(e);
}
public static void createApk(String[] args) throws FileNotFoundException, WrongOptionException,
ApkCreationException {
new ApkBuilderImpl().run(args);
}
private void printUsageAndQuit() {
private static void printUsageAndQuit() {
// 80 cols marker: 01234567890123456789012345678901234567890123456789012345678901234567890123456789
System.err.println("A command line tool to package an Android application from various sources.");
System.err.println("Usage: apkbuilder <out archive> [-v][-u][-storetype STORE_TYPE] [-z inputzip]");
@@ -455,11 +105,11 @@ public final class ApkBuilder {
System.err.println("");
System.err.println(" -nf Followed by the root folder containing native libraries to");
System.err.println(" include in the application package.");
System.exit(1);
}
private void printAndExit(String... messages) {
private static void printAndExit(String... messages) {
for (String message : messages) {
System.err.println(message);
}

View File

@@ -0,0 +1,437 @@
/*
* Copyright (C) 2008 The Android Open Source Project
*
* 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 com.android.apkbuilder.internal;
import com.android.apkbuilder.ApkBuilder.WrongOptionException;
import com.android.apkbuilder.ApkBuilder.ApkCreationException;
import com.android.jarutils.DebugKeyProvider;
import com.android.jarutils.JavaResourceFilter;
import com.android.jarutils.SignedJarBuilder;
import com.android.jarutils.DebugKeyProvider.KeytoolException;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.security.PrivateKey;
import java.security.cert.X509Certificate;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.regex.Pattern;
/**
* Command line APK builder with signing support.
*/
public final class ApkBuilderImpl {
private final static Pattern PATTERN_JAR_EXT = Pattern.compile("^.+\\.jar$",
Pattern.CASE_INSENSITIVE);
private final static Pattern PATTERN_NATIVELIB_EXT = Pattern.compile("^.+\\.so$",
Pattern.CASE_INSENSITIVE);
private final static String NATIVE_LIB_ROOT = "lib/";
/**
* A File to be added to the APK archive.
* <p/>This includes the {@link File} representing the file and its path in the archive.
*/
public final static class ApkFile {
String archivePath;
File file;
ApkFile(File file, String path) {
this.file = file;
this.archivePath = path;
}
}
private JavaResourceFilter mResourceFilter = new JavaResourceFilter();
private boolean mVerbose = false;
private boolean mSignedPackage = true;
/** the optional type of the debug keystore. If <code>null</code>, the default */
private String mStoreType = null;
public void setVerbose(boolean verbose) {
mVerbose = verbose;
}
public void setSignedPackage(boolean signedPackage) {
mSignedPackage = signedPackage;
}
public void run(String[] args) throws WrongOptionException, FileNotFoundException,
ApkCreationException {
if (args.length < 1) {
throw new WrongOptionException("No options specified");
}
// read the first args that should be a file path
File outFile = getOutFile(args[0]);
ArrayList<FileInputStream> zipArchives = new ArrayList<FileInputStream>();
ArrayList<File> archiveFiles = new ArrayList<File>();
ArrayList<ApkFile> javaResources = new ArrayList<ApkFile>();
ArrayList<FileInputStream> resourcesJars = new ArrayList<FileInputStream>();
ArrayList<ApkFile> nativeLibraries = new ArrayList<ApkFile>();
int index = 1;
do {
String argument = args[index++];
if ("-v".equals(argument)) {
mVerbose = true;
} else if ("-u".equals(argument)) {
mSignedPackage = false;
} else if ("-z".equals(argument)) {
// quick check on the next argument.
if (index == args.length) {
throw new WrongOptionException("Missing value for -z");
}
try {
FileInputStream input = new FileInputStream(args[index++]);
zipArchives.add(input);
} catch (FileNotFoundException e) {
throw new ApkCreationException("-z file is not found");
}
} else if ("-f". equals(argument)) {
// quick check on the next argument.
if (index == args.length) {
throw new WrongOptionException("Missing value for -f");
}
archiveFiles.add(getInputFile(args[index++]));
} else if ("-rf". equals(argument)) {
// quick check on the next argument.
if (index == args.length) {
throw new WrongOptionException("Missing value for -rf");
}
processSourceFolderForResource(args[index++], javaResources);
} else if ("-rj". equals(argument)) {
// quick check on the next argument.
if (index == args.length) {
throw new WrongOptionException("Missing value for -rj");
}
processJarFolder(args[index++], resourcesJars);
} else if ("-nf".equals(argument)) {
// quick check on the next argument.
if (index == args.length) {
throw new WrongOptionException("Missing value for -nf");
}
String parameter = args[index++];
File f = new File(parameter);
// compute the offset to get the relative path
int offset = parameter.length();
if (parameter.endsWith(File.separator) == false) {
offset++;
}
processNativeFolder(offset, f, nativeLibraries);
} else if ("-storetype".equals(argument)) {
// quick check on the next argument.
if (index == args.length) {
throw new WrongOptionException("Missing value for -storetype");
}
mStoreType = args[index++];
} else {
throw new WrongOptionException("Unknown argument: " + argument);
}
} while (index < args.length);
createPackage(outFile, zipArchives, archiveFiles, javaResources, resourcesJars,
nativeLibraries);
}
private File getOutFile(String filepath) throws ApkCreationException {
File f = new File(filepath);
if (f.isDirectory()) {
throw new ApkCreationException(filepath + " is a directory!");
}
if (f.exists()) { // will be a file in this case.
if (f.canWrite() == false) {
throw new ApkCreationException("Cannot write " + filepath);
}
} else {
try {
if (f.createNewFile() == false) {
throw new ApkCreationException("Failed to create " + filepath);
}
} catch (IOException e) {
throw new ApkCreationException(
"Failed to create '" + filepath + "' : " + e.getMessage());
}
}
return f;
}
public static File getInputFile(String filepath) throws ApkCreationException {
File f = new File(filepath);
if (f.isDirectory()) {
throw new ApkCreationException(filepath + " is a directory!");
}
if (f.exists()) {
if (f.canRead() == false) {
throw new ApkCreationException("Cannot read " + filepath);
}
} else {
throw new ApkCreationException(filepath + " does not exists!");
}
return f;
}
/**
* Processes a source folder and adds its java resources to a given list of {@link ApkFile}.
* @param folderPath the path to the source folder.
* @param javaResources the list of {@link ApkFile} to fill.
* @throws ApkCreationException
*/
public static void processSourceFolderForResource(String folderPath,
ArrayList<ApkFile> javaResources) throws ApkCreationException {
File folder = new File(folderPath);
if (folder.isDirectory()) {
// file is a directory, process its content.
File[] files = folder.listFiles();
for (File file : files) {
processFileForResource(file, null, javaResources);
}
} else {
// not a directory? output error and quit.
if (folder.exists()) {
throw new ApkCreationException(folderPath + " is not a folder!");
} else {
throw new ApkCreationException(folderPath + " does not exist!");
}
}
}
public static void processJarFolder(String parameter, Collection<FileInputStream> resourcesJars)
throws FileNotFoundException {
File f = new File(parameter);
if (f.isDirectory()) {
String[] files = f.list(new FilenameFilter() {
public boolean accept(File dir, String name) {
return PATTERN_JAR_EXT.matcher(name).matches();
}
});
for (String file : files) {
String path = f.getAbsolutePath() + File.separator + file;
FileInputStream input = new FileInputStream(path);
resourcesJars.add(input);
}
} else {
FileInputStream input = new FileInputStream(parameter);
resourcesJars.add(input);
}
}
/**
* Processes a {@link File} that could be a {@link ApkFile}, or a folder containing
* java resources.
* @param file the {@link File} to process.
* @param path the relative path of this file to the source folder. Can be <code>null</code> to
* identify a root file.
* @param javaResources the Collection of {@link ApkFile} object to fill.
*/
private static void processFileForResource(File file, String path,
Collection<ApkFile> javaResources) {
if (file.isDirectory()) {
// a directory? we check it
if (JavaResourceFilter.checkFolderForPackaging(file.getName())) {
// if it's valid, we append its name to the current path.
if (path == null) {
path = file.getName();
} else {
path = path + "/" + file.getName();
}
// and process its content.
File[] files = file.listFiles();
for (File contentFile : files) {
processFileForResource(contentFile, path, javaResources);
}
}
} else {
// a file? we check it
if (JavaResourceFilter.checkFileForPackaging(file.getName())) {
// we append its name to the current path
if (path == null) {
path = file.getName();
} else {
path = path + "/" + file.getName();
}
// and add it to the list.
javaResources.add(new ApkFile(file, path));
}
}
}
/**
* Process a {@link File} for native library inclusion.
* @param offset the length of the root folder (used to compute relative path)
* @param f the {@link File} to process
* @param nativeLibraries the collection to add native libraries to.
*/
public static void processNativeFolder(int offset, File f,
Collection<ApkFile> nativeLibraries) {
if (f.isDirectory()) {
File[] children = f.listFiles();
if (children != null) {
for (File child : children) {
processNativeFolder(offset, child, nativeLibraries);
}
}
} else if (f.isFile()) {
if (PATTERN_NATIVELIB_EXT.matcher(f.getName()).matches()) {
String path = NATIVE_LIB_ROOT +
f.getAbsolutePath().substring(offset).replace('\\', '/');
nativeLibraries.add(new ApkFile(f, path));
}
}
}
/**
* Creates the application package
* @param outFile the package file to create
* @param zipArchives the list of zip archive
* @param files the list of files to include in the archive
* @param javaResources the list of java resources from the source folders.
* @param resourcesJars the list of jar files from which to take java resources
* @throws ApkCreationException
*/
public void createPackage(File outFile, Iterable<? extends FileInputStream> zipArchives,
Iterable<? extends File> files, Iterable<? extends ApkFile> javaResources,
Iterable<? extends FileInputStream> resourcesJars,
Iterable<? extends ApkFile> nativeLibraries) throws ApkCreationException {
// get the debug key
try {
SignedJarBuilder builder;
if (mSignedPackage) {
System.err.println(String.format("Using keystore: %s",
DebugKeyProvider.getDefaultKeyStoreOsPath()));
DebugKeyProvider keyProvider = new DebugKeyProvider(
null /* osKeyPath: use default */,
mStoreType, null /* IKeyGenOutput */);
PrivateKey key = keyProvider.getDebugKey();
X509Certificate certificate = (X509Certificate)keyProvider.getCertificate();
if (key == null) {
throw new ApkCreationException("Unable to get debug signature key");
}
// compare the certificate expiration date
if (certificate != null && certificate.getNotAfter().compareTo(new Date()) < 0) {
// TODO, regenerate a new one.
throw new ApkCreationException("Debug Certificate expired on " +
DateFormat.getInstance().format(certificate.getNotAfter()));
}
builder = new SignedJarBuilder(
new FileOutputStream(outFile.getAbsolutePath(), false /* append */), key,
certificate);
} else {
builder = new SignedJarBuilder(
new FileOutputStream(outFile.getAbsolutePath(), false /* append */),
null /* key */, null /* certificate */);
}
// add the archives
for (FileInputStream input : zipArchives) {
builder.writeZip(input, null /* filter */);
}
// add the single files
for (File input : files) {
// always put the file at the root of the archive in this case
builder.writeFile(input, input.getName());
if (mVerbose) {
System.err.println(String.format("%1$s => %2$s", input.getAbsolutePath(),
input.getName()));
}
}
// add the java resource from the source folders.
for (ApkFile resource : javaResources) {
builder.writeFile(resource.file, resource.archivePath);
if (mVerbose) {
System.err.println(String.format("%1$s => %2$s",
resource.file.getAbsolutePath(), resource.archivePath));
}
}
// add the java resource from jar files.
for (FileInputStream input : resourcesJars) {
builder.writeZip(input, mResourceFilter);
}
// add the native files
for (ApkFile file : nativeLibraries) {
builder.writeFile(file.file, file.archivePath);
if (mVerbose) {
System.err.println(String.format("%1$s => %2$s", file.file.getAbsolutePath(),
file.archivePath));
}
}
// close and sign the application package.
builder.close();
} catch (KeytoolException e) {
if (e.getJavaHome() == null) {
throw new ApkCreationException(e.getMessage() +
"\nJAVA_HOME seems undefined, setting it will help locating keytool automatically\n" +
"You can also manually execute the following command\n:" +
e.getCommandLine());
} else {
throw new ApkCreationException(e.getMessage() +
"\nJAVA_HOME is set to: " + e.getJavaHome() +
"\nUpdate it if necessary, or manually execute the following command:\n" +
e.getCommandLine());
}
} catch (AndroidLocationException e) {
throw new ApkCreationException(e);
} catch (Exception e) {
throw new ApkCreationException(e);
}
}
}

View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="output" path="bin"/>
</classpath>

1
tools/archquery/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
bin

17
tools/archquery/.project Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>archquery</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@@ -0,0 +1,17 @@
#
# Copyright (C) 2009 The Android Open Source Project
#
# 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.
#
ARCHQUERY_LOCAL_DIR := $(call my-dir)
include $(ARCHQUERY_LOCAL_DIR)/src/Android.mk

View File

@@ -0,0 +1 @@
Main-Class: com.android.archquery.Main

View File

@@ -0,0 +1,25 @@
#
# Copyright (C) 2009 The Android Open Source Project
#
# 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.
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
LOCAL_JAR_MANIFEST := ../etc/manifest.txt
LOCAL_JAVA_LIBRARIES := \
LOCAL_MODULE := archquery
include $(BUILD_HOST_JAVA_LIBRARY)

View File

@@ -0,0 +1,72 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 com.android.archquery;
/**
* Java command line tool to return the CPU architecture of the host java VM.
*
* The goal is to be able to launch SWT based applications (DDMS, Traceview, Android) on any
* type of OS.
*
* Because a 64 bit OS can run a 32 bit Virtual Machine, we need to query the VM itself to know
* whether it's 32 or 64 bit to detect which swt.jar it should use (it contains native libraries).
* Simply querying the OS is not enough.
*
* The other problem is that once a VM is launched it is impossible to change its classpath to
* point the VM to the correct version of swt.jar.
*
* The solution is this small command line tool, running in the VM, and returning the value of
* the 'os.arch' property. Based on the returned value, the script launching the SWT based
* applications will configure the Java VM with the path to the correct swt.jar
*
* Because different VMs return different values for 32 and 64 bit version of x86 CPUs, the program
* handles all the possible values and normalize the returned value.
*
* At this time, the normalized values are:
* x86: 32 bit x86
* x86_64: 64 bit x86
* ppc: PowerPC (WARNING: the SDK doesn't actually support this architecture).
*
*
*/
public final class Main {
public static void main(String[] args) {
for (String arg : args) {
System.out.println(String.format("%1$s: %2$s", arg, System.getProperty(arg)));
}
if (args.length == 0) {
// Values listed from http://lopica.sourceforge.net/os.html
String arch = System.getProperty("os.arch");
if (arch.equalsIgnoreCase("x86_64") || arch.equalsIgnoreCase("amd64")) {
System.out.print("x86_64");
} else if (arch.equalsIgnoreCase("x86")
|| arch.equalsIgnoreCase("i386")
|| arch.equalsIgnoreCase("i686")) {
System.out.print("x86");
} else if (arch.equalsIgnoreCase("ppc") || arch.equalsIgnoreCase("PowerPC")) {
System.out.print("ppc");
} else {
System.out.print(arch);
}
}
}
}

4
tools/ddms/.gitignore vendored Normal file
View File

@@ -0,0 +1,4 @@
app/bin
libs/ddmlib/bin
libs/ddmuilib/bin

View File

@@ -1,4 +1,4 @@
#!/bin/sh
#!/bin/bash
# Copyright 2005-2007, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
@@ -79,6 +79,32 @@ else
jarpath="$frameworkdir/$jarfile"
fi
# Figure out the path to the swt.jar for the current architecture.
# if ANDROID_SWT is defined, then just use this.
# else, if running in the Android source tree, then look for the correct swt folder in prebuilt
# else, look for the correct swt folder in the SDK under tools/lib/
swtpath=""
if [ -n "$ANDROID_SWT" ]; then
swtpath="$ANDROID_SWT"
else
vmarch=`java -jar "${frameworkdir}"/archquery.jar`
if [ -n "$ANDROID_BUILD_TOP" ]; then
osname=`uname -s | tr A-Z a-z`
swtpath="${ANDROID_BUILD_TOP}/prebuilt/${osname}-${vmarch}/swt"
else
swtpath="${frameworkdir}/${vmarch}"
fi
fi
# Combine the swtpath and the framework dir path.
if [ -d "$swtpath" ]; then
frameworkdir="${swtpath}:${frameworkdir}"
else
echo "SWT folder '${swtpath}' does not exist."
echo "Please export ANDROID_SWT to point to the folder containing swt.jar for your platform."
exit 1
fi
# need to use "java.ext.dirs" because "-jar" causes classpath to be ignored
# might need more memory, e.g. -Xmx128M
exec "$java_cmd" -Xmx256M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Djava.library.path="$libdir" -Dcom.android.ddms.bindir="$progdir" -jar "$jarpath" "$@"
exec "$java_cmd" -Xmx256M $os_opts $java_debug -Djava.ext.dirs="$frameworkdir" -Dcom.android.ddms.bindir="$progdir" -jar "$jarpath" "$@"

View File

@@ -26,15 +26,12 @@ cd /d %~dp0
set jarfile=ddms.jar
set frameworkdir=
set libdir=
if exist %frameworkdir%%jarfile% goto JarFileOk
set frameworkdir=lib\
set libdir=lib\
if exist %frameworkdir%%jarfile% goto JarFileOk
set frameworkdir=..\framework\
set libdir=..\lib\
:JarFileOk
@@ -45,4 +42,23 @@ if debug NEQ "%1" goto NoDebug
set jarpath=%frameworkdir%%jarfile%
call java %java_debug% -Djava.ext.dirs=%frameworkdir% -Djava.library.path=%libdir% -Dcom.android.ddms.bindir= -jar %jarpath% %*
if not defined ANDROID_SWT goto QueryArch
set swt_path=%ANDROID_SWT%
goto SwtDone
:QueryArch
for /f %%a in ('java -jar %frameworkdir%archquery.jar') do set swt_path=%frameworkdir%%%a
:SwtDone
if exist %swt_path% goto SetPath
echo SWT folder '%swt_path%' does not exist.
echo Please set ANDROID_SWT to point to the folder containing swt.jar for your platform.
exit /B
:SetPath
set javaextdirs=%swt_path%;%frameworkdir%
call java %java_debug% -Djava.ext.dirs=%javaextdirs% -Dcom.android.ddms.bindir= -jar %jarpath% %*

View File

@@ -13,9 +13,9 @@ LOCAL_JAVA_LIBRARIES := \
ddmlib \
ddmuilib \
swt \
org.eclipse.jface_3.2.0.I20060605-1400 \
org.eclipse.equinox.common_3.2.0.v20060603 \
org.eclipse.core.commands_3.2.0.I20060605-1400
org.eclipse.jface_3.4.2.M20090107-0800 \
org.eclipse.equinox.common_3.4.0.v20080421-2006 \
org.eclipse.core.commands_3.4.0.I20080509-2000
LOCAL_MODULE := ddms
include $(BUILD_HOST_JAVA_LIBRARY)

View File

@@ -16,7 +16,7 @@
package com.android.ddms;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
import org.eclipse.jface.preference.IPreferenceStore;
@@ -53,15 +53,15 @@ public class DebugPortProvider implements IDebugPortProvider {
/**
* Returns a static debug port for the specified application running on the
* specified {@link Device}.
* specified {@link IDevice}.
* @param device The device the application is running on.
* @param appName The application name, as defined in the
* AndroidManifest.xml package attribute.
* @return The static debug port or {@link #NO_STATIC_PORT} if there is none setup.
*
* @see IDebugPortProvider#getPort(Device, String)
* @see IDebugPortProvider#getPort(IDevice, String)
*/
public int getPort(Device device, String appName) {
public int getPort(IDevice device, String appName) {
if (mMap != null) {
Map<String, Integer> deviceMap = mMap.get(device.getSerialNumber());
if (deviceMap != null) {
@@ -107,7 +107,7 @@ public class DebugPortProvider implements IDebugPortProvider {
if (entry.length == 3) {
deviceName = entry[2];
} else {
deviceName = Device.FIRST_EMULATOR_SN;
deviceName = IDevice.FIRST_EMULATOR_SN;
}
// get the device map

View File

@@ -17,7 +17,7 @@
package com.android.ddms;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.Log;
@@ -96,7 +96,7 @@ public class DeviceCommandDialog extends Dialog {
* Prepare and display the dialog.
* @param currentDevice
*/
public void open(Device currentDevice) {
public void open(IDevice currentDevice) {
Shell parent = getParent();
Shell shell = new Shell(parent, getStyle());
shell.setText("Remote Command");
@@ -219,13 +219,13 @@ public class DeviceCommandDialog extends Dialog {
private String mCommand;
private Text mText;
private int mResult;
private Device mDevice;
private IDevice mDevice;
/**
* Constructor; pass in the text widget that will receive the output.
* @param device
*/
public Gatherer(Shell shell, Device device, String command, Text text) {
public Gatherer(Shell shell, IDevice device, String command, Text text) {
mShell = shell;
mDevice = device;
mCommand = command;
@@ -307,7 +307,7 @@ public class DeviceCommandDialog extends Dialog {
* We have to run the command in a thread so that the UI continues
* to work.
*/
private void executeCommand(Shell shell, Device device) {
private void executeCommand(Shell shell, IDevice device) {
Gatherer gath = new Gatherer(shell, device, commandString(), mText);
gath.start();
}

View File

@@ -78,7 +78,7 @@ public class Main {
// the "ping" argument means to check in with the server and exit
// the application name and version number must also be supplied
if (args.length >= 3 && args[0].equals("ping")) {
SdkStatsService.ping(args[1], args[2]);
SdkStatsService.ping(args[1], args[2], null);
return;
} else if (args.length > 0) {
Log.e("ddms", "Unknown argument: " + args[0]);
@@ -86,7 +86,7 @@ public class Main {
}
// ddms itself is wanted: send a ping for ourselves
SdkStatsService.ping("ddms", VERSION); //$NON-NLS-1$
SdkStatsService.ping("ddms", VERSION, null); //$NON-NLS-1$
DebugPortManager.setProvider(DebugPortProvider.getInstance());

View File

@@ -16,7 +16,7 @@
package com.android.ddms;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
@@ -75,7 +75,7 @@ public class StaticPortEditDialog extends Dialog {
public StaticPortEditDialog(Shell parent, ArrayList<Integer> ports) {
super(parent, SWT.DIALOG_TRIM | SWT.BORDER | SWT.APPLICATION_MODAL);
mPorts = ports;
mDeviceSn = Device.FIRST_EMULATOR_SN;
mDeviceSn = IDevice.FIRST_EMULATOR_SN;
}
/**

View File

@@ -18,7 +18,7 @@ package com.android.ddms;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Client;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.Log.ILogOutput;
import com.android.ddmlib.Log.LogLevel;
@@ -90,7 +90,7 @@ import java.util.ArrayList;
/**
* This acts as the UI builder. This cannot be its own thread since this prevent using AWT in an
* SWT application. So this class mainly builds the ui, and manages communication between the panels
* when {@link Device} / {@link Client} selection changes.
* when {@link IDevice} / {@link Client} selection changes.
*/
public class UIThread implements IUiSelectionListener {
/*
@@ -153,7 +153,7 @@ public class UIThread implements IUiSelectionListener {
// the table we show in the left-hand pane
private DevicePanel mDevicePanel;
private Device mCurrentDevice = null;
private IDevice mCurrentDevice = null;
private Client mCurrentClient = null;
// status line at the bottom of the app window
@@ -166,7 +166,7 @@ public class UIThread implements IUiSelectionListener {
private ToolItem mTBCauseGc;
private ImageLoader mDdmsImageLoader;
private ImageLoader mDdmuiLibImageLoader;
private ImageLoader mDdmuiLibImageLoader;
private final class FilterStorage implements ILogFilterStorageManager {
@@ -238,7 +238,7 @@ public class UIThread implements IUiSelectionListener {
private Shell mExplorerShell = null;
private EmulatorControlPanel mEmulatorPanel;
private EventLogPanel mEventLogPanel;
private class TableFocusListener implements ITableFocusListener {
@@ -333,7 +333,7 @@ public class UIThread implements IUiSelectionListener {
// create the image loaders for DDMS and DDMUILIB
mDdmsImageLoader = new ImageLoader(this.getClass());
mDdmuiLibImageLoader = new ImageLoader(DevicePanel.class);
shell.setImage(ImageHelper.loadImage(mDdmsImageLoader, mDisplay,
"ddms-icon.png", //$NON-NLS-1$
100, 50, null));
@@ -883,7 +883,7 @@ public class UIThread implements IUiSelectionListener {
p.setTableFocusListener(mTableListener);
}
}
mStatusLine.setText("");
}
@@ -892,7 +892,7 @@ public class UIThread implements IUiSelectionListener {
*/
private void createDevicePanelToolBar(ToolBar toolBar) {
Display display = toolBar.getDisplay();
// add "show thread updates" button
mTBShowThreadUpdates = new ToolItem(toolBar, SWT.CHECK);
mTBShowThreadUpdates.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, display,
@@ -949,7 +949,7 @@ public class UIThread implements IUiSelectionListener {
mDevicePanel.killSelectedClient();
}
});
new ToolItem(toolBar, SWT.SEPARATOR);
// add "cause GC" button
@@ -1130,7 +1130,7 @@ public class UIThread implements IUiSelectionListener {
mClearAction = new ToolItemAction(toolBar, SWT.PUSH);
mClearAction.item.setToolTipText("Clear Log");
mClearAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, mDisplay,
"clear.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
@@ -1239,12 +1239,12 @@ public class UIThread implements IUiSelectionListener {
item = new TabItem(tabFolder, SWT.NONE);
item.setText("Event Log");
item.setToolTipText("Event Log");
// create the composite that will hold the toolbar and the event log panel.
Composite eventLogTopComposite = new Composite(tabFolder, SWT.NONE);
item.setControl(eventLogTopComposite);
eventLogTopComposite.setLayout(new GridLayout(1, false));
// create the toolbar and the actions
ToolBar toolbar = new ToolBar(eventLogTopComposite, SWT.HORIZONTAL);
toolbar.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
@@ -1260,7 +1260,7 @@ public class UIThread implements IUiSelectionListener {
clearAction.item.setImage(ImageHelper.loadImage(mDdmuiLibImageLoader, comp.getDisplay(),
"clear.png", //$NON-NLS-1$
DevicePanel.ICON_WIDTH, DevicePanel.ICON_WIDTH, null));
new ToolItem(toolbar, SWT.SEPARATOR);
ToolItemAction saveAction = new ToolItemAction(toolbar, SWT.PUSH);
@@ -1283,7 +1283,7 @@ public class UIThread implements IUiSelectionListener {
// create the event log panel
mEventLogPanel = new EventLogPanel(mDdmuiLibImageLoader);
// set the external actions
mEventLogPanel.setActions(optionsAction, clearAction, saveAction, loadAction,
importBugAction);
@@ -1450,13 +1450,13 @@ public class UIThread implements IUiSelectionListener {
}
/**
* Sent when a new {@link Device} and {@link Client} are selected.
* Sent when a new {@link IDevice} and {@link Client} are selected.
* @param selectedDevice the selected device. If null, no devices are selected.
* @param selectedClient The selected client. If null, no clients are selected.
*
* @see IUiSelectionListener
*/
public void selectionChanged(Device selectedDevice, Client selectedClient) {
public void selectionChanged(IDevice selectedDevice, Client selectedClient) {
if (mCurrentDevice != selectedDevice) {
mCurrentDevice = selectedDevice;
for (TablePanel panel : mPanels) {

View File

@@ -29,7 +29,7 @@ import java.nio.channels.SocketChannel;
/**
* Helper class to handle requests and connections to adb.
* <p/>{@link DebugBridgeServer} is the public API to connection to adb, while {@link AdbHelper}
* does the low level stuff.
* does the low level stuff.
* <p/>This currently uses spin-wait non-blocking I/O. A Selector would be more efficient,
* but seems like overkill for what we're doing here.
*/
@@ -272,14 +272,14 @@ final class AdbHelper {
try {
adbChan = SocketChannel.open(adbSockAddr);
adbChan.configureBlocking(false);
// if the device is not -1, then we first tell adb we're looking to talk
// to a specific device
setDevice(adbChan, device);
if (write(adbChan, request) == false)
throw new IOException("failed asking for frame buffer");
AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
if (!resp.ioSuccess || !resp.okay) {
Log.w("ddms", "Got timeout or unhappy response from ADB fb req: "
@@ -287,7 +287,7 @@ final class AdbHelper {
adbChan.close();
return null;
}
reply = new byte[16];
if (read(adbChan, reply) == false) {
Log.w("ddms", "got partial reply from ADB fb:");
@@ -297,19 +297,19 @@ final class AdbHelper {
}
ByteBuffer buf = ByteBuffer.wrap(reply);
buf.order(ByteOrder.LITTLE_ENDIAN);
imageParams.bpp = buf.getInt();
imageParams.size = buf.getInt();
imageParams.width = buf.getInt();
imageParams.height = buf.getInt();
Log.d("ddms", "image params: bpp=" + imageParams.bpp + ", size="
+ imageParams.size + ", width=" + imageParams.width
+ ", height=" + imageParams.height);
if (write(adbChan, nudge) == false)
throw new IOException("failed nudging");
reply = new byte[imageParams.size];
if (read(adbChan, reply) == false) {
Log.w("ddms", "got truncated reply from ADB fb data");
@@ -416,34 +416,34 @@ final class AdbHelper {
public static void runLogService(InetSocketAddress adbSockAddr, Device device, String logName,
LogReceiver rcvr) throws IOException {
SocketChannel adbChan = null;
try {
adbChan = SocketChannel.open(adbSockAddr);
adbChan.configureBlocking(false);
// if the device is not -1, then we first tell adb we're looking to talk
// to a specific device
setDevice(adbChan, device);
byte[] request = formAdbRequest("log:" + logName);
if (write(adbChan, request) == false) {
throw new IOException("failed to submit the log command");
}
AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
if (!resp.ioSuccess || !resp.okay) {
throw new IOException("Device rejected log command: " + resp.message);
}
byte[] data = new byte[16384];
ByteBuffer buf = ByteBuffer.wrap(data);
while (true) {
int count;
if (rcvr != null && rcvr.isCancelled()) {
break;
}
count = adbChan.read(buf);
if (count < 0) {
break;
@@ -465,7 +465,7 @@ final class AdbHelper {
}
}
}
/**
* Creates a port forwarding between a local and a remote port.
* @param adbSockAddr the socket address to connect to adb
@@ -473,7 +473,7 @@ final class AdbHelper {
* @param localPort the local port to forward
* @param remotePort the remote port.
* @return <code>true</code> if success.
* @throws IOException
* @throws IOException
*/
public static boolean createForward(InetSocketAddress adbSockAddr, Device device, int localPort,
int remotePort) throws IOException {
@@ -482,15 +482,15 @@ final class AdbHelper {
try {
adbChan = SocketChannel.open(adbSockAddr);
adbChan.configureBlocking(false);
byte[] request = formAdbRequest(String.format(
"host-serial:%1$s:forward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
device.serialNumber, localPort, remotePort));
device.getSerialNumber(), localPort, remotePort));
if (write(adbChan, request) == false) {
throw new IOException("failed to submit the forward command.");
}
AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
if (!resp.ioSuccess || !resp.okay) {
throw new IOException("Device rejected command: " + resp.message);
@@ -500,7 +500,7 @@ final class AdbHelper {
adbChan.close();
}
}
return true;
}
@@ -520,15 +520,15 @@ final class AdbHelper {
try {
adbChan = SocketChannel.open(adbSockAddr);
adbChan.configureBlocking(false);
byte[] request = formAdbRequest(String.format(
"host-serial:%1$s:killforward:tcp:%2$d;tcp:%3$d", //$NON-NLS-1$
device.serialNumber, localPort, remotePort));
device.getSerialNumber(), localPort, remotePort));
if (!write(adbChan, request)) {
throw new IOException("failed to submit the remove forward command.");
}
AdbResponse resp = readAdbResponse(adbChan, false /* readDiagString */);
if (!resp.ioSuccess || !resp.okay) {
throw new IOException("Device rejected command: " + resp.message);
@@ -563,7 +563,7 @@ final class AdbHelper {
}
return result;
}
/**
* Reads from the socket until the array is filled, or no more data is coming (because
* the socket closed or the timeout expired).
@@ -572,7 +572,7 @@ final class AdbHelper {
* mode for timeouts to work
* @param data the buffer to store the read data into.
* @return "true" if all data was read.
* @throws IOException
* @throws IOException
*/
static boolean read(SocketChannel chan, byte[] data) {
try {
@@ -581,7 +581,7 @@ final class AdbHelper {
Log.d("ddms", "readAll: IOException: " + e.getMessage());
return false;
}
return true;
}
@@ -597,7 +597,7 @@ final class AdbHelper {
* @param data the buffer to store the read data into.
* @param length the length to read or -1 to fill the data buffer completely
* @param timeout The timeout value. A timeout of zero means "wait forever".
* @throws IOException
* @throws IOException
*/
static void read(SocketChannel chan, byte[] data, int length, int timeout) throws IOException {
ByteBuffer buf = ByteBuffer.wrap(data, 0, length != -1 ? length : data.length);
@@ -653,7 +653,7 @@ final class AdbHelper {
* @param data the buffer to send.
* @param length the length to write or -1 to send the whole buffer.
* @param timeout The timeout value. A timeout of zero means "wait forever".
* @throws IOException
* @throws IOException
*/
static void write(SocketChannel chan, byte[] data, int length, int timeout)
throws IOException {
@@ -697,7 +697,7 @@ final class AdbHelper {
// if the device is not -1, then we first tell adb we're looking to talk
// to a specific device
if (device != null) {
String msg = "host:transport:" + device.serialNumber; //$NON-NLS-1$
String msg = "host:transport:" + device.getSerialNumber(); //$NON-NLS-1$
byte[] device_query = formAdbRequest(msg);
if (write(adbChan, device_query) == false)

View File

@@ -37,7 +37,7 @@ import java.util.regex.Pattern;
* <p/><b>{@link #init(boolean)} must be called before anything is done.</b>
*/
public final class AndroidDebugBridge {
/*
* Minimum and maximum version of adb supported. This correspond to
* ADB_SERVER_VERSION found in //device/tools/adb/adb.h
@@ -48,7 +48,7 @@ public final class AndroidDebugBridge {
private final static Pattern sAdbVersion = Pattern.compile(
"^.*(\\d+)\\.(\\d+)\\.(\\d+)$"); //$NON-NLS-1$
private final static String ADB = "adb"; //$NON-NLS-1$
private final static String DDMS = "ddms"; //$NON-NLS-1$
@@ -107,7 +107,7 @@ public final class AndroidDebugBridge {
/**
* Classes which implement this interface provide methods that deal
* with {@link Device} addition, deletion, and changes.
* with {@link IDevice} addition, deletion, and changes.
*/
public interface IDeviceChangeListener {
/**
@@ -116,7 +116,7 @@ public final class AndroidDebugBridge {
* This is sent from a non UI thread.
* @param device the new device.
*/
public void deviceConnected(Device device);
public void deviceConnected(IDevice device);
/**
* Sent when the a device is connected to the {@link AndroidDebugBridge}.
@@ -124,7 +124,7 @@ public final class AndroidDebugBridge {
* This is sent from a non UI thread.
* @param device the new device.
*/
public void deviceDisconnected(Device device);
public void deviceDisconnected(IDevice device);
/**
* Sent when a device data changed, or when clients are started/terminated on the device.
@@ -132,10 +132,10 @@ public final class AndroidDebugBridge {
* This is sent from a non UI thread.
* @param device the device that was updated.
* @param changeMask the mask describing what changed. It can contain any of the following
* values: {@link Device#CHANGE_BUILD_INFO}, {@link Device#CHANGE_STATE},
* {@link Device#CHANGE_CLIENT_LIST}
* values: {@link IDevice#CHANGE_BUILD_INFO}, {@link IDevice#CHANGE_STATE},
* {@link IDevice#CHANGE_CLIENT_LIST}
*/
public void deviceChanged(Device device, int changeMask);
public void deviceChanged(IDevice device, int changeMask);
}
/**
@@ -194,6 +194,7 @@ public final class AndroidDebugBridge {
HandleThread.register(monitorThread);
HandleHeap.register(monitorThread);
HandleWait.register(monitorThread);
HandleProfiling.register(monitorThread);
}
/**
@@ -211,15 +212,15 @@ public final class AndroidDebugBridge {
monitorThread.quit();
}
}
/**
* Returns whether the ddmlib is setup to support monitoring and interacting with
* {@link Client}s running on the {@link Device}s.
* {@link Client}s running on the {@link IDevice}s.
*/
static boolean getClientSupport() {
return sClientSupport;
}
/**
* Creates a {@link AndroidDebugBridge} that is not linked to any particular executable.
* <p/>This bridge will expect adb to be running. It will not be able to start/stop/restart
@@ -324,6 +325,7 @@ public final class AndroidDebugBridge {
/**
* Disconnects the current debug bridge, and destroy the object.
* <p/>This also stops the current adb host server.
* <p/>
* A new object will have to be created with {@link #createBridge(String, boolean)}.
*/
@@ -389,7 +391,7 @@ public final class AndroidDebugBridge {
}
/**
* Adds the listener to the collection of listeners who will be notified when a {@link Device}
* Adds the listener to the collection of listeners who will be notified when a {@link IDevice}
* is connected, disconnected, or when its properties or its {@link Client} list changed,
* by sending it one of the messages defined in the {@link IDeviceChangeListener} interface.
* @param listener The listener which should be notified.
@@ -404,7 +406,7 @@ public final class AndroidDebugBridge {
/**
* Removes the listener from the collection of listeners who will be notified when a
* {@link Device} is connected, disconnected, or when its properties or its {@link Client}
* {@link IDevice} is connected, disconnected, or when its properties or its {@link Client}
* list changed.
* @param listener The listener which should no longer be notified.
*/
@@ -444,30 +446,30 @@ public final class AndroidDebugBridge {
* Returns the devices.
* @see #hasInitialDeviceList()
*/
public Device[] getDevices() {
public IDevice[] getDevices() {
synchronized (sLock) {
if (mDeviceMonitor != null) {
return mDeviceMonitor.getDevices();
}
}
return new Device[0];
return new IDevice[0];
}
/**
* Returns whether the bridge has acquired the initial list from adb after being created.
* <p/>Calling {@link #getDevices()} right after {@link #createBridge(String, boolean)} will
* generally result in an empty list. This is due to the internal asynchronous communication
* mechanism with <code>adb</code> that does not guarantee that the {@link Device} list has been
* mechanism with <code>adb</code> that does not guarantee that the {@link IDevice} list has been
* built before the call to {@link #getDevices()}.
* <p/>The recommended way to get the list of {@link Device} objects is to create a
* <p/>The recommended way to get the list of {@link IDevice} objects is to create a
* {@link IDeviceChangeListener} object.
*/
public boolean hasInitialDeviceList() {
if (mDeviceMonitor != null) {
return mDeviceMonitor.hasInitialDeviceList();
}
return false;
}
@@ -514,7 +516,7 @@ public final class AndroidDebugBridge {
}
return -1;
}
/**
* Creates a new bridge.
* @param osLocation the location of the command line tool
@@ -528,7 +530,7 @@ public final class AndroidDebugBridge {
checkAdbVersion();
}
/**
* Creates a new bridge not linked to any particular adb executable.
*/
@@ -590,7 +592,7 @@ public final class AndroidDebugBridge {
Log.logAndDisplay(LogLevel.ERROR, ADB,
"Failed to parse the output of 'adb version'"); //$NON-NLS-1$
}
} catch (IOException e) {
Log.logAndDisplay(LogLevel.ERROR, ADB,
"Failed to get the adb version: " + e.getMessage()); //$NON-NLS-1$
@@ -608,7 +610,7 @@ public final class AndroidDebugBridge {
* <p/>
* Returns true when a version number has been found so that we can stop scanning,
* whether the version number is in the acceptable range or not.
*
*
* @param line The line to scan.
* @return True if a version number was found (whether it is acceptable or not).
*/
@@ -665,7 +667,7 @@ public final class AndroidDebugBridge {
}
/**
* Kills the debug bridge.
* Kills the debug bridge, and the adb host server.
* @return true if success
*/
boolean stop() {
@@ -717,19 +719,19 @@ public final class AndroidDebugBridge {
}
/**
* Notify the listener of a new {@link Device}.
* Notify the listener of a new {@link IDevice}.
* <p/>
* The notification of the listeners is done in a synchronized block. It is important to
* expect the listeners to potentially access various methods of {@link Device} as well as
* expect the listeners to potentially access various methods of {@link IDevice} as well as
* {@link #getDevices()} which use internal locks.
* <p/>
* For this reason, any call to this method from a method of {@link DeviceMonitor},
* {@link Device} which is also inside a synchronized block, should first synchronize on
* {@link IDevice} which is also inside a synchronized block, should first synchronize on
* the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
* @param device the new <code>Device</code>.
* @param device the new <code>IDevice</code>.
* @see #getLock()
*/
void deviceConnected(Device device) {
void deviceConnected(IDevice device) {
// because the listeners could remove themselves from the list while processing
// their event callback, we make a copy of the list and iterate on it instead of
// the main list.
@@ -739,7 +741,7 @@ public final class AndroidDebugBridge {
listenersCopy = sDeviceListeners.toArray(
new IDeviceChangeListener[sDeviceListeners.size()]);
}
// Notify the listeners
for (IDeviceChangeListener listener : listenersCopy) {
// we attempt to catch any exception so that a bad listener doesn't kill our
@@ -753,19 +755,19 @@ public final class AndroidDebugBridge {
}
/**
* Notify the listener of a disconnected {@link Device}.
* Notify the listener of a disconnected {@link IDevice}.
* <p/>
* The notification of the listeners is done in a synchronized block. It is important to
* expect the listeners to potentially access various methods of {@link Device} as well as
* expect the listeners to potentially access various methods of {@link IDevice} as well as
* {@link #getDevices()} which use internal locks.
* <p/>
* For this reason, any call to this method from a method of {@link DeviceMonitor},
* {@link Device} which is also inside a synchronized block, should first synchronize on
* {@link IDevice} which is also inside a synchronized block, should first synchronize on
* the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
* @param device the disconnected <code>Device</code>.
* @param device the disconnected <code>IDevice</code>.
* @see #getLock()
*/
void deviceDisconnected(Device device) {
void deviceDisconnected(IDevice device) {
// because the listeners could remove themselves from the list while processing
// their event callback, we make a copy of the list and iterate on it instead of
// the main list.
@@ -775,7 +777,7 @@ public final class AndroidDebugBridge {
listenersCopy = sDeviceListeners.toArray(
new IDeviceChangeListener[sDeviceListeners.size()]);
}
// Notify the listeners
for (IDeviceChangeListener listener : listenersCopy) {
// we attempt to catch any exception so that a bad listener doesn't kill our
@@ -789,19 +791,19 @@ public final class AndroidDebugBridge {
}
/**
* Notify the listener of a modified {@link Device}.
* Notify the listener of a modified {@link IDevice}.
* <p/>
* The notification of the listeners is done in a synchronized block. It is important to
* expect the listeners to potentially access various methods of {@link Device} as well as
* expect the listeners to potentially access various methods of {@link IDevice} as well as
* {@link #getDevices()} which use internal locks.
* <p/>
* For this reason, any call to this method from a method of {@link DeviceMonitor},
* {@link Device} which is also inside a synchronized block, should first synchronize on
* {@link IDevice} which is also inside a synchronized block, should first synchronize on
* the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
* @param device the modified <code>Device</code>.
* @param device the modified <code>IDevice</code>.
* @see #getLock()
*/
void deviceChanged(Device device, int changeMask) {
void deviceChanged(IDevice device, int changeMask) {
// because the listeners could remove themselves from the list while processing
// their event callback, we make a copy of the list and iterate on it instead of
// the main list.
@@ -811,7 +813,7 @@ public final class AndroidDebugBridge {
listenersCopy = sDeviceListeners.toArray(
new IDeviceChangeListener[sDeviceListeners.size()]);
}
// Notify the listeners
for (IDeviceChangeListener listener : listenersCopy) {
// we attempt to catch any exception so that a bad listener doesn't kill our
@@ -828,11 +830,11 @@ public final class AndroidDebugBridge {
* Notify the listener of a modified {@link Client}.
* <p/>
* The notification of the listeners is done in a synchronized block. It is important to
* expect the listeners to potentially access various methods of {@link Device} as well as
* expect the listeners to potentially access various methods of {@link IDevice} as well as
* {@link #getDevices()} which use internal locks.
* <p/>
* For this reason, any call to this method from a method of {@link DeviceMonitor},
* {@link Device} which is also inside a synchronized block, should first synchronize on
* {@link IDevice} which is also inside a synchronized block, should first synchronize on
* the {@link AndroidDebugBridge} lock. Access to this lock is done through {@link #getLock()}.
* @param device the modified <code>Client</code>.
* @param changeMask the mask indicating what changed in the <code>Client</code>
@@ -847,7 +849,7 @@ public final class AndroidDebugBridge {
synchronized (sLock) {
listenersCopy = sClientListeners.toArray(
new IClientChangeListener[sClientListeners.size()]);
}
// Notify the listeners
@@ -961,7 +963,7 @@ public final class AndroidDebugBridge {
* @param errorOutput The array to store the stderr output. cannot be null.
* @param stdOutput The array to store the stdout output. cannot be null.
* @param displayStdOut If true this will display stdout as well
* @param waitforReaders if true, this will wait for the reader threads.
* @param waitforReaders if true, this will wait for the reader threads.
* @return the process return code.
* @throws InterruptedException
*/

View File

@@ -199,7 +199,7 @@ abstract class ChunkHandler {
protected static Client checkDebuggerPortForAppName(Client client, String appName) {
IDebugPortProvider provider = DebugPortManager.getProvider();
if (provider != null) {
Device device = client.getDevice();
Device device = client.getDeviceImpl();
int newPort = provider.getPort(device, appName);
if (newPort != IDebugPortProvider.NO_STATIC_PORT &&

View File

@@ -133,7 +133,7 @@ public class Client {
mConnState = ST_INIT;
mClientData = new ClientData(pid);
mThreadUpdateEnabled = DdmPreferences.getInitialThreadUpdate();
mHeapUpdateEnabled = DdmPreferences.getInitialHeapUpdate();
}
@@ -147,9 +147,15 @@ public class Client {
}
/**
* Returns the {@link Device} on which this Client is running.
* Returns the {@link IDevice} on which this Client is running.
*/
public Device getDevice() {
public IDevice getDevice() {
return mDevice;
}
/** Returns the {@link Device} on which this Client is running.
*/
Device getDeviceImpl() {
return mDevice;
}
@@ -238,7 +244,7 @@ public class Client {
update(CHANGE_THREAD_MODE);
}
/**
* Returns whether the thread update is enabled.
*/
@@ -268,7 +274,7 @@ public class Client {
public void requestThreadStackTrace(int threadId) {
HandleThread.requestThreadStackCallRefresh(this, threadId);
}
/**
* Enables or disables the heap update.
* <p/>If <code>true</code>, any GC will cause the client to send its heap information.
@@ -320,7 +326,7 @@ public class Client {
return false;
}
/**
* Enables or disables the Allocation tracker for this client.
* <p/>If enabled, the VM will start tracking allocation informations. A call to
@@ -336,7 +342,7 @@ public class Client {
Log.e("ddmlib", e);
}
}
/**
* Sends a request to the VM to send the enable status of the allocation tracking.
* This is asynchronous.
@@ -350,9 +356,9 @@ public class Client {
HandleHeap.sendREAQ(this);
} catch (IOException e) {
Log.e("ddmlib", e);
}
}
}
/**
* Sends a request to the VM to send the information about all the allocations that have
* happened since the call to {@link #enableAllocationTracker(boolean)} with <var>enable</var>
@@ -457,7 +463,7 @@ public class Client {
}
mConnState = ST_AWAIT_SHAKE;
return true;
}
@@ -638,7 +644,7 @@ public class Client {
*/
Log.e("ddms", "Receiving data in state = " + mConnState);
}
return null;
}
@@ -753,7 +759,7 @@ public class Client {
mDevice.removeClient(this, notify);
}
/**
* Returns whether this {@link Client} has a valid connection to the application VM.
*/

View File

@@ -19,12 +19,12 @@ package com.android.ddmlib;
import com.android.ddmlib.Device;
/**
* Centralized point to provide a {@link IDebugPortProvider} to ddmlib.
*
* Centralized point to provide a {@link IDebugPortProvider} to ddmlib.
*
* <p/>When {@link Client} objects are created, they start listening for debuggers on a specific
* port. The default behavior is to start with {@link DdmPreferences#getDebugPortBase()} and
* port. The default behavior is to start with {@link DdmPreferences#getDebugPortBase()} and
* increment this value for each new <code>Client</code>.
*
*
* <p/>This {@link DebugPortManager} allows applications using ddmlib to provide a custom
* port provider on a per-<code>Client</code> basis, depending on the device/emulator they are
* running on, and/or their names.
@@ -48,7 +48,7 @@ public class DebugPortManager {
* @return The non-random debugger port or {@link #NO_STATIC_PORT} if the {@link Client}
* should use the automatic debugger port provider.
*/
public int getPort(Device device, String appName);
public int getPort(IDevice device, String appName);
}
private static IDebugPortProvider sProvider = null;
@@ -63,7 +63,7 @@ public class DebugPortManager {
}
/**
* Returns the
* Returns the
* @return
*/
static IDebugPortProvider getProvider() {

View File

@@ -16,9 +16,10 @@
package com.android.ddmlib;
import com.android.ddmlib.Client;
import com.android.ddmlib.SyncService.SyncResult;
import com.android.ddmlib.log.LogReceiver;
import java.io.File;
import java.io.IOException;
import java.nio.channels.SocketChannel;
import java.util.ArrayList;
@@ -26,54 +27,26 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* A Device. It can be a physical device or an emulator.
*
* TODO: make this class package-protected, and shift all callers to use IDevice
*/
public final class Device implements IDevice {
/**
* The state of a device.
*/
public static enum DeviceState {
BOOTLOADER("bootloader"), //$NON-NLS-1$
OFFLINE("offline"), //$NON-NLS-1$
ONLINE("device"); //$NON-NLS-1$
private String mState;
DeviceState(String state) {
mState = state;
}
/**
* Returns a {@link DeviceState} from the string returned by <code>adb devices</code>.
* @param state the device state.
* @return a {@link DeviceState} object or <code>null</code> if the state is unknown.
*/
public static DeviceState getState(String state) {
for (DeviceState deviceState : values()) {
if (deviceState.mState.equals(state)) {
return deviceState;
}
}
return null;
}
}
final class Device implements IDevice {
/** Emulator Serial Number regexp. */
final static String RE_EMULATOR_SN = "emulator-(\\d+)"; //$NON-NLS-1$
/** Serial number of the device */
String serialNumber = null;
private String mSerialNumber = null;
/** Name of the AVD */
String mAvdName = null;
private String mAvdName = null;
/** State of the device. */
DeviceState state = null;
private DeviceState mState = null;
/** Device properties. */
private final Map<String, String> mProperties = new HashMap<String, String>();
@@ -81,32 +54,92 @@ public final class Device implements IDevice {
private final ArrayList<Client> mClients = new ArrayList<Client>();
private DeviceMonitor mMonitor;
private static final String LOG_TAG = "Device";
/**
* Socket for the connection monitoring client connection/disconnection.
*/
private SocketChannel mSocketChannel;
/**
* Output receiver for "pm install package.apk" command line.
*/
private static final class InstallReceiver extends MultiLineReceiver {
private static final String SUCCESS_OUTPUT = "Success"; //$NON-NLS-1$
private static final Pattern FAILURE_PATTERN = Pattern.compile("Failure\\s+\\[(.*)\\]"); //$NON-NLS-1$
private String mErrorMessage = null;
public InstallReceiver() {
}
@Override
public void processNewLines(String[] lines) {
for (String line : lines) {
if (line.length() > 0) {
if (line.startsWith(SUCCESS_OUTPUT)) {
mErrorMessage = null;
} else {
Matcher m = FAILURE_PATTERN.matcher(line);
if (m.matches()) {
mErrorMessage = m.group(1);
}
}
}
}
}
public boolean isCancelled() {
return false;
}
public String getErrorMessage() {
return mErrorMessage;
}
}
/*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getSerialNumber()
*/
public String getSerialNumber() {
return serialNumber;
return mSerialNumber;
}
/** {@inheritDoc} */
public String getAvdName() {
return mAvdName;
}
/**
* Sets the name of the AVD
*/
void setAvdName(String avdName) {
if (isEmulator() == false) {
throw new IllegalArgumentException(
"Cannot set the AVD name of the device is not an emulator");
}
mAvdName = avdName;
}
/*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getState()
*/
public DeviceState getState() {
return state;
return mState;
}
/**
* Changes the state of the device.
*/
void setState(DeviceState state) {
mState = state;
}
/*
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getProperties()
@@ -134,7 +167,7 @@ public final class Device implements IDevice {
@Override
public String toString() {
return serialNumber;
return mSerialNumber;
}
/*
@@ -142,7 +175,7 @@ public final class Device implements IDevice {
* @see com.android.ddmlib.IDevice#isOnline()
*/
public boolean isOnline() {
return state == DeviceState.ONLINE;
return mState == DeviceState.ONLINE;
}
/*
@@ -150,7 +183,7 @@ public final class Device implements IDevice {
* @see com.android.ddmlib.IDevice#isEmulator()
*/
public boolean isEmulator() {
return serialNumber.matches(RE_EMULATOR_SN);
return mSerialNumber.matches(RE_EMULATOR_SN);
}
/*
@@ -158,7 +191,7 @@ public final class Device implements IDevice {
* @see com.android.ddmlib.IDevice#isOffline()
*/
public boolean isOffline() {
return state == DeviceState.OFFLINE;
return mState == DeviceState.OFFLINE;
}
/*
@@ -166,7 +199,7 @@ public final class Device implements IDevice {
* @see com.android.ddmlib.IDevice#isBootLoader()
*/
public boolean isBootLoader() {
return state == DeviceState.BOOTLOADER;
return mState == DeviceState.BOOTLOADER;
}
/*
@@ -208,7 +241,7 @@ public final class Device implements IDevice {
* (non-Javadoc)
* @see com.android.ddmlib.IDevice#getSyncService()
*/
public SyncService getSyncService() {
public SyncService getSyncService() throws IOException {
SyncService syncService = new SyncService(AndroidDebugBridge.sSocketAddr, this);
if (syncService.openSync()) {
return syncService;
@@ -305,8 +338,10 @@ public final class Device implements IDevice {
}
Device(DeviceMonitor monitor) {
Device(DeviceMonitor monitor, String serialNumber, DeviceState deviceState) {
mMonitor = monitor;
mSerialNumber = serialNumber;
mState = deviceState;
}
DeviceMonitor getMonitor() {
@@ -382,4 +417,94 @@ public final class Device implements IDevice {
void addProperty(String label, String value) {
mProperties.put(label, value);
}
/**
* {@inheritDoc}
*/
public String installPackage(String packageFilePath, boolean reinstall)
throws IOException {
String remoteFilePath = syncPackageToDevice(packageFilePath);
String result = installRemotePackage(remoteFilePath, reinstall);
removeRemotePackage(remoteFilePath);
return result;
}
/**
* {@inheritDoc}
*/
public String syncPackageToDevice(String localFilePath)
throws IOException {
try {
String packageFileName = getFileName(localFilePath);
String remoteFilePath = String.format("/data/local/tmp/%1$s", packageFileName); //$NON-NLS-1$
Log.i(packageFileName, String.format("Uploading %1$s onto device '%2$s'",
packageFileName, getSerialNumber()));
SyncService sync = getSyncService();
if (sync != null) {
String message = String.format("Uploading file onto device '%1$s'",
getSerialNumber());
Log.i(LOG_TAG, message);
SyncResult result = sync.pushFile(localFilePath, remoteFilePath,
SyncService.getNullProgressMonitor());
if (result.getCode() != SyncService.RESULT_OK) {
throw new IOException(String.format("Unable to upload file: %1$s",
result.getMessage()));
}
} else {
throw new IOException("Unable to open sync connection!");
}
return remoteFilePath;
} catch (IOException e) {
Log.e(LOG_TAG, String.format("Unable to open sync connection! reason: %1$s",
e.getMessage()));
throw e;
}
}
/**
* Helper method to retrieve the file name given a local file path
* @param filePath full directory path to file
* @return {@link String} file name
*/
private String getFileName(String filePath) {
return new File(filePath).getName();
}
/**
* {@inheritDoc}
*/
public String installRemotePackage(String remoteFilePath, boolean reinstall)
throws IOException {
InstallReceiver receiver = new InstallReceiver();
String cmd = String.format(reinstall ? "pm install -r \"%1$s\"" : "pm install \"%1$s\"",
remoteFilePath);
executeShellCommand(cmd, receiver);
return receiver.getErrorMessage();
}
/**
* {@inheritDoc}
*/
public void removeRemotePackage(String remoteFilePath) throws IOException {
// now we delete the app we sync'ed
try {
executeShellCommand("rm " + remoteFilePath, new NullOutputReceiver());
} catch (IOException e) {
Log.e(LOG_TAG, String.format("Failed to delete temporary package: %1$s",
e.getMessage()));
throw e;
}
}
/**
* {@inheritDoc}
*/
public String uninstallPackage(String packageName) throws IOException {
InstallReceiver receiver = new InstallReceiver();
executeShellCommand("pm uninstall " + packageName, receiver);
return receiver.getErrorMessage();
}
}

View File

@@ -18,7 +18,7 @@ package com.android.ddmlib;
import com.android.ddmlib.AdbHelper.AdbResponse;
import com.android.ddmlib.DebugPortManager.IDebugPortProvider;
import com.android.ddmlib.Device.DeviceState;
import com.android.ddmlib.IDevice.DeviceState;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
@@ -112,11 +112,11 @@ final class DeviceMonitor {
boolean isMonitoring() {
return mMonitoring;
}
int getConnectionAttemptCount() {
return mConnectionAttempt;
}
int getRestartAttemptCount() {
return mRestartAttemptCount;
}
@@ -129,7 +129,7 @@ final class DeviceMonitor {
return mDevices.toArray(new Device[mDevices.size()]);
}
}
boolean hasInitialDeviceList() {
return mInitialDeviceListDone;
}
@@ -184,11 +184,11 @@ final class DeviceMonitor {
if (mMonitoring) {
// read the length of the incoming message
int length = readLength(mMainAdbConnection, mLengthBuffer);
if (length >= 0) {
// read the incoming message
processIncomingDeviceData(length);
// flag the fact that we have build the list at least once.
mInitialDeviceListDone = true;
}
@@ -278,20 +278,19 @@ final class DeviceMonitor {
*/
private void processIncomingDeviceData(int length) throws IOException {
ArrayList<Device> list = new ArrayList<Device>();
if (length > 0) {
byte[] buffer = new byte[length];
String result = read(mMainAdbConnection, buffer);
String[] devices = result.split("\n"); // $NON-NLS-1$
for (String d : devices) {
String[] param = d.split("\t"); // $NON-NLS-1$
if (param.length == 2) {
// new adb uses only serial numbers to identify devices
Device device = new Device(this);
device.serialNumber = param[0];
device.state = DeviceState.getState(param[1]);
Device device = new Device(this, param[0] /*serialnumber*/,
DeviceState.getState(param[1]));
//add the device to the list
list.add(device);
@@ -319,24 +318,24 @@ final class DeviceMonitor {
// * if we do not find it, we remove it from the current list.
// Once this is done, the new list contains device we aren't monitoring yet, so we
// add them to the list, and start monitoring them.
for (int d = 0 ; d < mDevices.size() ;) {
Device device = mDevices.get(d);
// look for a similar device in the new list.
int count = newList.size();
boolean foundMatch = false;
for (int dd = 0 ; dd < count ; dd++) {
Device newDevice = newList.get(dd);
// see if it matches in id and serial number.
if (newDevice.serialNumber.equals(device.serialNumber)) {
if (newDevice.getSerialNumber().equals(device.getSerialNumber())) {
foundMatch = true;
// update the state if needed.
if (device.state != newDevice.state) {
device.state = newDevice.state;
if (device.getState() != newDevice.getState()) {
device.setState(newDevice.getState());
device.update(Device.CHANGE_STATE);
// if the device just got ready/online, we need to start
// monitoring it.
if (device.isOnline()) {
@@ -344,7 +343,7 @@ final class DeviceMonitor {
if (startMonitoringDevice(device) == false) {
Log.e("DeviceMonitor",
"Failed to start monitoring "
+ device.serialNumber);
+ device.getSerialNumber());
}
}
@@ -353,13 +352,13 @@ final class DeviceMonitor {
}
}
}
// remove the new device from the list since it's been used
newList.remove(dd);
break;
}
}
if (foundMatch == false) {
// the device is gone, we need to remove it, and keep current index
// to process the next one.
@@ -370,21 +369,21 @@ final class DeviceMonitor {
d++;
}
}
// at this point we should still have some new devices in newList, so we
// process them.
for (Device newDevice : newList) {
// add them to the list
mDevices.add(newDevice);
mServer.deviceConnected(newDevice);
// start monitoring them.
if (AndroidDebugBridge.getClientSupport() == true) {
if (newDevice.isOnline()) {
startMonitoringDevice(newDevice);
}
}
// look for their build info.
if (newDevice.isOnline()) {
queryNewDeviceForInfo(newDevice);
@@ -398,7 +397,7 @@ final class DeviceMonitor {
private void removeDevice(Device device) {
device.clearClientList();
mDevices.remove(device);
SocketChannel channel = device.getClientMonitoringSocket();
if (channel != null) {
try {
@@ -419,12 +418,12 @@ final class DeviceMonitor {
// first get the list of properties.
device.executeShellCommand(GetPropReceiver.GETPROP_COMMAND,
new GetPropReceiver(device));
// now get the emulator Virtual Device name (if applicable).
if (device.isEmulator()) {
EmulatorConsole console = EmulatorConsole.getConsole(device);
if (console != null) {
device.mAvdName = console.getAvdName();
device.setAvdName(console.getAvdName());
}
}
} catch (IOException e) {
@@ -510,7 +509,7 @@ final class DeviceMonitor {
MonitorThread monitorThread = MonitorThread.getInstance();
for (Client client : clients) {
Device device = client.getDevice();
Device device = client.getDeviceImpl();
int pid = client.getClientData().getPid();
monitorThread.dropClient(client, false /* notify */);
@@ -623,10 +622,10 @@ final class DeviceMonitor {
if (length > 0) {
byte[] buffer = new byte[length];
String result = read(monitorSocket, buffer);
// split each line in its own list and create an array of integer pid
String[] pids = result.split("\n"); //$NON-NLS-1$
for (String pid : pids) {
try {
pidList.add(Integer.valueOf(pid));
@@ -662,7 +661,7 @@ final class DeviceMonitor {
for (int c = 0 ; c < clients.size() ;) {
Client client = clients.get(c);
int pid = client.getClientData().getPid();
// look for a matching pid
Integer match = null;
for (Integer matchingPid : pidList) {
@@ -671,7 +670,7 @@ final class DeviceMonitor {
break;
}
}
if (match != null) {
pidList.remove(match);
c++; // move on to the next client.
@@ -705,7 +704,7 @@ final class DeviceMonitor {
* @return
*/
private void openClient(Device device, int pid, int port, MonitorThread monitorThread) {
SocketChannel clientSocket;
try {
clientSocket = AdbHelper.createPassThroughConnection(
@@ -721,7 +720,7 @@ final class DeviceMonitor {
"Failed to connect to client '" + pid + "': " + ioe.getMessage());
return ;
}
createClient(device, pid, clientSocket, port, monitorThread);
}
@@ -748,12 +747,13 @@ final class DeviceMonitor {
if (AndroidDebugBridge.getClientSupport()) {
client.listenForDebugger(debuggerPort);
}
client.requestAllocationStatus();
} catch (IOException ioe) {
client.getClientData().setDebuggerConnectionStatus(ClientData.DEBUGGER_ERROR);
Log.e("ddms", "Can't bind to local " + debuggerPort + " for debugger");
// oh well
}
client.requestAllocationStatus();
} else {
Log.e("ddms", "Handshake with " + client + " failed!");
/*
@@ -813,7 +813,7 @@ final class DeviceMonitor {
}
}
}
/**
* Reads the length of the next message from a socket.
* @param socket The {@link SocketChannel} to read from.

View File

@@ -41,7 +41,7 @@ import java.util.regex.Pattern;
* code removes <code>\r</code> and waits for <code>\n</code>.
* <p/>However this means you <i>may</i> receive <code>\r\n</code> when reading from the console.
* <p/>
* <b>This API will change in the near future.</b>
* <b>This API will change in the near future.</b>
*/
public final class EmulatorConsole {
@@ -65,7 +65,7 @@ public final class EmulatorConsole {
private final static String COMMAND_NETWORK_STATUS = "network status\r\n"; //$NON-NLS-1$
private final static String COMMAND_NETWORK_SPEED = "network speed %1$s\r\n"; //$NON-NLS-1$
private final static String COMMAND_NETWORK_LATENCY = "network delay %1$s\r\n"; //$NON-NLS-1$
private final static String COMMAND_GPS =
private final static String COMMAND_GPS =
"geo nmea $GPGGA,%1$02d%2$02d%3$02d.%4$03d," + //$NON-NLS-1$
"%5$03d%6$09.6f,%7$c,%8$03d%9$09.6f,%10$c," + //$NON-NLS-1$
"1,10,0.0,0.0,0,0.0,0,0.0,0000\r\n"; //$NON-NLS-1$
@@ -202,9 +202,9 @@ public final class EmulatorConsole {
* @param d The device that the console links to.
* @return an <code>EmulatorConsole</code> object or <code>null</code> if the connection failed.
*/
public static synchronized EmulatorConsole getConsole(Device d) {
public static synchronized EmulatorConsole getConsole(IDevice d) {
// we need to make sure that the device is an emulator
Matcher m = sEmulatorRegexp.matcher(d.serialNumber);
Matcher m = sEmulatorRegexp.matcher(d.getSerialNumber());
if (m.matches()) {
// get the port number. This is the console port.
int port;
@@ -308,7 +308,7 @@ public final class EmulatorConsole {
RemoveConsole(mPort);
}
}
public synchronized String getAvdName() {
if (sendCommand(COMMAND_AVD_NAME)) {
String[] result = readLines();
@@ -323,7 +323,7 @@ public final class EmulatorConsole {
}
}
}
return null;
}
@@ -517,18 +517,18 @@ public final class EmulatorConsole {
String command = String.format(COMMAND_NETWORK_LATENCY, NETWORK_LATENCIES[selectionIndex]);
return processCommand(command);
}
public synchronized String sendLocation(double longitude, double latitude, double elevation) {
Calendar c = Calendar.getInstance();
double absLong = Math.abs(longitude);
int longDegree = (int)Math.floor(absLong);
char longDirection = 'E';
if (longitude < 0) {
longDirection = 'W';
}
double longMinute = (absLong - Math.floor(absLong)) * 60;
double absLat = Math.abs(latitude);
@@ -537,15 +537,15 @@ public final class EmulatorConsole {
if (latitude < 0) {
latDirection = 'S';
}
double latMinute = (absLat - Math.floor(absLat)) * 60;
String command = String.format(COMMAND_GPS,
c.get(Calendar.HOUR_OF_DAY), c.get(Calendar.MINUTE),
c.get(Calendar.SECOND), c.get(Calendar.MILLISECOND),
latDegree, latMinute, latDirection,
longDegree, longMinute, longDirection);
return processCommand(command);
}
@@ -617,7 +617,7 @@ public final class EmulatorConsole {
ByteBuffer buf = ByteBuffer.wrap(mBuffer, 0, mBuffer.length);
int numWaits = 0;
boolean stop = false;
while (buf.position() != buf.limit() && stop == false) {
int count;

View File

@@ -32,6 +32,7 @@ final class HandleHeap extends ChunkHandler {
public static final int CHUNK_HPEN = type("HPEN");
public static final int CHUNK_HPSG = type("HPSG");
public static final int CHUNK_HPGC = type("HPGC");
public static final int CHUNK_HPDU = type("HPDU");
public static final int CHUNK_REAE = type("REAE");
public static final int CHUNK_REAQ = type("REAQ");
public static final int CHUNK_REAL = type("REAL");
@@ -98,6 +99,8 @@ final class HandleHeap extends ChunkHandler {
client.update(Client.CHANGE_HEAP_DATA);
} else if (type == CHUNK_HPSG) {
handleHPSG(client, data);
} else if (type == CHUNK_HPDU) {
handleHPDU(client, data);
} else if (type == CHUNK_REAQ) {
handleREAQ(client, data);
client.update(Client.CHANGE_HEAP_ALLOCATION_STATUS);
@@ -220,6 +223,44 @@ final class HandleHeap extends ChunkHandler {
client.sendAndConsume(packet, mInst);
}
/**
* Sends an HPDU request to the client.
*
* We will get an HPDU response when the heap dump has completed. On
* failure we get a generic failure response.
*
* @param fileName name of output file (on device)
*/
public static void sendHPDU(Client client, String fileName)
throws IOException {
ByteBuffer rawBuf = allocBuffer(4 + fileName.length() * 2);
JdwpPacket packet = new JdwpPacket(rawBuf);
ByteBuffer buf = getChunkDataBuf(rawBuf);
buf.putInt(fileName.length());
putString(buf, fileName);
finishChunkPacket(packet, CHUNK_HPDU, buf.position());
Log.d("ddm-heap", "Sending " + name(CHUNK_HPDU) + " '" + fileName +"'");
client.sendAndConsume(packet, mInst);
}
/*
* Handle notification of completion of a HeaP DUmp.
*/
private void handleHPDU(Client client, ByteBuffer data) {
byte result;
result = data.get();
if (result == 0) {
Log.i("ddm-heap", "Heap dump request has finished");
// TODO: stuff
} else {
Log.w("ddm-heap", "Heap dump request failed (check device log)");
}
}
/**
* Sends a REAE (REcent Allocation Enable) request to the client.
*/

View File

@@ -20,11 +20,12 @@ import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Handle the "hello" chunk (HELO).
* Handle the "hello" chunk (HELO) and feature discovery.
*/
final class HandleHello extends ChunkHandler {
public static final int CHUNK_HELO = ChunkHandler.type("HELO");
public static final int CHUNK_FEAT = ChunkHandler.type("FEAT");
private static final HandleHello mInst = new HandleHello();
@@ -65,6 +66,8 @@ final class HandleHello extends ChunkHandler {
if (type == CHUNK_HELO) {
assert isReply;
handleHELO(client, data);
} else if (type == CHUNK_FEAT) {
handleFEAT(client, data);
} else {
handleUnknownChunk(client, type, data, isReply, msgId);
}
@@ -126,5 +129,37 @@ final class HandleHello extends ChunkHandler {
+ " ID=0x" + Integer.toHexString(packet.getId()));
client.sendAndConsume(packet, mInst);
}
/**
* Handle a reply to our FEAT request.
*/
private static void handleFEAT(Client client, ByteBuffer data) {
int featureCount;
int i;
featureCount = data.getInt();
for (i = 0; i < featureCount; i++) {
int len = data.getInt();
String feature = getString(data, len);
Log.d("ddm-hello", "Feature: " + feature);
}
}
/**
* Send a FEAT request to the client.
*/
public static void sendFEAT(Client client) throws IOException {
ByteBuffer rawBuf = allocBuffer(0);
JdwpPacket packet = new JdwpPacket(rawBuf);
ByteBuffer buf = getChunkDataBuf(rawBuf);
// no data
finishChunkPacket(packet, CHUNK_FEAT, buf.position());
Log.d("ddm-heap", "Sending " + name(CHUNK_FEAT));
client.sendAndConsume(packet, mInst);
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2009 The Android Open Source Project
*
* 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 com.android.ddmlib;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Handle heap status updates.
*/
final class HandleProfiling extends ChunkHandler {
public static final int CHUNK_MPRS = type("MPRS");
public static final int CHUNK_MPRE = type("MPRE");
public static final int CHUNK_MPRQ = type("MPRQ");
private static final HandleProfiling mInst = new HandleProfiling();
private HandleProfiling() {}
/**
* Register for the packets we expect to get from the client.
*/
public static void register(MonitorThread mt) {
mt.registerChunkHandler(CHUNK_MPRE, mInst);
mt.registerChunkHandler(CHUNK_MPRQ, mInst);
}
/**
* Client is ready.
*/
@Override
public void clientReady(Client client) throws IOException {}
/**
* Client went away.
*/
@Override
public void clientDisconnected(Client client) {}
/**
* Chunk handler entry point.
*/
@Override
public void handleChunk(Client client, int type, ByteBuffer data,
boolean isReply, int msgId) {
Log.d("ddm-prof", "handling " + ChunkHandler.name(type));
if (type == CHUNK_MPRE) {
handleMPRE(client, data);
} else if (type == CHUNK_MPRQ) {
handleMPRQ(client, data);
} else {
handleUnknownChunk(client, type, data, isReply, msgId);
}
}
/**
* Send a MPRS (Method PRofiling Start) request to the client.
*
* @param fileName is the name of the file to which profiling data
* will be written (on the device); it will have ".trace"
* appended if necessary
* @param bufferSize is the desired buffer size in bytes (8MB is good)
* @param flags should be zero
*/
public static void sendMPRS(Client client, String fileName, int bufferSize,
int flags) throws IOException {
ByteBuffer rawBuf = allocBuffer(3*4 + fileName.length() * 2);
JdwpPacket packet = new JdwpPacket(rawBuf);
ByteBuffer buf = getChunkDataBuf(rawBuf);
buf.putInt(bufferSize);
buf.putInt(flags);
buf.putInt(fileName.length());
putString(buf, fileName);
finishChunkPacket(packet, CHUNK_MPRS, buf.position());
Log.d("ddm-prof", "Sending " + name(CHUNK_MPRS) + " '" + fileName
+ "', size=" + bufferSize + ", flags=" + flags);
client.sendAndConsume(packet, mInst);
}
/**
* Send a MPRE (Method PRofiling End) request to the client.
*/
public static void sendMPRE(Client client) throws IOException {
ByteBuffer rawBuf = allocBuffer(0);
JdwpPacket packet = new JdwpPacket(rawBuf);
ByteBuffer buf = getChunkDataBuf(rawBuf);
// no data
finishChunkPacket(packet, CHUNK_MPRE, buf.position());
Log.d("ddm-prof", "Sending " + name(CHUNK_MPRE));
client.sendAndConsume(packet, mInst);
}
/**
* Handle notification that method profiling has finished writing
* data to disk.
*/
private void handleMPRE(Client client, ByteBuffer data) {
byte result;
result = data.get();
if (result == 0) {
Log.i("ddm-prof", "Method profiling has finished");
} else {
Log.w("ddm-prof", "Method profiling has failed (check device log)");
}
// TODO: stuff
}
/**
* Send a MPRQ (Method PRofiling Query) request to the client.
*/
public static void sendMPRQ(Client client) throws IOException {
ByteBuffer rawBuf = allocBuffer(0);
JdwpPacket packet = new JdwpPacket(rawBuf);
ByteBuffer buf = getChunkDataBuf(rawBuf);
// no data
finishChunkPacket(packet, CHUNK_MPRQ, buf.position());
Log.d("ddm-prof", "Sending " + name(CHUNK_MPRQ));
client.sendAndConsume(packet, mInst);
}
/**
* Receive response to query.
*/
private void handleMPRQ(Client client, ByteBuffer data) {
byte result;
result = data.get();
if (result == 0) {
Log.i("ddm-prof", "Method profiling is not running");
} else {
Log.i("ddm-prof", "Method profiling is running");
}
}
}

View File

@@ -16,7 +16,6 @@
package com.android.ddmlib;
import com.android.ddmlib.Device.DeviceState;
import com.android.ddmlib.log.LogReceiver;
import java.io.IOException;
@@ -40,6 +39,35 @@ public interface IDevice {
/** Device change bit mask: build info change. */
public static final int CHANGE_BUILD_INFO = 0x0004;
/**
* The state of a device.
*/
public static enum DeviceState {
BOOTLOADER("bootloader"), //$NON-NLS-1$
OFFLINE("offline"), //$NON-NLS-1$
ONLINE("device"); //$NON-NLS-1$
private String mState;
DeviceState(String state) {
mState = state;
}
/**
* Returns a {@link DeviceState} from the string returned by <code>adb devices</code>.
* @param state the device state.
* @return a {@link DeviceState} object or <code>null</code> if the state is unknown.
*/
public static DeviceState getState(String state) {
for (DeviceState deviceState : values()) {
if (deviceState.mState.equals(state)) {
return deviceState;
}
}
return null;
}
}
/**
* Returns the serial number of the device.
*/
@@ -118,9 +146,11 @@ public interface IDevice {
/**
* Returns a {@link SyncService} object to push / pull files to and from the device.
* @return <code>null</code> if the SyncService couldn't be created.
* @return <code>null</code> if the SyncService couldn't be created. This can happen if adb
* refuse to open the connection because the {@link IDevice} is invalid (or got disconnected).
* @throws IOException if the connection with adb failed.
*/
public SyncService getSyncService();
public SyncService getSyncService() throws IOException;
/**
* Returns a {@link FileListingService} for this device.
@@ -181,4 +211,48 @@ public interface IDevice {
*/
public String getClientName(int pid);
/**
* Installs an Android application on device.
* This is a helper method that combines the syncPackageToDevice, installRemotePackage,
* and removePackage steps
* @param packageFilePath the absolute file system path to file on local host to install
* @param reinstall set to <code>true</code> if re-install of app should be performed
* @return a {@link String} with an error code, or <code>null</code> if success.
* @throws IOException
*/
public String installPackage(String packageFilePath, boolean reinstall) throws IOException;
/**
* Pushes a file to device
* @param localFilePath the absolute path to file on local host
* @return {@link String} destination path on device for file
* @throws IOException if fatal error occurred when pushing file
*/
public String syncPackageToDevice(String localFilePath)
throws IOException;
/**
* Installs the application package that was pushed to a temporary location on the device.
* @param remoteFilePath absolute file path to package file on device
* @param reinstall set to <code>true</code> if re-install of app should be performed
* @throws InstallException if installation failed
*/
public String installRemotePackage(String remoteFilePath, boolean reinstall)
throws IOException;
/**
* Remove a file from device
* @param remoteFilePath path on device of file to remove
* @throws IOException if file removal failed
*/
public void removeRemotePackage(String remoteFilePath) throws IOException;
/**
* Uninstall an package from the device.
* @param packageName the Android application package name to uninstall
* @return a {@link String} with an error code, or <code>null</code> if success.
* @throws IOException
*/
public String uninstallPackage(String packageName) throws IOException;
}

View File

@@ -103,7 +103,7 @@ final class MonitorThread extends Thread {
/**
* Sets or changes the port number for "debug selected".
* Sets or changes the port number for "debug selected".
*/
synchronized void setDebugSelectedPort(int port) throws IllegalStateException {
if (mInstance == null) {
@@ -206,7 +206,7 @@ final class MonitorThread extends Thread {
}
while (!mQuit) {
try {
/*
* sync with new registrations: we wait until addClient is done before going through
@@ -215,7 +215,7 @@ final class MonitorThread extends Thread {
*/
synchronized (mClientList) {
}
// (re-)open the "debug selected" port, if it's not opened yet or
// if the port changed.
try {
@@ -234,7 +234,7 @@ final class MonitorThread extends Thread {
Log.e("ddms", ioe);
mNewDebugSelectedPort = mDebugSelectedPort; // no retry
}
int count;
try {
count = mSelector.select();
@@ -244,20 +244,20 @@ final class MonitorThread extends Thread {
} catch (CancelledKeyException cke) {
continue;
}
if (count == 0) {
// somebody called wakeup() ?
// Log.i("ddms", "selector looping");
continue;
}
Set<SelectionKey> keys = mSelector.selectedKeys();
Iterator<SelectionKey> iter = keys.iterator();
while (iter.hasNext()) {
SelectionKey key = iter.next();
iter.remove();
try {
if (key.attachment() instanceof Client) {
processClientActivity(key);
@@ -300,7 +300,7 @@ final class MonitorThread extends Thread {
*/
private void processClientActivity(SelectionKey key) {
Client client = (Client)key.attachment();
try {
if (key.isReadable() == false || key.isValid() == false) {
Log.d("ddms", "Invalid key from " + client + ". Dropping client.");
@@ -423,7 +423,7 @@ final class MonitorThread extends Thread {
* @param notify
*/
synchronized void dropClient(Client client, boolean notify) {
if (mInstance == null) {
if (mInstance == null) {
return;
}
@@ -551,13 +551,13 @@ final class MonitorThread extends Thread {
// we should drop the client, but also attempt to reopen it.
// This is done by the DeviceMonitor.
client.getDevice().getMonitor().addClientToDropAndReopen(client,
client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
IDebugPortProvider.NO_STATIC_PORT);
} else {
Log.i("ddms", " (recycling client connection as well)");
// we should drop the client, but also attempt to reopen it.
// This is done by the DeviceMonitor.
client.getDevice().getMonitor().addClientToDropAndReopen(client,
client.getDeviceImpl().getMonitor().addClientToDropAndReopen(client,
IDebugPortProvider.NO_STATIC_PORT);
}
}
@@ -644,7 +644,7 @@ final class MonitorThread extends Thread {
}
}
}
/*
* Broadcast an event to all message handlers.
*/
@@ -719,7 +719,7 @@ final class MonitorThread extends Thread {
}
mDebugSelectedChan.register(mSelector, SelectionKey.OP_ACCEPT, this);
return true;
} catch (java.net.BindException e) {
displayDebugSelectedBindError(mNewDebugSelectedPort);
@@ -727,7 +727,7 @@ final class MonitorThread extends Thread {
// do not attempt to reopen it.
mDebugSelectedChan = null;
mNewDebugSelectedPort = -1;
return false;
}
}

View File

@@ -209,9 +209,11 @@ public final class SyncService {
/**
* Opens the sync connection. This must be called before any calls to push[File] / pull[File].
* @return true if the connection opened, false otherwise.
* @return true if the connection opened, false if adb refuse the connection. This can happen
* if the {@link Device} is invalid.
* @throws IOException If the connection to adb failed.
*/
boolean openSync() {
boolean openSync() throws IOException {
try {
mChannel = SocketChannel.open(mAddress);
mChannel.configureBlocking(false);
@@ -236,13 +238,15 @@ public final class SyncService {
if (mChannel != null) {
try {
mChannel.close();
} catch (IOException e1) {
// we do nothing, since we'll return false just below
} catch (IOException e2) {
// we want to throw the original exception, so we ignore this one.
}
mChannel = null;
return false;
}
throw e;
}
return true;
}

View File

@@ -16,7 +16,7 @@
package com.android.ddmlib.log;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.MultiLineReceiver;
import com.android.ddmlib.log.EventContainer.EventValueType;
@@ -55,7 +55,7 @@ public final class EventLogParser {
private final static int EVENT_TYPE_LONG = 1;
private final static int EVENT_TYPE_STRING = 2;
private final static int EVENT_TYPE_LIST = 3;
private final static Pattern PATTERN_SIMPLE_TAG = Pattern.compile(
"^(\\d+)\\s+([A-Za-z0-9_]+)\\s*$"); //$NON-NLS-1$
private final static Pattern PATTERN_TAG_WITH_DESC = Pattern.compile(
@@ -67,9 +67,9 @@ public final class EventLogParser {
"(\\d\\d)-(\\d\\d)\\s(\\d\\d):(\\d\\d):(\\d\\d).(\\d{3})\\s+I/([a-zA-Z0-9_]+)\\s*\\(\\s*(\\d+)\\):\\s+(.*)"); //$NON-NLS-1$
private final TreeMap<Integer, String> mTagMap = new TreeMap<Integer, String>();
private final TreeMap<Integer, EventValueDescription[]> mValueDescriptionMap =
new TreeMap<Integer, EventValueDescription[]>();
new TreeMap<Integer, EventValueDescription[]>();
public EventLogParser() {
}
@@ -82,7 +82,7 @@ public final class EventLogParser {
* @param device The device.
* @return <code>true</code> if success, <code>false</code> if failure or cancellation.
*/
public boolean init(Device device) {
public boolean init(IDevice device) {
// read the event tag map file on the device.
try {
device.executeShellCommand("cat " + EVENT_TAG_MAP_FILE, //$NON-NLS-1$
@@ -103,7 +103,7 @@ public final class EventLogParser {
return true;
}
/**
* Inits the parser with the content of a tag file.
* @param tagFileContent the lines of a tag file.
@@ -115,7 +115,7 @@ public final class EventLogParser {
}
return true;
}
/**
* Inits the parser with a specified event-log-tags file.
* @param filePath
@@ -124,7 +124,7 @@ public final class EventLogParser {
public boolean init(String filePath) {
try {
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String line = null;
do {
line = reader.readLine();
@@ -132,13 +132,13 @@ public final class EventLogParser {
processTagLine(line);
}
} while (line != null);
return true;
} catch (IOException e) {
return false;
}
}
/**
* Processes a line from the event-log-tags file.
* @param line the line to process
@@ -154,7 +154,7 @@ public final class EventLogParser {
if (name != null && mTagMap.get(value) == null) {
mTagMap.put(value, name);
}
// special case for the GC tag. We ignore what is in the file,
// and take what the custom GcEventContainer class tells us.
// This is due to the event encoding several values on 2 longs.
@@ -163,12 +163,12 @@ public final class EventLogParser {
mValueDescriptionMap.put(value,
GcEventContainer.getValueDescriptions());
} else {
String description = m.group(3);
if (description != null && description.length() > 0) {
EventValueDescription[] desc =
processDescription(description);
if (desc != null) {
mValueDescriptionMap.put(value, desc);
}
@@ -189,12 +189,12 @@ public final class EventLogParser {
}
}
}
private EventValueDescription[] processDescription(String description) {
String[] descriptions = description.split("\\s*,\\s*"); //$NON-NLS-1$
ArrayList<EventValueDescription> list = new ArrayList<EventValueDescription>();
for (String desc : descriptions) {
Matcher m = PATTERN_DESCRIPTION.matcher(desc);
if (m.matches()) {
@@ -208,15 +208,15 @@ public final class EventLogParser {
// just ignore this description if the value is not recognized.
// TODO: log the error.
}
typeString = m.group(3);
if (typeString != null && typeString.length() > 0) {
//skip the |
typeString = typeString.substring(1);
typeValue = Integer.parseInt(typeString);
ValueType valueType = ValueType.getValueType(typeValue);
list.add(new EventValueDescription(name, eventValueType, valueType));
} else {
list.add(new EventValueDescription(name, eventValueType));
@@ -233,15 +233,15 @@ public final class EventLogParser {
String.format("Can't parse %1$s", description)); //$NON-NLS-1$
}
}
if (list.size() == 0) {
return null;
}
return list.toArray(new EventValueDescription[list.size()]);
}
public EventContainer parse(LogEntry entry) {
if (entry.len < 4) {
return null;
@@ -251,7 +251,7 @@ public final class EventLogParser {
int tagValue = ArrayHelper.swap32bitFromArray(entry.data, inOffset);
inOffset += 4;
String tag = mTagMap.get(tagValue);
if (tag == null) {
Log.e("EventLogParser", String.format("unknown tag number: %1$d", tagValue));
@@ -275,10 +275,10 @@ public final class EventLogParser {
} else {
event = new EventContainer(entry, tagValue, data);
}
return event;
}
public EventContainer parse(String textLogLine) {
// line will look like
// 04-29 23:16:16.691 I/dvm_gc_info( 427): <data>
@@ -289,7 +289,7 @@ public final class EventLogParser {
if (textLogLine.length() == 0) {
return null;
}
// parse the header first
Matcher m = TEXT_LOG_LINE.matcher(textLogLine);
if (m.matches()) {
@@ -300,7 +300,7 @@ public final class EventLogParser {
int minutes = Integer.parseInt(m.group(4));
int seconds = Integer.parseInt(m.group(5));
int milliseconds = Integer.parseInt(m.group(6));
// convert into seconds since epoch and nano-seconds.
Calendar cal = Calendar.getInstance();
cal.set(cal.get(Calendar.YEAR), month-1, day, hours, minutes, seconds);
@@ -308,7 +308,7 @@ public final class EventLogParser {
int nsec = milliseconds * 1000000;
String tag = m.group(7);
// get the numerical tag value
int tagValue = -1;
Set<Entry<Integer, String>> tagSet = mTagMap.entrySet();
@@ -318,18 +318,18 @@ public final class EventLogParser {
break;
}
}
if (tagValue == -1) {
return null;
}
int pid = Integer.parseInt(m.group(8));
Object data = parseTextData(m.group(9), tagValue);
if (data == null) {
return null;
}
// now we can allocate and return the EventContainer
EventContainer event = null;
if (tagValue == GcEventContainer.GC_EVENT_TAG) {
@@ -337,20 +337,20 @@ public final class EventLogParser {
} else {
event = new EventContainer(tagValue, pid, -1 /* tid */, sec, nsec, data);
}
return event;
} catch (NumberFormatException e) {
return null;
}
}
return null;
}
public Map<Integer, String> getTagMap() {
return mTagMap;
}
public Map<Integer, EventValueDescription[]> getEventInfoMap() {
return mValueDescriptionMap;
}
@@ -370,7 +370,7 @@ public final class EventLogParser {
if (eventData.length - dataOffset < 1)
return -1;
int offset = dataOffset;
int type = eventData[offset++];
@@ -385,7 +385,7 @@ public final class EventLogParser {
return -1;
ival = ArrayHelper.swap32bitFromArray(eventData, offset);
offset += 4;
list.add(new Integer(ival));
}
break;
@@ -396,7 +396,7 @@ public final class EventLogParser {
return -1;
lval = ArrayHelper.swap64bitFromArray(eventData, offset);
offset += 8;
list.add(new Long(lval));
}
break;
@@ -410,7 +410,7 @@ public final class EventLogParser {
if (eventData.length - offset < strLen)
return -1;
// get the string
try {
String str = new String(eventData, offset, strLen, "UTF-8"); //$NON-NLS-1$
@@ -434,7 +434,7 @@ public final class EventLogParser {
if (result == -1) {
return result;
}
offset += result;
}
@@ -446,59 +446,59 @@ public final class EventLogParser {
String.format("Unknown binary event type %1$d", type)); //$NON-NLS-1$
return -1;
}
return offset - dataOffset;
}
private Object parseTextData(String data, int tagValue) {
// first, get the description of what we're supposed to parse
EventValueDescription[] desc = mValueDescriptionMap.get(tagValue);
if (desc == null) {
// TODO parse and create string values.
return null;
}
if (desc.length == 1) {
return getObjectFromString(data, desc[0].getEventValueType());
} else if (data.startsWith("[") && data.endsWith("]")) {
data = data.substring(1, data.length() - 1);
// get each individual values as String
String[] values = data.split(",");
if (tagValue == GcEventContainer.GC_EVENT_TAG) {
// special case for the GC event!
Object[] objects = new Object[2];
objects[0] = getObjectFromString(values[0], EventValueType.LONG);
objects[1] = getObjectFromString(values[1], EventValueType.LONG);
return objects;
} else {
// must be the same number as the number of descriptors.
if (values.length != desc.length) {
return null;
}
Object[] objects = new Object[values.length];
for (int i = 0 ; i < desc.length ; i++) {
Object obj = getObjectFromString(values[i], desc[i].getEventValueType());
if (obj == null) {
return null;
}
objects[i] = obj;
objects[i] = obj;
}
return objects;
}
}
return null;
}
private Object getObjectFromString(String value, EventValueType type) {
try {
switch (type) {
@@ -512,14 +512,14 @@ public final class EventLogParser {
} catch (NumberFormatException e) {
// do nothing, we'll return null.
}
return null;
}
/**
* Recreates the event-log-tags at the specified file path.
* Recreates the event-log-tags at the specified file path.
* @param filePath the file path to write the file.
* @throws IOException
* @throws IOException
*/
public void saveTags(String filePath) throws IOException {
File destFile = new File(filePath);
@@ -527,16 +527,16 @@ public final class EventLogParser {
FileOutputStream fos = null;
try {
fos = new FileOutputStream(destFile);
for (Integer key : mTagMap.keySet()) {
// get the tag name
String tagName = mTagMap.get(key);
// get the value descriptions
EventValueDescription[] descriptors = mValueDescriptionMap.get(key);
String line = null;
if (descriptors != null) {
StringBuilder sb = new StringBuilder();
@@ -557,12 +557,12 @@ public final class EventLogParser {
sb.append("|)"); //$NON-NLS-1$
}
sb.append("\n"); //$NON-NLS-1$
line = sb.toString();
} else {
line = String.format("%1$d %2$s\n", key, tagName); //$NON-NLS-1$
}
byte[] buffer = line.getBytes();
fos.write(buffer);
}

View File

@@ -22,7 +22,6 @@ import com.android.ddmlib.IDevice;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.RawImage;
import com.android.ddmlib.SyncService;
import com.android.ddmlib.Device.DeviceState;
import com.android.ddmlib.log.LogReceiver;
import java.io.IOException;
@@ -100,7 +99,7 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
final String extraArgValue = "blahValue";
mRunner.addInstrumentationArg(extraArgName, extraArgValue);
mRunner.run(new EmptyListener());
assertStringsEquals(String.format("am instrument -w -r -e %s %s %s/%s", extraArgName,
assertStringsEquals(String.format("am instrument -w -r -e %s %s %s/%s", extraArgName,
extraArgValue, TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand());
}
@@ -221,6 +220,30 @@ public class RemoteAndroidTestRunnerTest extends TestCase {
return "";
}
public String installPackage(String packageFilePath, boolean reinstall)
throws IOException {
throw new UnsupportedOperationException();
}
public String uninstallPackage(String packageName) throws IOException {
throw new UnsupportedOperationException();
}
public String installRemotePackage(String remoteFilePath,
boolean reinstall) throws IOException {
throw new UnsupportedOperationException();
}
public void removeRemotePackage(String remoteFilePath)
throws IOException {
throw new UnsupportedOperationException();
}
public String syncPackageToDevice(String localFilePath)
throws IOException {
throw new UnsupportedOperationException();
}
}
/**

View File

@@ -9,9 +9,9 @@ LOCAL_JAVA_RESOURCE_DIRS := resources
LOCAL_JAVA_LIBRARIES := \
ddmlib \
swt \
org.eclipse.jface_3.2.0.I20060605-1400 \
org.eclipse.equinox.common_3.2.0.v20060603 \
org.eclipse.core.commands_3.2.0.I20060605-1400 \
org.eclipse.jface_3.4.2.M20090107-0800 \
org.eclipse.equinox.common_3.4.0.v20080421-2006 \
org.eclipse.core.commands_3.4.0.I20080509-2000 \
jcommon-1.0.12 \
jfreechart-1.0.9 \
jfreechart-1.0.9-swt

View File

@@ -20,11 +20,11 @@ import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Client;
import com.android.ddmlib.ClientData;
import com.android.ddmlib.DdmPreferences;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.AndroidDebugBridge.IClientChangeListener;
import com.android.ddmlib.AndroidDebugBridge.IDebugBridgeChangeListener;
import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
import com.android.ddmlib.Device.DeviceState;
import com.android.ddmlib.IDevice.DeviceState;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.viewers.ILabelProviderListener;
@@ -69,16 +69,16 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
private final static int CLIENT_COL_THREAD = 2;
private final static int CLIENT_COL_HEAP = 3;
private final static int CLIENT_COL_PORT = 4;
public final static int ICON_WIDTH = 16;
public final static String ICON_THREAD = "thread.png"; //$NON-NLS-1$
public final static String ICON_HEAP = "heap.png"; //$NON-NLS-1$
public final static String ICON_HALT = "halt.png"; //$NON-NLS-1$
public final static String ICON_GC = "gc.png"; //$NON-NLS-1$
private Device mCurrentDevice;
private IDevice mCurrentDevice;
private Client mCurrentClient;
private Tree mTree;
private TreeViewer mTreeViewer;
@@ -92,8 +92,8 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
private Image mDebugErrorImage;
private final ArrayList<IUiSelectionListener> mListeners = new ArrayList<IUiSelectionListener>();
private final ArrayList<Device> mDevicesToExpand = new ArrayList<Device>();
private final ArrayList<IDevice> mDevicesToExpand = new ArrayList<IDevice>();
private IImageLoader mLoader;
@@ -102,13 +102,13 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
/**
* A Content provider for the {@link TreeViewer}.
* <p/>
* The input is a {@link AndroidDebugBridge}. First level elements are {@link Device} objects,
* The input is a {@link AndroidDebugBridge}. First level elements are {@link IDevice} objects,
* and second level elements are {@link Client} object.
*/
private class ContentProvider implements ITreeContentProvider {
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof Device) {
return ((Device)parentElement).getClients();
if (parentElement instanceof IDevice) {
return ((IDevice)parentElement).getClients();
}
return new Object[0];
}
@@ -121,8 +121,8 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
}
public boolean hasChildren(Object element) {
if (element instanceof Device) {
return ((Device)element).hasClients();
if (element instanceof IDevice) {
return ((IDevice)element).hasClients();
}
// Clients never have children.
@@ -147,13 +147,13 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
/**
* A Label Provider for the {@link TreeViewer} in {@link DevicePanel}. It provides
* labels and images for {@link Device} and {@link Client} objects.
* labels and images for {@link IDevice} and {@link Client} objects.
*/
private class LabelProvider implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
if (columnIndex == DEVICE_COL_SERIAL && element instanceof Device) {
Device device = (Device)element;
if (columnIndex == DEVICE_COL_SERIAL && element instanceof IDevice) {
IDevice device = (IDevice)element;
if (device.isEmulator()) {
return mEmulatorImage;
}
@@ -192,17 +192,17 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
}
public String getColumnText(Object element, int columnIndex) {
if (element instanceof Device) {
Device device = (Device)element;
if (element instanceof IDevice) {
IDevice device = (IDevice)element;
switch (columnIndex) {
case DEVICE_COL_SERIAL:
return device.getSerialNumber();
case DEVICE_COL_STATE:
return getStateString(device);
case DEVICE_COL_BUILD: {
String version = device.getProperty(Device.PROP_BUILD_VERSION);
String version = device.getProperty(IDevice.PROP_BUILD_VERSION);
if (version != null) {
String debuggable = device.getProperty(Device.PROP_DEBUGGABLE);
String debuggable = device.getProperty(IDevice.PROP_DEBUGGABLE);
if (device.isEmulator()) {
String avdName = device.getAvdName();
if (avdName == null) {
@@ -279,15 +279,15 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
/**
* Classes which implement this interface provide methods that deals
* with {@link Device} and {@link Client} selection changes coming from the ui.
* with {@link IDevice} and {@link Client} selection changes coming from the ui.
*/
public interface IUiSelectionListener {
/**
* Sent when a new {@link Device} and {@link Client} are selected.
* Sent when a new {@link IDevice} and {@link Client} are selected.
* @param selectedDevice the selected device. If null, no devices are selected.
* @param selectedClient The selected client. If null, no clients are selected.
*/
public void selectionChanged(Device selectedDevice, Client selectedClient);
public void selectionChanged(IDevice selectedDevice, Client selectedClient);
}
/**
@@ -359,7 +359,7 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
return mTree;
}
/**
* Sets the focus to the proper control inside the panel.
*/
@@ -371,7 +371,7 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
@Override
protected void postCreation() {
// ask for notification of changes in AndroidDebugBridge (a new one is created when
// adb is restarted from a different location), Device and Client objects.
// adb is restarted from a different location), IDevice and Client objects.
AndroidDebugBridge.addDebugBridgeChangeListener(this);
AndroidDebugBridge.addDeviceChangeListener(this);
AndroidDebugBridge.addClientChangeListener(this);
@@ -391,10 +391,10 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
}
/**
* Returns the selected {@link Device}. If a {@link Client} is selected, it returns the
* Device object containing the client.
* Returns the selected {@link IDevice}. If a {@link Client} is selected, it returns the
* IDevice object containing the client.
*/
public Device getSelectedDevice() {
public IDevice getSelectedDevice() {
return mCurrentDevice;
}
@@ -404,7 +404,7 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
public void killSelectedClient() {
if (mCurrentClient != null) {
Client client = mCurrentClient;
// reset the selection to the device.
TreePath treePath = new TreePath(new Object[] { mCurrentDevice });
TreeSelection treeSelection = new TreeSelection(treePath);
@@ -413,7 +413,7 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
client.kill();
}
}
/**
* Forces a GC on the selected {@link Client}.
*/
@@ -422,13 +422,13 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
mCurrentClient.executeGarbageCollector();
}
}
public void setEnabledHeapOnSelectedClient(boolean enable) {
if (mCurrentClient != null) {
mCurrentClient.setHeapUpdateEnabled(enable);
}
}
public void setEnabledThreadOnSelectedClient(boolean enable) {
if (mCurrentClient != null) {
mCurrentClient.setThreadUpdateEnabled(enable);
@@ -476,9 +476,9 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
* This is sent from a non UI thread.
* @param device the new device.
*
* @see IDeviceChangeListener#deviceConnected(Device)
* @see IDeviceChangeListener#deviceConnected(IDevice)
*/
public void deviceConnected(Device device) {
public void deviceConnected(IDevice device) {
exec(new Runnable() {
public void run() {
if (mTree.isDisposed() == false) {
@@ -511,11 +511,11 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
* This is sent from a non UI thread.
* @param device the new device.
*
* @see IDeviceChangeListener#deviceDisconnected(Device)
* @see IDeviceChangeListener#deviceDisconnected(IDevice)
*/
public void deviceDisconnected(Device device) {
public void deviceDisconnected(IDevice device) {
deviceConnected(device);
// just in case, we remove it from the list of devices to expand.
synchronized (mDevicesToExpand) {
mDevicesToExpand.remove(device);
@@ -529,9 +529,9 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
* @param device the device that was updated.
* @param changeMask the mask indicating what changed.
*
* @see IDeviceChangeListener#deviceChanged(Device)
* @see IDeviceChangeListener#deviceChanged(IDevice)
*/
public void deviceChanged(final Device device, int changeMask) {
public void deviceChanged(final IDevice device, int changeMask) {
boolean expand = false;
synchronized (mDevicesToExpand) {
int index = mDevicesToExpand.indexOf(device);
@@ -540,7 +540,7 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
expand = true;
}
}
final boolean finalExpand = expand;
exec(new Runnable() {
@@ -549,22 +549,22 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
// look if the current device is selected. This is done in case the current
// client of this particular device was killed. In this case, we'll need to
// manually reselect the device.
Device selectedDevice = getSelectedDevice();
IDevice selectedDevice = getSelectedDevice();
// refresh the device
mTreeViewer.refresh(device);
// if the selected device was the changed device and the new selection is
// empty, we reselect the device.
if (selectedDevice == device && mTreeViewer.getSelection().isEmpty()) {
mTreeViewer.setSelection(new TreeSelection(new TreePath(
new Object[] { device })));
}
// notify the listener of a possible selection change.
notifyListeners();
if (finalExpand) {
mTreeViewer.setExpandedState(device, true);
}
@@ -606,7 +606,7 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
// make sure the device is expanded. Normally the setSelection below
// will auto expand, but the children of device may not already exist
// at this time. Forcing an expand will make the TreeViewer create them.
Device device = client.getDevice();
IDevice device = client.getDevice();
if (mTreeViewer.getExpandedState(device) == false) {
mTreeViewer.setExpandedState(device, true);
}
@@ -615,11 +615,11 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
TreePath treePath = new TreePath(new Object[] { device, client});
TreeSelection treeSelection = new TreeSelection(treePath);
mTreeViewer.setSelection(treeSelection);
if (mAdvancedPortSupport) {
client.setAsSelectedClient();
}
// notify the listener of a possible selection change.
notifyListeners(device, client);
}
@@ -676,7 +676,7 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
* Returns a display string representing the state of the device.
* @param d the device
*/
private static String getStateString(Device d) {
private static String getStateString(IDevice d) {
DeviceState deviceState = d.getState();
if (deviceState == DeviceState.ONLINE) {
return "Online";
@@ -704,32 +704,32 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
AndroidDebugBridge.removeClientChangeListener(this);
}
}
private void notifyListeners() {
// get the selection
TreeItem[] items = mTree.getSelection();
Client client = null;
Device device = null;
IDevice device = null;
if (items.length == 1) {
Object object = items[0].getData();
if (object instanceof Client) {
client = (Client)object;
device = client.getDevice();
} else if (object instanceof Device) {
device = (Device)object;
} else if (object instanceof IDevice) {
device = (IDevice)object;
}
}
notifyListeners(device, client);
}
private void notifyListeners(Device selectedDevice, Client selectedClient) {
private void notifyListeners(IDevice selectedDevice, Client selectedClient) {
if (selectedDevice != mCurrentDevice || selectedClient != mCurrentClient) {
mCurrentDevice = selectedDevice;
mCurrentClient = selectedClient;
for (IUiSelectionListener listener : mListeners) {
// notify the listener with a try/catch-all to make sure this thread won't die
// because of an uncaught exception before all the listeners were notified.
@@ -740,5 +740,5 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen
}
}
}
}

View File

@@ -16,7 +16,7 @@
package com.android.ddmuilib;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.EmulatorConsole;
import com.android.ddmlib.EmulatorConsole.GsmMode;
import com.android.ddmlib.EmulatorConsole.GsmStatus;
@@ -75,7 +75,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
// default location: Patio outside Charlie's
private final static double DEFAULT_LONGITUDE = -122.084095;
private final static double DEFAULT_LATITUDE = 37.422006;
private final static String SPEED_FORMAT = "Speed: %1$dX";
@@ -106,7 +106,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
"EDGE",
"UMTS",
};
private final static int[] PLAY_SPEEDS = new int[] { 1, 2, 5, 10, 20, 50 };
private final static String RE_PHONE_NUMBER = "^[+#0-9]+$"; //$NON-NLS-1$
@@ -149,7 +149,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
private Button mCancelButton;
private TabFolder mLocationFolders;
private Button mDecimalButton;
private Button mSexagesimalButton;
private CoordinateControls mLongitudeControls;
@@ -177,7 +177,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
private int mPlayDirection = 1;
private int mSpeed;
private int mSpeedIndex;
private final SelectionAdapter mDirectionButtonAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -188,7 +188,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
b.setSelection(true);
return;
}
// now handle selection change.
if (b == mGpxForwardButton || b == mKmlForwardButton) {
mGpxBackwardButton.setSelection(false);
@@ -196,7 +196,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
mKmlBackwardButton.setSelection(false);
mKmlForwardButton.setSelection(true);
mPlayDirection = 1;
} else {
mGpxBackwardButton.setSelection(true);
mGpxForwardButton.setSelection(false);
@@ -206,27 +206,27 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
}
}
};
private final SelectionAdapter mSpeedButtonAdapter = new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
mSpeedIndex = (mSpeedIndex+1) % PLAY_SPEEDS.length;
mSpeed = PLAY_SPEEDS[mSpeedIndex];
mGpxSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
mGpxPlayControls.pack();
mKmlSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
mKmlPlayControls.pack();
if (mPlayingThread != null) {
mPlayingThread.interrupt();
}
}
}
};
private Composite mKmlPlayControls;
private Composite mGpxPlayControls;
public EmulatorControlPanel(IImageLoader imageLoader) {
mImageLoader = imageLoader;
}
@@ -274,11 +274,11 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
scollingParent.setMinSize(top.computeSize(r.width, SWT.DEFAULT));
}
});
createRadioControls(top);
createCallControls(top);
createLocationControls(top);
doEnable(false);
@@ -379,7 +379,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
Label l = new Label(g1, SWT.NONE);
l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
}
/**
* Create Voice/SMS call/hang up controls
* @param top
@@ -517,7 +517,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
}
});
}
/**
* Create Location controls.
* @param top
@@ -526,15 +526,15 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
Label l = new Label(top, SWT.NONE);
l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
l.setText("Location Controls");
mLocationFolders = new TabFolder(top, SWT.NONE);
mLocationFolders.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
Composite manualLocationComp = new Composite(mLocationFolders, SWT.NONE);
TabItem item = new TabItem(mLocationFolders, SWT.NONE);
item.setText("Manual");
item.setControl(manualLocationComp);
createManualLocationControl(manualLocationComp);
mPlayImage = mImageLoader.loadImage("play.png", mParent.getDisplay()); // $NON-NLS-1$
@@ -544,7 +544,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
item = new TabItem(mLocationFolders, SWT.NONE);
item.setText("GPX");
item.setControl(gpxLocationComp);
createGpxLocationControl(gpxLocationComp);
Composite kmlLocationComp = new Composite(mLocationFolders, SWT.NONE);
@@ -552,7 +552,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
item = new TabItem(mLocationFolders, SWT.NONE);
item.setText("KML");
item.setControl(kmlLocationComp);
createKmlLocationControl(kmlLocationComp);
}
@@ -572,63 +572,63 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
// composite to hold and switching between the 2 modes.
final Composite content = new Composite(manualLocationComp, SWT.NONE);
content.setLayout(sl = new StackLayout());
// decimal display
final Composite decimalContent = new Composite(content, SWT.NONE);
decimalContent.setLayout(gl = new GridLayout(2, false));
gl.marginHeight = gl.marginWidth = 0;
mLongitudeControls = new CoordinateControls();
mLatitudeControls = new CoordinateControls();
label = new Label(decimalContent, SWT.NONE);
label.setText("Longitude");
mLongitudeControls.createDecimalText(decimalContent);
label = new Label(decimalContent, SWT.NONE);
label.setText("Latitude");
mLatitudeControls.createDecimalText(decimalContent);
// sexagesimal content
final Composite sexagesimalContent = new Composite(content, SWT.NONE);
sexagesimalContent.setLayout(gl = new GridLayout(7, false));
gl.marginHeight = gl.marginWidth = 0;
label = new Label(sexagesimalContent, SWT.NONE);
label.setText("Longitude");
mLongitudeControls.createSexagesimalDegreeText(sexagesimalContent);
label = new Label(sexagesimalContent, SWT.NONE);
label.setText("\u00B0"); // degree character
mLongitudeControls.createSexagesimalMinuteText(sexagesimalContent);
label = new Label(sexagesimalContent, SWT.NONE);
label.setText("'");
mLongitudeControls.createSexagesimalSecondText(sexagesimalContent);
label = new Label(sexagesimalContent, SWT.NONE);
label.setText("\"");
label = new Label(sexagesimalContent, SWT.NONE);
label.setText("Latitude");
mLatitudeControls.createSexagesimalDegreeText(sexagesimalContent);
label = new Label(sexagesimalContent, SWT.NONE);
label.setText("\u00B0");
mLatitudeControls.createSexagesimalMinuteText(sexagesimalContent);
label = new Label(sexagesimalContent, SWT.NONE);
label.setText("'");
mLatitudeControls.createSexagesimalSecondText(sexagesimalContent);
label = new Label(sexagesimalContent, SWT.NONE);
label.setText("\"");
@@ -647,7 +647,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
content.layout();
}
});
Button sendButton = new Button(manualLocationComp, SWT.PUSH);
sendButton.setText("Send");
sendButton.addSelectionListener(new SelectionAdapter() {
@@ -659,7 +659,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
}
}
});
mLongitudeControls.setValue(DEFAULT_LONGITUDE);
mLatitudeControls.setValue(DEFAULT_LATITUDE);
}
@@ -681,7 +681,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
gd.heightHint = 100;
mGpxWayPointTable.setHeaderVisible(true);
mGpxWayPointTable.setLinesVisible(true);
TableHelper.createTableColumn(mGpxWayPointTable, "Name", SWT.LEFT,
"Some Name",
PREFS_WAYPOINT_COL_NAME, store);
@@ -701,7 +701,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
final TableViewer gpxWayPointViewer = new TableViewer(mGpxWayPointTable);
gpxWayPointViewer.setContentProvider(new WayPointContentProvider());
gpxWayPointViewer.setLabelProvider(new WayPointLabelProvider());
gpxWayPointViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
ISelection selection = event.getSelection();
@@ -710,7 +710,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
Object selectedObject = structuredSelection.getFirstElement();
if (selectedObject instanceof WayPoint) {
WayPoint wayPoint = (WayPoint)selectedObject;
if (mEmulatorConsole != null && mPlayingTrack == false) {
processCommandResult(mEmulatorConsole.sendLocation(
wayPoint.getLongitude(), wayPoint.getLatitude(),
@@ -748,7 +748,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
final TableViewer gpxTrackViewer = new TableViewer(mGpxTrackTable);
gpxTrackViewer.setContentProvider(new TrackContentProvider());
gpxTrackViewer.setLabelProvider(new TrackLabelProvider());
gpxTrackViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
ISelection selection = event.getSelection();
@@ -757,19 +757,19 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
Object selectedObject = structuredSelection.getFirstElement();
if (selectedObject instanceof Track) {
Track track = (Track)selectedObject;
if (mEmulatorConsole != null && mPlayingTrack == false) {
TrackPoint[] points = track.getPoints();
processCommandResult(mEmulatorConsole.sendLocation(
points[0].getLongitude(), points[0].getLatitude(),
points[0].getElevation()));
}
mPlayGpxButton.setEnabled(true);
mGpxBackwardButton.setEnabled(true);
mGpxForwardButton.setEnabled(true);
mGpxSpeedButton.setEnabled(true);
return;
}
}
@@ -780,7 +780,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
mGpxSpeedButton.setEnabled(false);
}
});
mGpxUploadButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
@@ -799,7 +799,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
}
}
});
mGpxPlayControls = new Composite(gpxLocationComp, SWT.NONE);
GridLayout gl;
mGpxPlayControls.setLayout(gl = new GridLayout(5, false));
@@ -828,14 +828,14 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
mPlayingThread.interrupt();
}
}
}
}
});
Label separator = new Label(mGpxPlayControls, SWT.SEPARATOR | SWT.VERTICAL);
separator.setLayoutData(gd = new GridData(
GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
gd.heightHint = 0;
mGpxBackwardButton = new Button(mGpxPlayControls, SWT.TOGGLE | SWT.FLAT);
mGpxBackwardButton.setImage(mImageLoader.loadImage("backward.png", mParent.getDisplay())); // $NON-NLS-1$
mGpxBackwardButton.setSelection(false);
@@ -852,7 +852,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
mGpxSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
mGpxSpeedButton.addSelectionListener(mSpeedButtonAdapter);
mPlayGpxButton.setEnabled(false);
mGpxBackwardButton.setEnabled(false);
mGpxForwardButton.setEnabled(false);
@@ -877,7 +877,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
gd.heightHint = 200;
mKmlWayPointTable.setHeaderVisible(true);
mKmlWayPointTable.setLinesVisible(true);
TableHelper.createTableColumn(mKmlWayPointTable, "Name", SWT.LEFT,
"Some Name",
PREFS_WAYPOINT_COL_NAME, store);
@@ -911,7 +911,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
KmlParser parser = new KmlParser(fileName);
if (parser.parse()) {
kmlWayPointViewer.setInput(parser.getWayPoints());
mPlayKmlButton.setEnabled(true);
mKmlBackwardButton.setEnabled(true);
mKmlForwardButton.setEnabled(true);
@@ -920,7 +920,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
}
}
});
kmlWayPointViewer.addSelectionChangedListener(new ISelectionChangedListener() {
public void selectionChanged(SelectionChangedEvent event) {
ISelection selection = event.getSelection();
@@ -929,7 +929,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
Object selectedObject = structuredSelection.getFirstElement();
if (selectedObject instanceof WayPoint) {
WayPoint wayPoint = (WayPoint)selectedObject;
if (mEmulatorConsole != null && mPlayingTrack == false) {
processCommandResult(mEmulatorConsole.sendLocation(
wayPoint.getLongitude(), wayPoint.getLatitude(),
@@ -939,9 +939,9 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
}
}
});
mKmlPlayControls = new Composite(kmlLocationComp, SWT.NONE);
GridLayout gl;
mKmlPlayControls.setLayout(gl = new GridLayout(5, false));
@@ -965,14 +965,14 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
mPlayingThread.interrupt();
}
}
}
}
});
Label separator = new Label(mKmlPlayControls, SWT.SEPARATOR | SWT.VERTICAL);
separator.setLayoutData(gd = new GridData(
GridData.VERTICAL_ALIGN_FILL | GridData.GRAB_VERTICAL));
gd.heightHint = 0;
mKmlBackwardButton = new Button(mKmlPlayControls, SWT.TOGGLE | SWT.FLAT);
mKmlBackwardButton.setImage(mImageLoader.loadImage("backward.png", mParent.getDisplay())); // $NON-NLS-1$
mKmlBackwardButton.setSelection(false);
@@ -989,7 +989,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
mKmlSpeedButton.setText(String.format(SPEED_FORMAT, mSpeed));
mKmlSpeedButton.addSelectionListener(mSpeedButtonAdapter);
mPlayKmlButton.setEnabled(false);
mKmlBackwardButton.setEnabled(false);
mKmlForwardButton.setEnabled(false);
@@ -1039,7 +1039,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
* Callback on device selection change.
* @param device the new selected device
*/
public void handleNewDevice(Device device) {
public void handleNewDevice(IDevice device) {
if (mParent.isDisposed()) {
return;
}
@@ -1061,7 +1061,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
// get the gsm status
gsm = mEmulatorConsole.getGsmStatus();
netstatus = mEmulatorConsole.getNetworkStatus();
if (gsm == null || netstatus == null) {
mEmulatorConsole = null;
}
@@ -1073,7 +1073,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
if (d.isDisposed() == false) {
final GsmStatus f_gsm = gsm;
final NetworkStatus f_netstatus = netstatus;
d.asyncExec(new Runnable() {
public void run() {
if (f_gsm.voice != GsmMode.UNKNOWN) {
@@ -1109,7 +1109,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
synchronized (this) {
enable = mEmulatorConsole != null;
}
enable(enable);
}
}
@@ -1240,10 +1240,10 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
} catch (SWTException e) {
// we're quitting, just ignore
}
return false;
}
return true;
}
@@ -1264,13 +1264,13 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
try {
TrackPoint[] trackPoints = track.getPoints();
int count = trackPoints.length;
// get the start index.
int start = 0;
if (mPlayDirection == -1) {
start = count - 1;
}
for (int p = start; p >= 0 && p < count; p += mPlayDirection) {
if (mPlayingTrack == false) {
return;
@@ -1299,7 +1299,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
if (delta < 0) {
delta = -delta;
}
long startTime = System.currentTimeMillis();
try {
@@ -1308,7 +1308,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
if (mPlayingTrack == false) {
return;
}
// we got interrupted, lets make sure we can play
do {
long waited = System.currentTimeMillis() - startTime;
@@ -1351,7 +1351,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
mPlayingThread.start();
}
}
private void playKml(final WayPoint[] trackPoints) {
// no need to synchronize this check, the worst that can happen, is we start the thread
// for nothing.
@@ -1365,13 +1365,13 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
public void run() {
try {
int count = trackPoints.length;
// get the start index.
int start = 0;
if (mPlayDirection == -1) {
start = count - 1;
}
for (int p = start; p >= 0 && p < count; p += mPlayDirection) {
if (mPlayingTrack == false) {
return;
@@ -1399,7 +1399,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
if (delta < 0) {
delta = -delta;
}
long startTime = System.currentTimeMillis();
try {
@@ -1408,7 +1408,7 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
if (mPlayingTrack == false) {
return;
}
// we got interrupted, lets make sure we can play
do {
long waited = System.currentTimeMillis() - startTime;
@@ -1449,6 +1449,6 @@ public class EmulatorControlPanel extends SelectionDependentPanel {
};
mPlayingThread.start();
}
}
}
}

View File

@@ -16,7 +16,7 @@
package com.android.ddmuilib;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.RawImage;
@@ -47,7 +47,7 @@ public class ScreenShotDialog extends Dialog {
private Label mBusyLabel;
private Label mImageLabel;
private Button mSave;
private Device mDevice;
private IDevice mDevice;
/**
@@ -66,9 +66,9 @@ public class ScreenShotDialog extends Dialog {
/**
* Prepare and display the dialog.
* @param device The {@link Device} from which to get the screenshot.
* @param device The {@link IDevice} from which to get the screenshot.
*/
public void open(Device device) {
public void open(IDevice device) {
mDevice = device;
Shell parent = getParent();

View File

@@ -17,20 +17,20 @@
package com.android.ddmuilib;
import com.android.ddmlib.Client;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
/**
* A Panel that requires {@link Device}/{@link Client} selection notifications.
*/
public abstract class SelectionDependentPanel extends Panel {
private Device mCurrentDevice = null;
private IDevice mCurrentDevice = null;
private Client mCurrentClient = null;
/**
* Returns the current {@link Device}.
* @return the current device or null if none are selected.
*/
protected final Device getCurrentDevice() {
protected final IDevice getCurrentDevice() {
return mCurrentDevice;
}
@@ -46,7 +46,7 @@ public abstract class SelectionDependentPanel extends Panel {
* Sent when a new device is selected.
* @param selectedDevice the selected device.
*/
public final void deviceSelected(Device selectedDevice) {
public final void deviceSelected(IDevice selectedDevice) {
if (selectedDevice != mCurrentDevice) {
mCurrentDevice = selectedDevice;
deviceSelected();

View File

@@ -16,7 +16,7 @@
package com.android.ddmuilib.explorer;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.FileListingService;
import com.android.ddmlib.IShellOutputReceiver;
import com.android.ddmlib.SyncService;
@@ -99,7 +99,7 @@ public class DeviceExplorer extends Panel {
private Image mPackageImage;
private Image mOtherImage;
private Device mCurrentDevice;
private IDevice mCurrentDevice;
private String mDefaultSave;
@@ -374,13 +374,13 @@ public class DeviceExplorer extends Panel {
}
}.start();
return mTree;
}
@Override
protected void postCreation() {
}
/**
@@ -418,61 +418,67 @@ public class DeviceExplorer extends Panel {
}
// download the files
SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
ISyncProgressMonitor monitor = SyncService.getNullProgressMonitor();
SyncResult result = sync.pullFile(keyEntry, keyFile.getAbsolutePath(), monitor);
if (result.getCode() != SyncService.RESULT_OK) {
DdmConsole.printErrorToConsole(String.format(
"Failed to pull %1$s: %2$s", keyEntry.getName(), result.getMessage()));
return;
}
try {
SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
ISyncProgressMonitor monitor = SyncService.getNullProgressMonitor();
SyncResult result = sync.pullFile(keyEntry, keyFile.getAbsolutePath(), monitor);
if (result.getCode() != SyncService.RESULT_OK) {
DdmConsole.printErrorToConsole(String.format(
"Failed to pull %1$s: %2$s", keyEntry.getName(), result.getMessage()));
return;
}
result = sync.pullFile(dataEntry, dataFile.getAbsolutePath(), monitor);
if (result.getCode() != SyncService.RESULT_OK) {
DdmConsole.printErrorToConsole(String.format(
"Failed to pull %1$s: %2$s", dataEntry.getName(), result.getMessage()));
return;
}
result = sync.pullFile(dataEntry, dataFile.getAbsolutePath(), monitor);
if (result.getCode() != SyncService.RESULT_OK) {
DdmConsole.printErrorToConsole(String.format(
"Failed to pull %1$s: %2$s", dataEntry.getName(), result.getMessage()));
return;
}
// now that we have the file, we need to launch traceview
String[] command = new String[2];
command[0] = DdmUiPreferences.getTraceview();
command[1] = path + File.separator + baseName;
// now that we have the file, we need to launch traceview
String[] command = new String[2];
command[0] = DdmUiPreferences.getTraceview();
command[1] = path + File.separator + baseName;
try {
final Process p = Runtime.getRuntime().exec(command);
try {
final Process p = Runtime.getRuntime().exec(command);
// create a thread for the output
new Thread("Traceview output") {
@Override
public void run() {
// create a buffer to read the stderr output
InputStreamReader is = new InputStreamReader(p.getErrorStream());
BufferedReader resultReader = new BufferedReader(is);
// create a thread for the output
new Thread("Traceview output") {
@Override
public void run() {
// create a buffer to read the stderr output
InputStreamReader is = new InputStreamReader(p.getErrorStream());
BufferedReader resultReader = new BufferedReader(is);
// read the lines as they come. if null is returned, it's
// because the process finished
try {
while (true) {
String line = resultReader.readLine();
if (line != null) {
DdmConsole.printErrorToConsole("Traceview: " + line);
} else {
break;
// read the lines as they come. if null is returned, it's
// because the process finished
try {
while (true) {
String line = resultReader.readLine();
if (line != null) {
DdmConsole.printErrorToConsole("Traceview: " + line);
} else {
break;
}
}
// get the return code from the process
p.waitFor();
} catch (IOException e) {
} catch (InterruptedException e) {
}
// get the return code from the process
p.waitFor();
} catch (IOException e) {
} catch (InterruptedException e) {
}
}
}.start();
}.start();
} catch (IOException e) {
} catch (IOException e) {
}
}
} catch (IOException e) {
DdmConsole.printErrorToConsole(String.format(
"Failed to pull %1$s: %2$s", keyEntry.getName(), e.getMessage()));
return;
}
}
@@ -625,7 +631,7 @@ public class DeviceExplorer extends Panel {
/**
* Sets the new device to explorer
*/
public void switchDevice(final Device device) {
public void switchDevice(final IDevice device) {
if (device != mCurrentDevice) {
mCurrentDevice = device;
// now we change the input. but we need to do that in the
@@ -667,21 +673,21 @@ public class DeviceExplorer extends Panel {
* @param localDirector the local directory in which to save the files.
*/
private void pullSelection(TreeItem[] items, final String localDirectory) {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
// make a list of the FileEntry.
ArrayList<FileEntry> entries = new ArrayList<FileEntry>();
for (TreeItem item : items) {
Object data = item.getData();
if (data instanceof FileEntry) {
entries.add((FileEntry)data);
try {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
// make a list of the FileEntry.
ArrayList<FileEntry> entries = new ArrayList<FileEntry>();
for (TreeItem item : items) {
Object data = item.getData();
if (data instanceof FileEntry) {
entries.add((FileEntry)data);
}
}
}
final FileEntry[] entryArray = entries.toArray(
new FileEntry[entries.size()]);
final FileEntry[] entryArray = entries.toArray(
new FileEntry[entries.size()]);
// get a progressdialog
try {
// get a progressdialog
new ProgressMonitorDialog(mParent.getShell()).run(true, true,
new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
@@ -699,13 +705,10 @@ public class DeviceExplorer extends Panel {
sync.close();
}
});
} catch (InvocationTargetException e) {
DdmConsole.printErrorToConsole( "Failed to pull selection");
DdmConsole.printErrorToConsole(e.getMessage());
} catch (InterruptedException e) {
DdmConsole.printErrorToConsole("Failed to pull selection");
DdmConsole.printErrorToConsole(e.getMessage());
}
} catch (Exception e) {
DdmConsole.printErrorToConsole( "Failed to pull selection");
DdmConsole.printErrorToConsole(e.getMessage());
}
}
@@ -715,9 +718,9 @@ public class DeviceExplorer extends Panel {
* @param local the destination filepath
*/
private void pullFile(final FileEntry remote, final String local) {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
try {
try {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
new ProgressMonitorDialog(mParent.getShell()).run(true, true,
new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
@@ -734,13 +737,10 @@ public class DeviceExplorer extends Panel {
sync.close();
}
});
} catch (InvocationTargetException e) {
DdmConsole.printErrorToConsole( "Failed to pull selection");
DdmConsole.printErrorToConsole(e.getMessage());
} catch (InterruptedException e) {
DdmConsole.printErrorToConsole("Failed to pull selection");
DdmConsole.printErrorToConsole(e.getMessage());
}
} catch (Exception e) {
DdmConsole.printErrorToConsole( "Failed to pull selection");
DdmConsole.printErrorToConsole(e.getMessage());
}
}
@@ -750,9 +750,9 @@ public class DeviceExplorer extends Panel {
* @param remoteDirectory
*/
private void pushFiles(final String[] localFiles, final FileEntry remoteDirectory) {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
try {
try {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
new ProgressMonitorDialog(mParent.getShell()).run(true, true,
new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
@@ -769,14 +769,10 @@ public class DeviceExplorer extends Panel {
sync.close();
}
});
} catch (InvocationTargetException e) {
DdmConsole.printErrorToConsole("Failed to push the items");
DdmConsole.printErrorToConsole(e.getMessage());
} catch (InterruptedException e) {
DdmConsole.printErrorToConsole("Failed to push the items");
DdmConsole.printErrorToConsole(e.getMessage());
}
return;
} catch (Exception e) {
DdmConsole.printErrorToConsole("Failed to push the items");
DdmConsole.printErrorToConsole(e.getMessage());
}
}
@@ -786,9 +782,9 @@ public class DeviceExplorer extends Panel {
* @param remoteDirectory the remote destination directory on the device
*/
private void pushFile(final String local, final String remoteDirectory) {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
try {
try {
final SyncService sync = mCurrentDevice.getSyncService();
if (sync != null) {
new ProgressMonitorDialog(mParent.getShell()).run(true, true,
new IRunnableWithProgress() {
public void run(IProgressMonitor monitor)
@@ -812,14 +808,10 @@ public class DeviceExplorer extends Panel {
sync.close();
}
});
} catch (InvocationTargetException e) {
DdmConsole.printErrorToConsole("Failed to push the item(s).");
DdmConsole.printErrorToConsole(e.getMessage());
} catch (InterruptedException e) {
DdmConsole.printErrorToConsole("Failed to push the item(s).");
DdmConsole.printErrorToConsole(e.getMessage());
}
return;
} catch (Exception e) {
DdmConsole.printErrorToConsole("Failed to push the item(s).");
DdmConsole.printErrorToConsole(e.getMessage());
}
}

View File

@@ -17,7 +17,7 @@
package com.android.ddmuilib.log.event;
import com.android.ddmlib.Client;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.Log.LogLevel;
import com.android.ddmlib.log.EventContainer;
@@ -80,7 +80,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
private IImageLoader mImageLoader;
private Device mCurrentLoggedDevice;
private IDevice mCurrentLoggedDevice;
private String mCurrentLogFile;
private LogReceiver mCurrentLogReceiver;
private EventLogParser mCurrentEventLogParser;
@@ -94,7 +94,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
private final ArrayList<EventContainer> mNewEvents = new ArrayList<EventContainer>();
/** indicates a pending ui thread display */
private boolean mPendingDisplay = false;
/** list of all the custom event displays */
private final ArrayList<EventDisplay> mEventDisplays = new ArrayList<EventDisplay>();
@@ -107,7 +107,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
private ICommonAction mSaveAction;
private ICommonAction mLoadAction;
private ICommonAction mImportAction;
/** file containing the current log raw data. */
private File mTempFile = null;
@@ -209,10 +209,10 @@ public class EventLogPanel extends TablePanel implements ILogListener,
// get the new EventDisplay list
mEventDisplays.clear();
mEventDisplays.addAll(dialog.getEventDisplays());
// since the list of EventDisplay changed, we store it.
saveEventDisplays();
rebuildUi();
}
}
@@ -220,7 +220,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
Log.e("EventLog", e); //$NON-NLS-1$
}
}
/**
* Clears the log.
* <p/>
@@ -240,7 +240,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
Log.e("EventLog", e); //$NON-NLS-1$
}
}
/**
* Saves the content of the event log into a file. The log is saved in the same
* binary format than on the device.
@@ -254,16 +254,16 @@ public class EventLogPanel extends TablePanel implements ILogListener,
FileInputStream fis = new FileInputStream(mTempFile);
FileOutputStream fos = new FileOutputStream(destFile);
byte[] buffer = new byte[1024];
int count;
while ((count = fis.read(buffer)) != -1) {
fos.write(buffer, 0, count);
}
fos.close();
fis.close();
// now we save the tag file
filePath = filePath + TAG_FILE_EXT;
mCurrentEventLogParser.saveTags(filePath);
@@ -293,16 +293,16 @@ public class EventLogPanel extends TablePanel implements ILogListener,
}
}
public void importBugReport(String filePath) {
try {
BugReportImporter importer = new BugReportImporter(filePath);
String[] tags = importer.getTags();
String[] log = importer.getLog();
startEventLogFromContent(tags, log);
} catch (FileNotFoundException e) {
Log.logAndDisplay(LogLevel.ERROR, "Import",
"Unable to import bug report: " + e.getMessage());
@@ -324,7 +324,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
public void deviceSelected() {
startEventLog(getCurrentDevice());
}
/*
* (non-Javadoc)
* @see com.android.ddmlib.AndroidDebugBridge.IClientChangeListener#clientChanged(com.android.ddmlib.Client, int)
@@ -359,7 +359,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
// init some store stuff
store.setDefault(PREFS_DISPLAY_WIDTH, DEFAULT_DISPLAY_WIDTH);
store.setDefault(PREFS_DISPLAY_HEIGHT, DEFAULT_DISPLAY_HEIGHT);
mBottomParentPanel = new ScrolledComposite(parent, SWT.V_SCROLL);
mBottomParentPanel.setLayoutData(new GridData(GridData.FILL_BOTH));
mBottomParentPanel.setExpandHorizontal(true);
@@ -383,7 +383,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
// create the ui
createDisplayUi();
return mBottomParentPanel;
}
@@ -402,12 +402,12 @@ public class EventLogPanel extends TablePanel implements ILogListener,
public void setFocus() {
mBottomParentPanel.setFocus();
}
/**
* Starts a new logcat and set mCurrentLogCat as the current receiver.
* @param device the device to connect logcat to.
*/
private void startEventLog(final Device device) {
private void startEventLog(final IDevice device) {
if (device == mCurrentLoggedDevice) {
return;
}
@@ -448,10 +448,10 @@ public class EventLogPanel extends TablePanel implements ILogListener,
mCurrentEventLogParser = new EventLogParser();
mCurrentEventLogParser.init(device);
}
// update the event display with the new parser.
updateEventDisplays();
// prepare the temp file that will contain the raw data
mTempFile = File.createTempFile("android-event-", ".log");
@@ -464,7 +464,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
}.start();
}
}
private void startEventLogFromFiles(final String fileName) {
// if we have a logcat already running
if (mCurrentLogReceiver != null) {
@@ -475,7 +475,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
// create a new output receiver
mCurrentLogReceiver = new LogReceiver(this);
mSaveAction.setEnabled(false);
// start the logcat in a different thread
@@ -493,10 +493,10 @@ public class EventLogPanel extends TablePanel implements ILogListener,
return;
}
}
// update the event display with the new parser.
updateEventDisplays();
runLocalEventLogService(fileName, mCurrentLogReceiver);
} catch (Exception e) {
Log.e("EventLog", e);
@@ -516,7 +516,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
// create a new output receiver
mCurrentLogReceiver = new LogReceiver(this);
mSaveAction.setEnabled(false);
// start the logcat in a different thread
@@ -531,10 +531,10 @@ public class EventLogPanel extends TablePanel implements ILogListener,
return;
}
}
// update the event display with the new parser.
updateEventDisplays();
runLocalEventLogService(log, mCurrentLogReceiver);
} catch (Exception e) {
Log.e("EventLog", e);
@@ -563,7 +563,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
resetUI(inUiThread);
}
if (mTempFile != null) {
mTempFile.delete();
mTempFile = null;
@@ -593,7 +593,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
}
}
}
private void resetUiFromUiThread() {
synchronized(mLock) {
for (EventDisplay eventDisplay : mEventDisplays) {
@@ -618,11 +618,11 @@ public class EventLogPanel extends TablePanel implements ILogListener,
rowLayout.fill = true;
rowLayout.type = SWT.HORIZONTAL;
mBottomPanel.setLayout(rowLayout);
IPreferenceStore store = DdmUiPreferences.getStore();
int displayWidth = store.getInt(PREFS_DISPLAY_WIDTH);
int displayHeight = store.getInt(PREFS_DISPLAY_HEIGHT);
for (EventDisplay eventDisplay : mEventDisplays) {
Control c = eventDisplay.createComposite(mBottomPanel, mCurrentEventLogParser, this);
if (c != null) {
@@ -631,7 +631,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
rd.width = displayWidth;
c.setLayoutData(rd);
}
Table table = eventDisplay.getTable();
if (table != null) {
addTableToFocusListener(table);
@@ -642,7 +642,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
mBottomParentPanel.setMinSize(mBottomPanel.computeSize(SWT.DEFAULT, SWT.DEFAULT));
mBottomParentPanel.layout();
}
/**
* Rebuild the display ui.
*/
@@ -652,26 +652,26 @@ public class EventLogPanel extends TablePanel implements ILogListener,
// we need to rebuild the ui. First we get rid of it.
mBottomPanel.dispose();
mBottomPanel = null;
prepareDisplayUi();
createDisplayUi();
// and fill it
boolean start_event = false;
synchronized (mNewEvents) {
mNewEvents.addAll(0, mEvents);
if (mPendingDisplay == false) {
mPendingDisplay = true;
start_event = true;
}
}
if (start_event) {
scheduleUIEventHandler();
}
Rectangle r = mBottomParentPanel.getClientArea();
mBottomParentPanel.setMinSize(mBottomPanel.computeSize(r.width,
SWT.DEFAULT));
@@ -682,7 +682,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
/**
* Processes a new {@link LogEntry} by parsing it with {@link EventLogParser} and displaying it.
* @param entry The new log entry
* @see LogReceiver.ILogListener#newEntry(LogEntry)
* @see LogReceiver.ILogListener#newEntry(LogEntry)
*/
@WorkerThread
public void newEntry(LogEntry entry) {
@@ -695,24 +695,24 @@ public class EventLogPanel extends TablePanel implements ILogListener,
}
}
}
@WorkerThread
private void handleNewEvent(EventContainer event) {
// add the event to the generic list
mEvents.add(event);
// add to the list of events that needs to be displayed, and trigger a
// new display if needed.
boolean start_event = false;
synchronized (mNewEvents) {
mNewEvents.add(event);
if (mPendingDisplay == false) {
mPendingDisplay = true;
start_event = true;
}
}
if (start_event == false) {
// we're done
return;
@@ -737,7 +737,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
}
});
} catch (SWTException e) {
// if the ui is disposed, do nothing
// if the ui is disposed, do nothing
}
}
@@ -766,7 +766,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
for (EventDisplay eventDisplay : mEventDisplays) {
eventDisplay.startMultiEventDisplay();
}
// display the new events
EventContainer event = null;
boolean need_to_reloop = false;
@@ -803,7 +803,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
for (EventDisplay eventDisplay : mEventDisplays) {
eventDisplay.endMultiEventDisplay();
}
// if needed, ask the UI thread to re-run this method.
if (need_to_reloop) {
scheduleUIEventHandler();
@@ -816,10 +816,10 @@ public class EventLogPanel extends TablePanel implements ILogListener,
private void loadEventDisplays() {
IPreferenceStore store = DdmUiPreferences.getStore();
String storage = store.getString(PREFS_EVENT_DISPLAY);
if (storage.length() > 0) {
String[] values = storage.split(Pattern.quote(EVENT_DISPLAY_STORAGE_SEPARATOR));
for (String value : values) {
EventDisplay eventDisplay = EventDisplay.load(value);
if (eventDisplay != null) {
@@ -834,10 +834,10 @@ public class EventLogPanel extends TablePanel implements ILogListener,
*/
private void saveEventDisplays() {
IPreferenceStore store = DdmUiPreferences.getStore();
boolean first = true;
StringBuilder sb = new StringBuilder();
for (EventDisplay eventDisplay : mEventDisplays) {
String storage = eventDisplay.getStorageString();
if (storage != null) {
@@ -846,7 +846,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
} else {
first = false;
}
sb.append(storage);
}
}
@@ -870,7 +870,7 @@ public class EventLogPanel extends TablePanel implements ILogListener,
for (EventDisplay eventDisplay : mEventDisplays) {
eventDisplay.setNewLogParser(mCurrentEventLogParser);
}
mOptionsAction.setEnabled(true);
mClearAction.setEnabled(true);
if (mCurrentLogFile == null) {
@@ -897,21 +897,21 @@ public class EventLogPanel extends TablePanel implements ILogListener,
* Runs an event log service out of a local file.
* @param fileName the full file name of the local file containing the event log.
* @param logReceiver the receiver that will handle the log
* @throws IOException
* @throws IOException
*/
@WorkerThread
private void runLocalEventLogService(String fileName, LogReceiver logReceiver)
throws IOException {
byte[] buffer = new byte[256];
FileInputStream fis = new FileInputStream(fileName);
int count;
while ((count = fis.read(buffer)) != -1) {
logReceiver.parseNewData(buffer, 0, count);
}
}
@WorkerThread
private void runLocalEventLogService(String[] log, LogReceiver currentLogReceiver) {
synchronized (mLock) {

View File

@@ -16,7 +16,7 @@
package com.android.ddmuilib.logcat;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.MultiLineReceiver;
import com.android.ddmlib.Log.LogLevel;
@@ -163,13 +163,13 @@ public class LogPanel extends SelectionDependentPanel {
private int mFilterMode = FILTER_NONE;
/** Device currently running logcat */
private Device mCurrentLoggedDevice = null;
private IDevice mCurrentLoggedDevice = null;
private ICommonAction mDeleteFilterAction;
private ICommonAction mEditFilterAction;
private ICommonAction[] mLogLevelActions;
/** message data, separated from content for multi line messages */
protected static class LogMessageInfo {
public LogLevel logLevel;
@@ -183,7 +183,7 @@ public class LogPanel extends SelectionDependentPanel {
* log message, to reuse the info regarding level, pid, etc...
*/
private LogMessageInfo mLastMessageInfo = null;
private boolean mPendingAsyncRefresh = false;
/** loader for the images. the implementation will varie between standalone
@@ -481,7 +481,7 @@ public class LogPanel extends SelectionDependentPanel {
* Starts a new logcat and set mCurrentLogCat as the current receiver.
* @param device the device to connect logcat to.
*/
public void startLogCat(final Device device) {
public void startLogCat(final IDevice device) {
if (device == mCurrentLoggedDevice) {
return;
}
@@ -491,7 +491,7 @@ public class LogPanel extends SelectionDependentPanel {
stopLogCat(false);
mCurrentLoggedDevice = null;
}
resetUI(false);
if (device != null) {
@@ -696,7 +696,7 @@ public class LogPanel extends SelectionDependentPanel {
synchronized (mBuffer) {
FileDialog dlg = new FileDialog(mParent.getShell(), SWT.SAVE);
String fileName;
dlg.setText("Save log...");
dlg.setFileName("log.txt");
String defaultPath = mDefaultLogSave;
@@ -710,7 +710,7 @@ public class LogPanel extends SelectionDependentPanel {
dlg.setFilterExtensions(new String[] {
"*.txt"
});
fileName = dlg.open();
if (fileName != null) {
mDefaultLogSave = dlg.getFilterPath();
@@ -928,7 +928,7 @@ public class LogPanel extends SelectionDependentPanel {
t.setLinesVisible(false);
if (mGlobalListener != null) {
addTableToFocusListener(t);
addTableToFocusListener(t);
}
// create a controllistener that will handle the resizing of all the
@@ -1064,7 +1064,7 @@ public class LogPanel extends SelectionDependentPanel {
}
/**
* Process new Log lines coming from {@link LogCatOuputReceiver}.
* Process new Log lines coming from {@link LogCatOuputReceiver}.
* @param lines the new lines
*/
protected void processLogLines(String[] lines) {
@@ -1074,10 +1074,10 @@ public class LogPanel extends SelectionDependentPanel {
if (lines.length > STRING_BUFFER_LENGTH) {
Log.e("LogCat", "Receiving more lines than STRING_BUFFER_LENGTH");
}
// parse the lines and create LogMessage that are stored in a temporary list
final ArrayList<LogMessage> newMessages = new ArrayList<LogMessage>();
synchronized (mBuffer) {
for (String line : lines) {
// ignore empty lines.
@@ -1087,7 +1087,7 @@ public class LogPanel extends SelectionDependentPanel {
if (matcher.matches()) {
// this is a header line, parse the header and keep it around.
mLastMessageInfo = new LogMessageInfo();
mLastMessageInfo.time = matcher.group(1);
mLastMessageInfo.pidString = matcher.group(2);
mLastMessageInfo.pid = Integer.valueOf(mLastMessageInfo.pidString);
@@ -1097,7 +1097,7 @@ public class LogPanel extends SelectionDependentPanel {
// This is not a header line.
// Create a new LogMessage and process it.
LogMessage mc = new LogMessage();
if (mLastMessageInfo == null) {
// The first line of output wasn't preceded
// by a header line; make something up so
@@ -1109,34 +1109,34 @@ public class LogPanel extends SelectionDependentPanel {
mLastMessageInfo.logLevel = LogLevel.INFO;
mLastMessageInfo.tag = "<unknown>"; //$NON-NLS1$
}
// If someone printed a log message with
// embedded '\n' characters, there will
// one header line followed by multiple text lines.
// Use the last header that we saw.
mc.data = mLastMessageInfo;
// tabs seem to display as only 1 tab so we replace the leading tabs
// by 4 spaces.
mc.msg = line.replaceAll("\t", " "); //$NON-NLS-1$ //$NON-NLS-2$
// process the new LogMessage.
processNewMessage(mc);
// store the new LogMessage
newMessages.add(mc);
}
}
}
// if we don't have a pending Runnable that will do the refresh, we ask the Display
// to run one in the UI thread.
if (mPendingAsyncRefresh == false) {
mPendingAsyncRefresh = true;
try {
Display display = mFolders.getDisplay();
// run in sync because this will update the buffer start/end indices
display.asyncExec(new Runnable() {
public void run() {
@@ -1165,7 +1165,7 @@ public class LogPanel extends SelectionDependentPanel {
f.flush();
}
}
if (mDefaultFilter != null) {
mDefaultFilter.flush();
}
@@ -1209,7 +1209,7 @@ public class LogPanel extends SelectionDependentPanel {
// increment the next usable slot index
mBufferEnd = (mBufferEnd + 1) % STRING_BUFFER_LENGTH;
}
LogMessage oldMessage = null;
// record the message that was there before
@@ -1381,7 +1381,7 @@ public class LogPanel extends SelectionDependentPanel {
initDefaultFilter();
return;
}
filter.clear();
if (mBufferStart != -1) {
@@ -1482,13 +1482,13 @@ public class LogPanel extends SelectionDependentPanel {
if (mDefaultFilter != null) {
mDefaultFilter.resetTempFiltering();
}
// now we need to figure out the new temp filtering
// split each word
String[] segments = text.split(" "); //$NON-NLS-1$
ArrayList<String> keywords = new ArrayList<String>(segments.length);
// loop and look for temp id/tag
int tempPid = -1;
String tempTag = null;
@@ -1511,12 +1511,12 @@ public class LogPanel extends SelectionDependentPanel {
keywords.add(s);
}
}
// set the temp filtering in the filters
if (tempPid != -1 || tempTag != null || keywords.size() > 0) {
String[] keywordsArray = keywords.toArray(
new String[keywords.size()]);
for (LogFilter f : mFilters) {
if (tempPid != -1) {
f.setTempPidFiltering(tempPid);
@@ -1526,7 +1526,7 @@ public class LogPanel extends SelectionDependentPanel {
}
f.setTempKeywordFiltering(keywordsArray);
}
if (mDefaultFilter != null) {
if (tempPid != -1) {
mDefaultFilter.setTempPidFiltering(tempPid);
@@ -1535,10 +1535,10 @@ public class LogPanel extends SelectionDependentPanel {
mDefaultFilter.setTempTagFiltering(tempTag);
}
mDefaultFilter.setTempKeywordFiltering(keywordsArray);
}
}
initFilter(mCurrentFilter);
}
}

View File

@@ -17,7 +17,7 @@
package com.android.dumpeventlog;
import com.android.ddmlib.AndroidDebugBridge;
import com.android.ddmlib.Device;
import com.android.ddmlib.IDevice;
import com.android.ddmlib.Log;
import com.android.ddmlib.Log.ILogOutput;
import com.android.ddmlib.Log.LogLevel;
@@ -30,7 +30,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
/**
* Connects to a device using ddmlib and dumps its event log as long as the device is connected.
* Connects to a device using ddmlib and dumps its event log as long as the device is connected.
*/
public class DumpEventLog {
@@ -74,7 +74,7 @@ public class DumpEventLog {
System.out.println("Usage: dumpeventlog <device s/n> <filepath>");
return;
}
// redirect the log output to /dev/null
Log.setLogOutput(new ILogOutput() {
public void printAndPromptLog(LogLevel logLevel, String tag, String message) {
@@ -85,13 +85,13 @@ public class DumpEventLog {
// pass
}
});
// init the lib
AndroidDebugBridge.init(false /* debugger support */);
try {
AndroidDebugBridge bridge = AndroidDebugBridge.createBridge();
// we can't just ask for the device list right away, as the internal thread getting
// them from ADB may not be done getting the first list.
// Since we don't really want getDevices() to be blocking, we wait here manually.
@@ -103,7 +103,7 @@ public class DumpEventLog {
} catch (InterruptedException e) {
// pass
}
// let's not wait > 10 sec.
if (count > 100) {
System.err.println("Timeout getting device list!");
@@ -112,9 +112,9 @@ public class DumpEventLog {
}
// now get the devices
Device[] devices = bridge.getDevices();
for (Device device : devices) {
IDevice[] devices = bridge.getDevices();
for (IDevice device : devices) {
if (device.getSerialNumber().equals(args[0])) {
try {
grabLogFrom(device, args[1]);
@@ -126,20 +126,20 @@ public class DumpEventLog {
return;
}
}
System.err.println("Could not find " + args[0]);
} finally {
AndroidDebugBridge.terminate();
}
}
private static void grabLogFrom(Device device, String filePath) throws IOException {
private static void grabLogFrom(IDevice device, String filePath) throws IOException {
LogWriter writer = new LogWriter(filePath);
LogReceiver receiver = new LogReceiver(writer);
writer.setReceiver(receiver);
device.runEventLogService(receiver);
writer.done();
}
}

View File

@@ -1,4 +1,15 @@
0.9.0 (work in progress)
0.9.2:
- New wizard to create Android JUnit Test Projects.
0.9.1:
- Added an AVD creation wizard to ADT. It is automatically displayed during a launch if no compatible AVDs are found.
- Fixed issue with libs/ folder where files with no extension would prevent the build from finishing.
- Improved error handling during the final steps of the build to mark the project if an unexpected error prevent the build from finishing.
- Fixed issue when launching ADT on a clean install would trigger org.eclipse.swt.SWTError: Not implemented [multiple displays].
0.9.0:
- Projects now store generated Java files (R.java/Manifest.java and output from aidl) in a 'gen' source folder.
- Support for the new Android SDK with support for multiple versions of the Android platform and for vendor supplied add-ons.
* New Project Wizard lets you choose which platform/add-on to target.

View File

@@ -2,7 +2,7 @@
<feature
id="com.android.ide.eclipse.adt"
label="Android Development Tools"
version="0.9.0.qualifier"
version="0.9.1.qualifier"
provider-name="The Android Open Source Project"
plugin="com.android.ide.eclipse.adt">
@@ -15,7 +15,7 @@
</copyright>
<license url="http://www.eclipse.org/org/documents/epl-v10.php">
Note: jcommon-1.0.12.jar is under the BSD license rather than the APL. You can find a copy of the BSD License at http://www.opensource.org/licenses/bsd-license.php
Note: jcommon-1.0.12.jar is under the BSD license rather than the APL. You can find a copy of the BSD License at http://www.opensource.org/licenses/bsd-license.php
jfreechart-1.0.9.jar and jfreechart-1.0.9-swt.jar are under the LGPL rather than the EPL. You can find a copy of the LGPL at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt. You can get the source code for these two components at http://android.git.kernel.org/pub/jfreechart-1.0.9.zip
@@ -140,6 +140,10 @@ This Agreement is governed by the laws of the State of New York and the intellec
<import plugin="org.eclipse.wst.xml.core"/>
<import plugin="org.eclipse.wst.xml.ui"/>
<import plugin="org.eclipse.jdt.junit"/>
<import plugin="org.eclipse.jdt.junit.runtime"/>
<import plugin="org.eclipse.ltk.core.refactoring"/>
<import plugin="org.eclipse.ltk.ui.refactoring"/>
<import plugin="org.eclipse.core.expressions"/>
</requires>
<plugin

View File

@@ -2,7 +2,7 @@
<feature
id="com.android.ide.eclipse.ddms"
label="Android DDMS"
version="0.9.0.qualifier"
version="0.9.1.qualifier"
provider-name="The Android Open Source Project">
<description>

View File

@@ -2,7 +2,7 @@
<feature
id="com.android.ide.eclipse.tests"
label="ADT Tests"
version="0.9.0.qualifier"
version="0.9.1.qualifier"
provider-name="The Android Open Source Project">
<copyright>

52
tools/eclipse/plugins/.gitignore vendored Normal file
View File

@@ -0,0 +1,52 @@
com.android.ide.eclipse.adt/bin
com.android.ide.eclipse.ddms/bin
com.android.ide.eclipse.tests/bin
com.android.ide.eclipse.adt/androidprefs.jar
com.android.ide.eclipse.adt/jarutils.jar
com.android.ide.eclipse.adt/kxml2-2.3.0.jar
com.android.ide.eclipse.adt/layoutlib_api.jar
com.android.ide.eclipse.adt/layoutlib_utils.jar
com.android.ide.eclipse.adt/ninepatch.jar
com.android.ide.eclipse.adt/sdklib.jar
com.android.ide.eclipse.adt/sdkstats.jar
com.android.ide.eclipse.adt/sdkuilib.jar
com.android.ide.eclipse.ddms/icons/add.png
com.android.ide.eclipse.ddms/icons/backward.png
com.android.ide.eclipse.ddms/icons/clear.png
com.android.ide.eclipse.ddms/icons/d.png
com.android.ide.eclipse.ddms/icons/debug-attach.png
com.android.ide.eclipse.ddms/icons/debug-error.png
com.android.ide.eclipse.ddms/icons/debug-wait.png
com.android.ide.eclipse.ddms/icons/delete.png
com.android.ide.eclipse.ddms/icons/device.png
com.android.ide.eclipse.ddms/icons/down.png
com.android.ide.eclipse.ddms/icons/e.png
com.android.ide.eclipse.ddms/icons/edit.png
com.android.ide.eclipse.ddms/icons/empty.png
com.android.ide.eclipse.ddms/icons/emulator.png
com.android.ide.eclipse.ddms/icons/forward.png
com.android.ide.eclipse.ddms/icons/gc.png
com.android.ide.eclipse.ddms/icons/halt.png
com.android.ide.eclipse.ddms/icons/heap.png
com.android.ide.eclipse.ddms/icons/i.png
com.android.ide.eclipse.ddms/icons/importBug.png
com.android.ide.eclipse.ddms/icons/load.png
com.android.ide.eclipse.ddms/icons/pause.png
com.android.ide.eclipse.ddms/icons/play.png
com.android.ide.eclipse.ddms/icons/pull.png
com.android.ide.eclipse.ddms/icons/push.png
com.android.ide.eclipse.ddms/icons/save.png
com.android.ide.eclipse.ddms/icons/thread.png
com.android.ide.eclipse.ddms/icons/up.png
com.android.ide.eclipse.ddms/icons/v.png
com.android.ide.eclipse.ddms/icons/w.png
com.android.ide.eclipse.ddms/icons/warning.png
com.android.ide.eclipse.ddms/libs/jcommon-1.0.12.jar
com.android.ide.eclipse.ddms/libs/jfreechart-1.0.9-swt.jar
com.android.ide.eclipse.ddms/libs/jfreechart-1.0.9.jar
com.android.ide.eclipse.ddms/src/com/android/ddmlib
com.android.ide.eclipse.ddms/src/com/android/ddmuilib
com.android.ide.eclipse.tests/kxml2-2.3.0.jar
com.android.ide.eclipse.tests/unittests/com/android/ddmlib

View File

@@ -1,63 +0,0 @@
Compiling and deploying the Android Development Toolkit (ADT) feature.
The ADT feature is composed of four plugins:
- com.android.ide.eclipse.adt:
The ADT plugin, which provides support for compiling and debugging android
applications.
- com.android.ide.eclipse.common:
A common plugin providing utility services to the other plugins.
- com.android.ide.eclipse.editors:
A plugin providing optional XML editors.
- com.android.ide.eclipse.ddms:
A plugin version of the tool DDMS
Each of these live in development/tools/eclipse/plugins/
2 Features are used to distribute the plugins:
ADT, which contains ADT, ddms, common
Editors, which contains Editors, and requires the ADT feature.
The feature projects are located in development/tools/eclipse/features/
Finally 2 site projects are located in development/tools/eclipse/sites/
internal: is a site containing the features mentioned above as well as a test feature.
external: contains only the ADT and Editors features.
Basic requirements to develop on the plugins:
- Eclipse 3.3 or 3.4 with JDT and PDE.
----------------------------------
1- Loading the projects in Eclipse
----------------------------------
The plugins projects depend on jar files located in the Android source tree,
or, in some cases, built by the Android source.
Also, some source code (ddms) is located in a different location and needs to
be linked into the DDMS plugin source.
To automatize all of this, cd into development/tools/eclipse/scripts/
and run create_all_symlinks.sh
Once this has been done successfully, use the import project action in Eclipse
and point it to development/tools/eclipse. It will find all the projects in the
sub folder.
-----------------------------------------------
2- Launching/Debugging the plugins from Eclipse
-----------------------------------------------
- Open Debug Dialog.
- Create an "Eclipse Application" configuration.
- in the "Plug-ins" tab, make sure the plugins are selected (you may
want to disable the test plugin if you just want to run ADT)
-----------------------------
3- Building a new update site
-----------------------------
- From Eclipse, open the site.xml of the site project you want to build and click
"Build All" from the "Site Map" tab.

View File

@@ -5,7 +5,7 @@
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="lib" path="jarutils.jar"/>
<classpathentry kind="lib" path="androidprefs.jar"/>
<classpathentry kind="lib" path="sdkstats.jar"/>
<classpathentry kind="lib" path="sdkstats.jar" sourcepath="/SdkStatsService"/>
<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
<classpathentry kind="lib" path="layoutlib_api.jar"/>
<classpathentry kind="lib" path="layoutlib_utils.jar"/>

View File

@@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Android Development Toolkit
Bundle-SymbolicName: com.android.ide.eclipse.adt;singleton:=true
Bundle-Version: 0.9.0.qualifier
Bundle-Version: 0.9.1.qualifier
Bundle-ClassPath: .,
jarutils.jar,
androidprefs.jar,
@@ -47,39 +47,59 @@ Require-Bundle: com.android.ide.eclipse.ddms,
org.eclipse.core.expressions
Eclipse-LazyStart: true
Export-Package: com.android.ide.eclipse.adt;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.build;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.launch;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.project;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.project.internal;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.sdk;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.wizards.newproject;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.ui;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.common;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.common.project;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.common.resources;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.layout;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.layout.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.layout.parts;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.layout.uimodel;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.manifest;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.manifest.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.manifest.model;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.manifest.pages;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.menu;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.menu.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.resources;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.resources.configurations;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.resources.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.resources.explorer;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.resources.manager;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.resources.manager.files;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.resources.uimodel;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.ui;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.ui.tree;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.uimodel;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.xml;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.editors.xml.descriptors;x-friends:="com.android.ide.eclipse.tests"
com.android.ide.eclipse.adt.internal;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.actions;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.build;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.layout;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.layout.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.layout.parts;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.layout.uimodel;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.manifest;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.manifest.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.manifest.model;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.manifest.pages;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.menu;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.menu.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.resources;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.resources.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.resources.uimodel;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.ui;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.ui.tree;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.uimodel;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.xml;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.editors.xml.descriptors;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.launch;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.launch.junit;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.launch.junit.runtime;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.preferences;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.project;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.properties;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.refactorings.extractstring;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.resources;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.resources.configurations;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.resources.manager;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.resources.manager.files;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.sdk;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.ui;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.wizards.actions;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.wizards.export;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.wizards.newproject;x-friends:="com.android.ide.eclipse.tests",
com.android.ide.eclipse.adt.internal.wizards.newxmlfile;x-friends:="com.android.ide.eclipse.tests",
com.android.jarutils;x-friends:="com.android.ide.eclipse.tests",
com.android.layoutlib.api;x-friends:="com.android.ide.eclipse.tests",
com.android.layoutlib.utils;x-friends:="com.android.ide.eclipse.tests",
com.android.ninepatch;x-friends:="com.android.ide.eclipse.tests",
com.android.prefs;x-friends:="com.android.ide.eclipse.tests",
com.android.sdklib;x-friends:="com.android.ide.eclipse.tests",
com.android.sdklib.internal.avd;x-friends:="com.android.ide.eclipse.tests",
com.android.sdklib.internal.project;x-friends:="com.android.ide.eclipse.tests",
com.android.sdklib.internal.repository;x-friends:="com.android.ide.eclipse.tests",
com.android.sdklib.repository;x-friends:="com.android.ide.eclipse.tests",
com.android.sdkstats;x-friends:="com.android.ide.eclipse.tests",
com.android.sdkuilib.internal.repository;x-friends:="com.android.ide.eclipse.tests",
com.android.sdkuilib.internal.widgets;x-friends:="com.android.ide.eclipse.tests",
com.android.sdkuilib.repository;x-friends:="com.android.ide.eclipse.tests"

Binary file not shown.

After

Width:  |  Height:  |  Size: 135 B

View File

@@ -47,7 +47,7 @@
point="org.eclipse.core.resources.builders">
<builder
hasNature="true">
<run class="com.android.ide.eclipse.adt.build.ResourceManagerBuilder"/>
<run class="com.android.ide.eclipse.adt.internal.build.ResourceManagerBuilder"/>
</builder>
</extension>
<extension
@@ -56,7 +56,7 @@
point="org.eclipse.core.resources.builders">
<builder
hasNature="true">
<run class="com.android.ide.eclipse.adt.build.PreCompilerBuilder"/>
<run class="com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder"/>
</builder>
</extension>
<extension
@@ -65,7 +65,7 @@
point="org.eclipse.core.resources.builders">
<builder
hasNature="true">
<run class="com.android.ide.eclipse.adt.build.ApkBuilder"/>
<run class="com.android.ide.eclipse.adt.internal.build.ApkBuilder"/>
</builder>
</extension>
<extension
@@ -73,7 +73,7 @@
name="AndroidNature"
point="org.eclipse.core.resources.natures">
<runtime>
<run class="com.android.ide.eclipse.adt.project.AndroidNature"/>
<run class="com.android.ide.eclipse.adt.internal.project.AndroidNature"/>
</runtime>
<builder id="com.android.ide.eclipse.adt.ResourceManagerBuilder"/>
<builder id="com.android.ide.eclipse.adt.PreCompilerBuilder"/>
@@ -87,10 +87,10 @@
<wizard
canFinishEarly="false"
category="com.android.ide.eclipse.wizards.category"
class="com.android.ide.eclipse.adt.wizards.newproject.NewProjectWizard"
class="com.android.ide.eclipse.adt.internal.wizards.newproject.NewProjectWizard"
finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
hasPages="true"
icon="icons/android.png"
icon="icons/new_adt_project.png"
id="com.android.ide.eclipse.adt.project.NewProjectWizard"
name="Android Project"
preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
@@ -98,10 +98,22 @@
<wizard
canFinishEarly="false"
category="com.android.ide.eclipse.wizards.category"
class="com.android.ide.eclipse.editors.wizards.NewXmlFileWizard"
class="com.android.ide.eclipse.adt.internal.wizards.newproject.NewTestProjectWizard"
finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
hasPages="true"
icon="icons/android.png"
icon="icons/androidjunit.png"
id="com.android.ide.eclipse.adt.project.NewTestProjectWizard"
name="Android Test Project"
preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
project="true">
</wizard>
<wizard
canFinishEarly="false"
category="com.android.ide.eclipse.wizards.category"
class="com.android.ide.eclipse.adt.internal.wizards.newxmlfile.NewXmlFileWizard"
finalPerspective="org.eclipse.jdt.ui.JavaPerspective"
hasPages="true"
icon="icons/new_xml.png"
id="com.android.ide.eclipse.editors.wizards.NewXmlFileWizard"
name="Android XML File"
preferredPerspectives="org.eclipse.jdt.ui.JavaPerspective"
@@ -111,7 +123,7 @@
<extension
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
delegate="com.android.ide.eclipse.adt.launch.LaunchConfigDelegate"
delegate="com.android.ide.eclipse.adt.internal.launch.LaunchConfigDelegate"
delegateDescription="The Android Application Launcher supports running and debugging remote Android applications on devices or emulators."
delegateName="Android Launcher"
id="com.android.ide.eclipse.adt.debug.LaunchConfigType"
@@ -132,7 +144,7 @@
<extension
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
<launchConfigurationTabGroup
class="com.android.ide.eclipse.adt.launch.LaunchConfigTabGroup"
class="com.android.ide.eclipse.adt.internal.launch.LaunchConfigTabGroup"
description="Android Application"
id="com.android.ide.eclipse.adt.debug.LaunchConfigTabGroup"
type="com.android.ide.eclipse.adt.debug.LaunchConfigType"/>
@@ -141,7 +153,7 @@
point="org.eclipse.debug.ui.launchShortcuts">
<shortcut
category="com.android.ide.eclipse.adt.launch.LaunchConfigType"
class="com.android.ide.eclipse.adt.launch.LaunchShortcut"
class="com.android.ide.eclipse.adt.internal.launch.LaunchShortcut"
icon="icons/android.png"
id="com.android.ide.eclipse.adt.debug.launching.LaunchShortcut"
label="Android Application"
@@ -197,7 +209,7 @@
</not>
</visibility>
<action
class="com.android.ide.eclipse.adt.project.ConvertToAndroidAction"
class="com.android.ide.eclipse.adt.internal.actions.ConvertToAndroidAction"
enablesFor="1"
id="com.android.ide.eclipse.adt.ConvertToAndroidAction"
label="Convert To Android Project"
@@ -220,26 +232,37 @@
value="com.android.ide.eclipse.adt.AndroidNature">
</filter>
<action
class="com.android.ide.eclipse.adt.project.NewXmlFileWizardAction"
class="com.android.ide.eclipse.adt.internal.wizards.actions.NewXmlFileAction"
enablesFor="1"
id="com.android.ide.eclipse.adt.project.NewXmlFileWizardAction"
icon="icons/new_xml.png"
id="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
label="New Resource File..."
menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1">
menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1"
tooltip="Opens a wizard to help create a new Android XML Resource file">
</action>
<action
class="com.android.ide.eclipse.adt.project.ExportAction"
class="com.android.ide.eclipse.adt.internal.wizards.actions.NewTestProjectAction"
enablesFor="1"
icon="icons/androidjunit.png"
id="com.android.ide.eclipse.adt.wizards.actions.NewTestProjectAction"
label="New Test Project..."
menubarPath="com.android.ide.eclipse.adt.AndroidTools/group1"
tooltip="Opens a wizard to help create a new Android Test Project">
</action>
<action
class="com.android.ide.eclipse.adt.internal.wizards.actions.ExportAction"
enablesFor="1"
id="com.android.ide.eclipse.adt.project.ExportAction"
label="Export Unsigned Application Package..."
menubarPath="com.android.ide.eclipse.adt.AndroidTools/group2"/>
<action
class="com.android.ide.eclipse.adt.project.ExportWizardAction"
class="com.android.ide.eclipse.adt.internal.wizards.actions.ExportWizardAction"
enablesFor="1"
id="com.android.ide.eclipse.adt.project.ExportWizardAction"
label="Export Signed Application Package..."
menubarPath="com.android.ide.eclipse.adt.AndroidTools/group2"/>
<action
class="com.android.ide.eclipse.adt.project.FixProjectAction"
class="com.android.ide.eclipse.adt.internal.actions.FixProjectAction"
enablesFor="1"
id="com.android.ide.eclipse.adt.project.FixProjectAction"
label="Fix Project Properties"
@@ -250,29 +273,29 @@
<extension
point="org.eclipse.ui.preferencePages">
<page
class="com.android.ide.eclipse.adt.preferences.AndroidPreferencePage"
class="com.android.ide.eclipse.adt.internal.preferences.AndroidPreferencePage"
id="com.android.ide.eclipse.preferences.main"
name="Android"/>
<page
category="com.android.ide.eclipse.preferences.main"
class="com.android.ide.eclipse.adt.preferences.BuildPreferencePage"
class="com.android.ide.eclipse.adt.internal.preferences.BuildPreferencePage"
id="com.android.ide.eclipse.adt.preferences.BuildPreferencePage"
name="Build"/>
<page
category="com.android.ide.eclipse.preferences.main"
class="com.android.ide.eclipse.adt.preferences.LaunchPreferencePage"
class="com.android.ide.eclipse.adt.internal.preferences.LaunchPreferencePage"
id="com.android.ide.eclipse.adt.preferences.LaunchPreferencePage"
name="Launch"/>
<page
category="com.android.ide.eclipse.preferences.main"
class="com.android.ide.eclipse.common.preferences.UsagePreferencePage"
class="com.android.ide.eclipse.adt.internal.preferences.UsagePreferencePage"
id="com.android.ide.eclipse.common.preferences.UsagePreferencePage"
name="Usage Stats">
</page>
</extension>
<extension
point="org.eclipse.core.runtime.preferences">
<initializer class="com.android.ide.eclipse.adt.preferences.PreferenceInitializer"/>
<initializer class="com.android.ide.eclipse.adt.internal.preferences.PreferenceInitializer"/>
</extension>
<extension
id="com.android.ide.eclipse.adt.adtProblem"
@@ -312,11 +335,11 @@
<extension
point="org.eclipse.jdt.core.classpathContainerInitializer">
<classpathContainerInitializer
class="com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer"
class="com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer"
id="com.android.ide.eclipse.adt.project.AndroidClasspathContainerInitializer">
</classpathContainerInitializer>
<classpathContainerInitializer
class="com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer"
class="com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer"
id="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK">
</classpathContainerInitializer>
</extension>
@@ -328,7 +351,7 @@
</category>
<wizard
category="com.android.ide.eclipse.wizards.category"
class="com.android.ide.eclipse.adt.project.export.ExportWizard"
class="com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard"
icon="icons/android.png"
id="com.android.ide.eclipse.adt.project.ExportWizard"
name="Export Android Application">
@@ -365,7 +388,7 @@
point="org.eclipse.ui.decorators">
<decorator
adaptable="true"
class="com.android.ide.eclipse.adt.project.FolderDecorator"
class="com.android.ide.eclipse.adt.internal.project.FolderDecorator"
id="com.android.ide.eclipse.adt.project.FolderDecorator"
label="Android Decorator"
lightweight="true"
@@ -377,7 +400,7 @@
<extension
point="org.eclipse.ui.editors">
<editor
class="com.android.ide.eclipse.editors.manifest.ManifestEditor"
class="com.android.ide.eclipse.adt.internal.editors.manifest.ManifestEditor"
default="true"
filenames="AndroidManifest.xml"
icon="icons/android.png"
@@ -385,7 +408,7 @@
name="Android Manifest Editor">
</editor>
<editor
class="com.android.ide.eclipse.editors.resources.ResourcesEditor"
class="com.android.ide.eclipse.adt.internal.editors.resources.ResourcesEditor"
default="false"
extensions="xml"
icon="icons/android.png"
@@ -393,16 +416,16 @@
name="Android Resource Editor">
</editor>
<editor
class="com.android.ide.eclipse.editors.layout.LayoutEditor"
class="com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor"
default="false"
extensions="xml"
icon="icons/android.png"
id="com.android.ide.eclipse.editors.layout.LayoutEditor"
matchingStrategy="com.android.ide.eclipse.editors.layout.MatchingStrategy"
matchingStrategy="com.android.ide.eclipse.adt.internal.editors.layout.MatchingStrategy"
name="Android Layout Editor">
</editor>
<editor
class="com.android.ide.eclipse.editors.menu.MenuEditor"
class="com.android.ide.eclipse.adt.internal.editors.menu.MenuEditor"
default="false"
extensions="xml"
icon="icons/android.png"
@@ -410,7 +433,7 @@
name="Android Menu Editor">
</editor>
<editor
class="com.android.ide.eclipse.editors.xml.XmlEditor"
class="com.android.ide.eclipse.adt.internal.editors.xml.XmlEditor"
default="false"
extensions="xml"
icon="icons/android.png"
@@ -423,7 +446,7 @@
<view
allowMultiple="false"
category="com.android.ide.eclipse.ddms.views.category"
class="com.android.ide.eclipse.editors.resources.explorer.ResourceExplorerView"
class="com.android.ide.eclipse.adt.internal.ui.ResourceExplorerView"
icon="icons/android.png"
id="com.android.ide.eclipse.editors.resources.explorer.ResourceExplorerView"
name="Resource Explorer">
@@ -432,23 +455,23 @@
<extension
point="org.eclipse.wst.sse.ui.editorConfiguration">
<sourceViewerConfiguration
class="com.android.ide.eclipse.editors.manifest.ManifestSourceViewerConfig"
class="com.android.ide.eclipse.adt.internal.editors.manifest.ManifestSourceViewerConfig"
target="com.android.ide.eclipse.editors.manifest.ManifestEditor">
</sourceViewerConfiguration>
<sourceViewerConfiguration
class="com.android.ide.eclipse.editors.resources.ResourcesSourceViewerConfig"
class="com.android.ide.eclipse.adt.internal.editors.resources.ResourcesSourceViewerConfig"
target="com.android.ide.eclipse.editors.resources.ResourcesEditor">
</sourceViewerConfiguration>
<sourceViewerConfiguration
class="com.android.ide.eclipse.editors.layout.LayoutSourceViewerConfig"
class="com.android.ide.eclipse.adt.internal.editors.layout.LayoutSourceViewerConfig"
target="com.android.ide.eclipse.editors.layout.LayoutEditor">
</sourceViewerConfiguration>
<sourceViewerConfiguration
class="com.android.ide.eclipse.editors.menu.MenuSourceViewerConfig"
class="com.android.ide.eclipse.adt.internal.editors.menu.MenuSourceViewerConfig"
target="com.android.ide.eclipse.editors.menu.MenuEditor">
</sourceViewerConfiguration>
<sourceViewerConfiguration
class="com.android.ide.eclipse.editors.xml.XmlSourceViewerConfig"
class="com.android.ide.eclipse.adt.internal.editors.xml.XmlSourceViewerConfig"
target="com.android.ide.eclipse.editors.xml.XmlEditor">
</sourceViewerConfiguration>
</extension>
@@ -456,7 +479,7 @@
point="org.eclipse.ui.propertyPages">
<page
adaptable="true"
class="com.android.ide.eclipse.adt.project.properties.AndroidPropertyPage"
class="com.android.ide.eclipse.adt.internal.properties.AndroidPropertyPage"
id="com.android.ide.eclipse.adt.project.properties.AndroidPropertyPage"
name="Android"
nameFilter="*"
@@ -475,7 +498,7 @@
label="Android Wizards"
visible="true">
<action
class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
class="com.android.ide.eclipse.adt.internal.wizards.actions.NewXmlFileAction"
icon="icons/new_xml.png"
id="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction"
label="New Android XML File"
@@ -484,7 +507,16 @@
tooltip="Opens a wizard to help create a new Android XML file">
</action>
<action
class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
class="com.android.ide.eclipse.adt.internal.wizards.actions.NewTestProjectAction"
icon="icons/androidjunit.png"
id="com.android.ide.eclipse.adt.wizards.actions.NewTestProjectAction"
label="New Android Test Project"
style="push"
toolbarPath="android_project"
tooltip="Opens a wizard to help create a new Android Test Project">
</action>
<action
class="com.android.ide.eclipse.adt.internal.wizards.actions.NewProjectAction"
icon="icons/new_adt_project.png"
id="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction"
label="New Android Project"
@@ -498,9 +530,9 @@
id="adt.actionSet.refactorings"
label="Android Refactorings"
visible="true">
<!-- This duplicates the Refactoring Menu definition from the jdt.ui plugin.xml,
which allows us to insert our contribution even if the JDT is not loaded.
which allows us to insert our contribution even if the JDT is not loaded.
We overload the definition with our new group.-->
<menu
label="Refactor"
@@ -518,14 +550,14 @@
<separator name="scriptGroup"/>
</menu>
<menu
label="Android"
path="org.eclipse.jdt.ui.refactoring.menu/androidGroup"
id="com.android.ide.eclipse.adt.refactoring.menu">
<separator name="android"/>
</menu>
<menu
label="Android"
path="org.eclipse.jdt.ui.refactoring.menu/androidGroup"
id="com.android.ide.eclipse.adt.refactoring.menu">
<separator name="android"/>
</menu>
<action
class="com.android.ide.eclipse.adt.refactorings.extractstring.ExtractStringAction"
class="com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringAction"
definitionId="com.android.ide.eclipse.adt.refactoring.extract.string"
id="com.android.ide.eclipse.adt.actions.ExtractString"
label="Extract Android String..."
@@ -538,11 +570,27 @@
label="Refactor">
</menu>
</actionSet>
<actionSet
description="Android AVD Manager"
id="adt.actionSet.avdManager"
label="Android AVD Manager"
visible="true">
<action
class="com.android.ide.eclipse.adt.internal.wizards.actions.AvdManagerAction"
icon="icons/avd_manager.png"
id="com.android.ide.eclipse.adt.ui.avdmanager"
label="Android AVD Manager"
menubarPath="Window/additions"
style="push"
toolbarPath="android_project"
tooltip="Opens the Android Virtual Device (AVD) Manager">
</action>
</actionSet>
</extension>
<extension
point="org.eclipse.debug.core.launchDelegates">
<launchDelegate
delegate="com.android.ide.eclipse.adt.launch.JUnitLaunchConfigDelegate"
delegate="com.android.ide.eclipse.adt.internal.launch.JUnitLaunchConfigDelegate"
delegateDescription="Removes the Android JAR from the Bootstrap Classpath"
id="com.android.ide.eclipse.adt.launch.JUnitLaunchConfigDelegate.launchAndroidJunit"
modes="run,debug"
@@ -553,7 +601,7 @@
<extension
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
delegate="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitLaunchConfigDelegate"
delegate="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitLaunchConfigDelegate"
id="com.android.ide.eclipse.adt.junit.launchConfigurationType"
modes="run,debug"
name="Android JUnit Test"
@@ -573,7 +621,7 @@
<extension
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
<launchConfigurationTabGroup
class="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitTabGroup"
class="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitTabGroup"
description="Android JUnit Test"
id="com.android.ide.eclipse.adt.junit.AndroidJUnitLaunchConfigTabGroup"
type="com.android.ide.eclipse.adt.junit.launchConfigurationType"/>
@@ -581,7 +629,7 @@
<extension
point="org.eclipse.debug.ui.launchShortcuts">
<shortcut
class="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitLaunchShortcut"
class="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitLaunchShortcut"
icon="icons/androidjunit.png"
id="com.android.ide.eclipse.adt.junit.launchShortcut"
label="Android JUnit Test"
@@ -622,7 +670,7 @@
<extension
point="org.eclipse.ltk.core.refactoring.refactoringContributions">
<contribution
class="com.android.ide.eclipse.adt.refactorings.extractstring.ExtractStringContribution"
class="com.android.ide.eclipse.adt.internal.refactorings.extractstring.ExtractStringContribution"
id="com.android.ide.eclipse.adt.refactoring.extract.string">
</contribution>
</extension>
@@ -632,7 +680,7 @@
properties="isTest,canLaunchAsJUnit"
namespace="com.android.ide.eclipse.adt"
type="org.eclipse.core.runtime.IAdaptable"
class="com.android.ide.eclipse.adt.launch.junit.AndroidJUnitPropertyTester"
class="com.android.ide.eclipse.adt.internal.launch.junit.AndroidJUnitPropertyTester"
id="com.android.ide.eclipse.adt.AndroidJUnitPropertyTester">
</propertyTester>
</extension>

View File

@@ -16,7 +16,7 @@
package com.android.ide.eclipse.adt;
import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
import com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer;
/**

View File

@@ -20,37 +20,36 @@ import com.android.ddmuilib.StackTracePanel;
import com.android.ddmuilib.StackTracePanel.ISourceRevealer;
import com.android.ddmuilib.console.DdmConsole;
import com.android.ddmuilib.console.IDdmConsole;
import com.android.ide.eclipse.adt.launch.AndroidLaunchController;
import com.android.ide.eclipse.adt.preferences.BuildPreferencePage;
import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.adt.project.export.ExportWizard;
import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer;
import com.android.ide.eclipse.adt.sdk.AndroidTargetParser;
import com.android.ide.eclipse.adt.sdk.LoadStatus;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.adt.ui.EclipseUiHelper;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.SdkStatsHelper;
import com.android.ide.eclipse.common.StreamHelper;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.common.project.ExportHelper;
import com.android.ide.eclipse.common.project.ExportHelper.IExportCallback;
import com.android.ide.eclipse.adt.internal.VersionCheck;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor;
import com.android.ide.eclipse.adt.internal.editors.menu.MenuEditor;
import com.android.ide.eclipse.adt.internal.editors.resources.ResourcesEditor;
import com.android.ide.eclipse.adt.internal.editors.xml.XmlEditor;
import com.android.ide.eclipse.adt.internal.launch.AndroidLaunchController;
import com.android.ide.eclipse.adt.internal.preferences.BuildPreferencePage;
import com.android.ide.eclipse.adt.internal.project.AndroidClasspathContainerInitializer;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ExportHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ExportHelper.IExportCallback;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolder;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceMonitor.IFileListener;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetParser;
import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.adt.internal.ui.EclipseUiHelper;
import com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard;
import com.android.ide.eclipse.ddms.DdmsPlugin;
import com.android.ide.eclipse.ddms.ImageLoader;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.layout.LayoutEditor;
import com.android.ide.eclipse.editors.menu.MenuEditor;
import com.android.ide.eclipse.editors.resources.ResourcesEditor;
import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
import com.android.ide.eclipse.editors.resources.manager.ResourceFolder;
import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor;
import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IFileListener;
import com.android.ide.eclipse.editors.xml.XmlEditor;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
import com.android.sdkstats.SdkStatsService;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
@@ -110,6 +109,7 @@ import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;
/**
@@ -118,7 +118,7 @@ import java.util.List;
public class AdtPlugin extends AbstractUIPlugin {
/** The plug-in ID */
public static final String PLUGIN_ID = "com.android.ide.eclipse.adt"; //$NON-NLS-1$
public final static String PREFS_SDK_DIR = PLUGIN_ID + ".sdk"; //$NON-NLS-1$
public final static String PREFS_RES_AUTO_REFRESH = PLUGIN_ID + ".resAutoRefresh"; //$NON-NLS-1$
@@ -132,7 +132,7 @@ public class AdtPlugin extends AbstractUIPlugin {
public final static String PREFS_HOME_PACKAGE = PLUGIN_ID + ".homePackage"; //$NON-NLS-1$
public final static String PREFS_EMU_OPTIONS = PLUGIN_ID + ".emuOptions"; //$NON-NLS-1$
/** singleton instance */
private static AdtPlugin sPlugin;
@@ -162,7 +162,7 @@ public class AdtPlugin extends AbstractUIPlugin {
/** Color used in the error console */
private Color mRed;
/** Load status of the SDK. Any access MUST be in a synchronized(mPostLoadProjects) block */
private LoadStatus mSdkIsLoaded = LoadStatus.LOADING;
/** Project to update once the SDK is loaded.
@@ -172,7 +172,7 @@ public class AdtPlugin extends AbstractUIPlugin {
/** Project to check validity of cache vs actual once the SDK is loaded.
* Any access MUST be in a synchronized(mPostLoadProjectsToResolve) block */
private final ArrayList<IJavaProject> mPostLoadProjectsToCheck = new ArrayList<IJavaProject>();
private ResourceMonitor mResourceMonitor;
private ArrayList<ITargetChangeListener> mTargetChangeListeners =
new ArrayList<ITargetChangeListener>();
@@ -204,7 +204,7 @@ public class AdtPlugin extends AbstractUIPlugin {
@Override
public void println(String message) {
// write the date/project tag first.
String tag = StreamHelper.getMessageTag(mProject != null ? mProject.getName() : null);
String tag = getMessageTag(mProject != null ? mProject.getName() : null);
print(tag);
if (mPrefix != null) {
@@ -312,7 +312,7 @@ public class AdtPlugin extends AbstractUIPlugin {
// get the SDK location and build id.
if (checkSdkLocationAndId()) {
// if sdk if valid, reparse it
// add all the opened Android projects to the list of projects to be updated
// after the SDK is reloaded
synchronized (getSdkLockObject()) {
@@ -320,7 +320,7 @@ public class AdtPlugin extends AbstractUIPlugin {
IJavaProject[] androidProjects = BaseProjectHelper.getAndroidProjects();
mPostLoadProjectsToResolve.addAll(Arrays.asList(androidProjects));
}
// parse the SDK resources at the new location
parseSdkContent();
}
@@ -341,7 +341,7 @@ public class AdtPlugin extends AbstractUIPlugin {
// check the location of SDK
final boolean isSdkLocationValid = checkSdkLocationAndId();
mBuildVerbosity = BuildPreferencePage.getBuildLevel(
mStore.getString(PREFS_BUILD_VERBOSITY));
@@ -356,7 +356,7 @@ public class AdtPlugin extends AbstractUIPlugin {
// and give it the debug launcher for android projects
DdmsPlugin.setRunningAppDebugLauncher(new DdmsPlugin.IDebugLauncher() {
public boolean debug(String appName, int port) {
// search for an android project matching the process name
// search for an android project matching the process name
IProject project = ProjectHelper.findAndroidProjectByAppName(appName);
if (project != null) {
AndroidLaunchController.debugRunningApp(project, port);
@@ -366,7 +366,7 @@ public class AdtPlugin extends AbstractUIPlugin {
}
}
});
StackTracePanel.setSourceRevealer(new ISourceRevealer() {
public void reveal(String applicationName, String className, int line) {
IProject project = ProjectHelper.findAndroidProjectByAppName(applicationName);
@@ -375,12 +375,12 @@ public class AdtPlugin extends AbstractUIPlugin {
}
}
});
// setup export callback for editors
ExportHelper.setCallback(new IExportCallback() {
public void startExportWizard(IProject project) {
StructuredSelection selection = new StructuredSelection(project);
ExportWizard wizard = new ExportWizard();
wizard.init(PlatformUI.getWorkbench(), selection);
WizardDialog dialog = new WizardDialog(getDisplay().getActiveShell(),
@@ -388,7 +388,7 @@ public class AdtPlugin extends AbstractUIPlugin {
dialog.open();
}
});
// initialize editors
startEditors();
@@ -400,16 +400,16 @@ public class AdtPlugin extends AbstractUIPlugin {
@Override
public void done(IJobChangeEvent event) {
super.done(event);
// Once the ping job is finished, start the SDK parser
if (isSdkLocationValid) {
// parse the SDK resources.
parseSdkContent();
}
}
}
});
// build jobs are run after other interactive jobs
pingJob.setPriority(Job.BUILD);
pingJob.setPriority(Job.BUILD);
// Wait 2 seconds before starting the ping job. This leaves some time to the
// other bundles to initialize.
pingJob.schedule(2000 /*milliseconds*/);
@@ -417,15 +417,15 @@ public class AdtPlugin extends AbstractUIPlugin {
/*
* (non-Javadoc)
*
*
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
@Override
public void stop(BundleContext context) throws Exception {
super.stop(context);
stopEditors();
mRed.dispose();
synchronized (AdtPlugin.class) {
sPlugin = null;
@@ -525,7 +525,7 @@ public class AdtPlugin extends AbstractUIPlugin {
if (sPlugin != null) {
return sPlugin.mBuildVerbosity;
}
return 0;
}
@@ -537,7 +537,7 @@ public class AdtPlugin extends AbstractUIPlugin {
* @return the image descriptor
*/
public static ImageDescriptor getImageDescriptor(String path) {
return imageDescriptorFromPlugin(PLUGIN_ID, path);
return imageDescriptorFromPlugin(PLUGIN_ID, path);
}
/**
@@ -555,7 +555,7 @@ public class AdtPlugin extends AbstractUIPlugin {
return null;
}
}
// attempt to get a file to one of the template.
try {
URL url = bundle.getEntry(AndroidConstants.WS_SEP + filepath);
@@ -683,10 +683,10 @@ public class AdtPlugin extends AbstractUIPlugin {
});
return result[0];
}
/**
* Logs a message to the default Eclipse log.
*
*
* @param severity The severity code. Valid values are: {@link IStatus#OK},
* {@link IStatus#ERROR}, {@link IStatus#INFO}, {@link IStatus#WARNING} or
* {@link IStatus#CANCEL}.
@@ -704,7 +704,7 @@ public class AdtPlugin extends AbstractUIPlugin {
* Logs an exception to the default Eclipse log.
* <p/>
* The status severity is always set to ERROR.
*
*
* @param exception the exception to log.
* @param format The format string, like for {@link String#format(String, Object...)}.
* @param args The arguments for the format string, like for
@@ -715,13 +715,13 @@ public class AdtPlugin extends AbstractUIPlugin {
Status status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
getDefault().getLog().log(status);
}
/**
* This is a mix between log(Throwable) and printErrorToConsole.
* <p/>
* This logs the exception with an ERROR severity and the given printf-like format message.
* The same message is then printed on the Android error console with the associated tag.
*
*
* @param exception the exception to log.
* @param format The format string, like for {@link String#format(String, Object...)}.
* @param args The arguments for the format string, like for
@@ -733,7 +733,7 @@ public class AdtPlugin extends AbstractUIPlugin {
String message = String.format(format, args);
Status status = new Status(IStatus.ERROR, PLUGIN_ID, message, exception);
getDefault().getLog().log(status);
StreamHelper.printToStream(sPlugin.mAndroidConsoleErrorStream, tag, message);
printToStream(sPlugin.mAndroidConsoleErrorStream, tag, message);
showAndroidConsole();
}
}
@@ -745,8 +745,8 @@ public class AdtPlugin extends AbstractUIPlugin {
*/
public static synchronized void printErrorToConsole(String tag, Object... objects) {
if (sPlugin != null) {
StreamHelper.printToStream(sPlugin.mAndroidConsoleErrorStream, tag, objects);
printToStream(sPlugin.mAndroidConsoleErrorStream, tag, objects);
showAndroidConsole();
}
}
@@ -783,7 +783,7 @@ public class AdtPlugin extends AbstractUIPlugin {
if (sPlugin != null) {
if (level <= sPlugin.mBuildVerbosity) {
String tag = project != null ? project.getName() : null;
StreamHelper.printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
}
}
}
@@ -795,7 +795,7 @@ public class AdtPlugin extends AbstractUIPlugin {
*/
public static synchronized void printToConsole(String tag, Object... objects) {
if (sPlugin != null) {
StreamHelper.printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
printToStream(sPlugin.mAndroidConsoleStream, tag, objects);
}
}
@@ -813,7 +813,7 @@ public class AdtPlugin extends AbstractUIPlugin {
public static void showAndroidConsole() {
// first make sure the console is in the workbench
EclipseUiHelper.showView(IConsoleConstants.ID_CONSOLE_VIEW, true);
// now make sure it's not docked.
ConsolePlugin.getDefault().getConsoleManager().showConsoleView(
AdtPlugin.getDefault().getAndroidConsole());
@@ -832,7 +832,7 @@ public class AdtPlugin extends AbstractUIPlugin {
if (sPlugin != null) {
return new AndroidPrintStream(project, prefix, sPlugin.mAndroidConsoleStream);
}
return null;
}
@@ -849,10 +849,10 @@ public class AdtPlugin extends AbstractUIPlugin {
if (sPlugin != null) {
return new AndroidPrintStream(project, prefix, sPlugin.mAndroidConsoleErrorStream);
}
return null;
}
/**
* Returns whether the Sdk has been loaded.
*/
@@ -861,7 +861,7 @@ public class AdtPlugin extends AbstractUIPlugin {
return mSdkIsLoaded;
}
}
/**
* Returns the lock object for SDK loading. If you wish to do things while the SDK is loading,
* you must synchronize on this object.
@@ -869,7 +869,7 @@ public class AdtPlugin extends AbstractUIPlugin {
public final Object getSdkLockObject() {
return mPostLoadProjectsToResolve;
}
/**
* Sets the given {@link IJavaProject} to have its target resolved again once the SDK finishes
* to load.
@@ -879,14 +879,14 @@ public class AdtPlugin extends AbstractUIPlugin {
mPostLoadProjectsToResolve.add(javaProject);
}
}
/**
* Sets the given {@link IJavaProject} to have its target checked for consistency
* once the SDK finishes to load. This is used if the target is resolved using cached
* information while the SDK is loading.
*/
public final void setProjectToCheck(IJavaProject javaProject) {
// only lock on
// only lock on
synchronized (getSdkLockObject()) {
mPostLoadProjectsToCheck.add(javaProject);
}
@@ -983,25 +983,19 @@ public class AdtPlugin extends AbstractUIPlugin {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
pingUsageServer(); //$NON-NLS-1$
// get the version of the plugin
String versionString = (String) getBundle().getHeaders().get(
Constants.BUNDLE_VERSION);
Version version = new Version(versionString);
SdkStatsHelper.pingUsageServer("adt", version); //$NON-NLS-1$
return Status.OK_STATUS;
} catch (Throwable t) {
log(t, "pingUsageServer failed"); //$NON-NLS-1$
log(t, "pingUsageServer failed"); //$NON-NLS-1$
return new Status(IStatus.ERROR, PLUGIN_ID,
"pingUsageServer failed", t);
"pingUsageServer failed", t); //$NON-NLS-1$
}
}
};
return job;
}
/**
* Parses the SDK resources.
*/
@@ -1018,18 +1012,18 @@ public class AdtPlugin extends AbstractUIPlugin {
return new Status(IStatus.WARNING, PLUGIN_ID,
"An Android SDK is already being loaded. Please try again later.");
}
mSdkIsLoading = true;
SubMonitor progress = SubMonitor.convert(monitor,
"Initialize SDK Manager", 100);
Sdk sdk = Sdk.loadSdk(mOsSdkLocation);
if (sdk != null) {
progress.setTaskName(Messages.AdtPlugin_Parsing_Resources);
int n = sdk.getTargets().length;
if (n > 0) {
int w = 60 / n;
@@ -1050,7 +1044,7 @@ public class AdtPlugin extends AbstractUIPlugin {
mSdkIsLoaded = LoadStatus.LOADED;
progress.setTaskName("Check Projects");
ArrayList<IJavaProject> list = new ArrayList<IJavaProject>();
for (IJavaProject javaProject : mPostLoadProjectsToResolve) {
if (javaProject.getProject().isOpen()) {
@@ -1066,24 +1060,24 @@ public class AdtPlugin extends AbstractUIPlugin {
// do not need to be resolved again).
AndroidClasspathContainerInitializer.checkProjectsCache(
mPostLoadProjectsToCheck);
list.addAll(mPostLoadProjectsToCheck);
// update the project that needs recompiling.
if (list.size() > 0) {
IJavaProject[] array = list.toArray(
new IJavaProject[list.size()]);
AndroidClasspathContainerInitializer.updateProjects(array);
}
progress.worked(10);
}
}
// Notify resource changed listeners
progress.setTaskName("Refresh UI");
progress.setWorkRemaining(mTargetChangeListeners.size());
// Clone the list before iterating, to avoid Concurrent Modification
// exceptions
final List<ITargetChangeListener> listeners =
@@ -1102,6 +1096,11 @@ public class AdtPlugin extends AbstractUIPlugin {
}
}
});
} catch (Throwable t) {
log(t, "Unknown exception in parseSdkContent."); //$NON-NLS-1$
return new Status(IStatus.ERROR, PLUGIN_ID,
"parseSdkContent failed", t); //$NON-NLS-1$
} finally {
mSdkIsLoading = false;
if (monitor != null) {
@@ -1115,34 +1114,18 @@ public class AdtPlugin extends AbstractUIPlugin {
job.setPriority(Job.BUILD); // build jobs are run after other interactive jobs
job.schedule();
}
/** Returns the global android console */
public MessageConsole getAndroidConsole() {
return mAndroidConsole;
}
// ----- Methods for Editors -------
public void startEditors() {
sAndroidLogoDesc = imageDescriptorFromPlugin(AdtPlugin.PLUGIN_ID,
"/icons/android.png"); //$NON-NLS-1$
sAndroidLogo = sAndroidLogoDesc.createImage();
// get the stream to write in the android console.
MessageConsole androidConsole = AdtPlugin.getDefault().getAndroidConsole();
mAndroidConsoleStream = androidConsole.newMessageStream();
mAndroidConsoleErrorStream = androidConsole.newMessageStream();
mRed = new Color(getDisplay(), 0xFF, 0x00, 0x00);
// because this can be run, in some cases, by a non ui thread, and beccause
// changing the console properties update the ui, we need to make this change
// in the ui thread.
getDisplay().asyncExec(new Runnable() {
public void run() {
mAndroidConsoleErrorStream.setColor(mRed);
}
});
// Add a resource listener to handle compiled resources.
IWorkspace ws = ResourcesPlugin.getWorkspace();
@@ -1160,19 +1143,19 @@ public class AdtPlugin extends AbstractUIPlugin {
/**
* The <code>AbstractUIPlugin</code> implementation of this <code>Plugin</code>
* method saves this plug-in's preference and dialog stores and shuts down
* method saves this plug-in's preference and dialog stores and shuts down
* its image registry (if they are in use). Subclasses may extend this
* method, but must send super <b>last</b>. A try-finally statement should
* be used where necessary to ensure that <code>super.shutdown()</code> is
* always done.
*
*
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
*/
public void stopEditors() {
sAndroidLogo.dispose();
IconFactory.getInstance().Dispose();
// Remove the resource listener that handles compiled resources.
IWorkspace ws = ResourcesPlugin.getWorkspace();
ResourceMonitor.stopMonitoring(ws);
@@ -1182,7 +1165,7 @@ public class AdtPlugin extends AbstractUIPlugin {
/**
* Returns an Image for the small Android logo.
*
*
* Callers should not dispose it.
*/
public static Image getAndroidLogo() {
@@ -1191,13 +1174,13 @@ public class AdtPlugin extends AbstractUIPlugin {
/**
* Returns an {@link ImageDescriptor} for the small Android logo.
*
*
* Callers should not dispose it.
*/
public static ImageDescriptor getAndroidLogoDesc() {
return sAndroidLogoDesc;
}
/**
* Returns the ResourceMonitor object.
*/
@@ -1207,23 +1190,23 @@ public class AdtPlugin extends AbstractUIPlugin {
/**
* Sets up the editor to register default editors for resource files when needed.
*
*
* This is called by the {@link AdtPlugin} during initialization.
*
*
* @param monitor The main Resource Monitor object.
*/
public void setupDefaultEditor(ResourceMonitor monitor) {
monitor.addFileListener(new IFileListener() {
private static final String UNKNOWN_EDITOR = "unknown-editor"; //$NON-NLS-1$
/* (non-Javadoc)
* Sent when a file changed.
* @param file The file that changed.
* @param markerDeltas The marker deltas for the file.
* @param kind The change kind. This is equivalent to
* {@link IResourceDelta#accept(IResourceDeltaVisitor)}
*
*
* @see IFileListener#fileChanged
*/
public void fileChanged(IFile file, IMarkerDelta[] markerDeltas, int kind) {
@@ -1233,7 +1216,7 @@ public class AdtPlugin extends AbstractUIPlugin {
// There is no support for sub folders, so the segment count must be 4
if (file.getFullPath().segmentCount() == 4) {
// check if we are inside the res folder.
String segment = file.getFullPath().segment(1);
String segment = file.getFullPath().segment(1);
if (segment.equalsIgnoreCase(SdkConstants.FD_RESOURCES)) {
// we are inside a res/ folder, get the actual ResourceFolder
ProjectResources resources = ResourceManager.getInstance().
@@ -1252,7 +1235,7 @@ public class AdtPlugin extends AbstractUIPlugin {
ResourceFolder resFolder = resources.getResourceFolder(
(IFolder)file.getParent());
if (resFolder != null) {
if (kind == IResourceDelta.ADDED) {
resourceAdded(file, resFolder.getType());
@@ -1320,7 +1303,7 @@ public class AdtPlugin extends AbstractUIPlugin {
file.setPersistentProperty(qname, null);
IWorkbenchPage page = PlatformUI.getWorkbench().
getActiveWorkbenchWindow().getActivePage();
IEditorPart oldEditor = page.findEditor(new FileEditorInput(file));
if (oldEditor != null &&
AdtPlugin.displayPrompt("Android XML Editor",
@@ -1332,7 +1315,7 @@ public class AdtPlugin extends AbstractUIPlugin {
XmlEditor.ID,
true, /* activate */
IWorkbenchPage.MATCH_NONE);
if (newEditor != null) {
page.closeEditor(oldEditor, true /* save */);
}
@@ -1385,8 +1368,60 @@ public class AdtPlugin extends AbstractUIPlugin {
}
});
}
public static synchronized OutputStream getErrorStream() {
return sPlugin.mAndroidConsoleErrorStream;
}
/**
* Pings the usage start server.
*/
private void pingUsageServer() {
// get the version of the plugin
String versionString = (String) getBundle().getHeaders().get(
Constants.BUNDLE_VERSION);
Version version = new Version(versionString);
versionString = String.format("%1$d.%2$d.%3$d", version.getMajor(), //$NON-NLS-1$
version.getMinor(), version.getMicro());
SdkStatsService.ping("adt", versionString, getDisplay()); //$NON-NLS-1$
}
/**
* Prints messages, associated with a project to the specified stream
* @param stream The stream to write to
* @param tag The tag associated to the message. Can be null
* @param objects The objects to print through their toString() method (or directly for
* {@link String} objects.
*/
public static synchronized void printToStream(MessageConsoleStream stream, String tag,
Object... objects) {
String dateTag = getMessageTag(tag);
for (Object obj : objects) {
stream.print(dateTag);
if (obj instanceof String) {
stream.println((String)obj);
} else {
stream.println(obj.toString());
}
}
}
/**
* Creates a string containing the current date/time, and the tag
* @param tag The tag associated to the message. Can be null
* @return The dateTag
*/
public static String getMessageTag(String tag) {
Calendar c = Calendar.getInstance();
if (tag == null) {
return String.format(Messages.Console_Date_Tag, c);
}
return String.format(Messages.Console_Data_Project_Tag, c, tag);
}
}

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.ide.eclipse.common;
package com.android.ide.eclipse.adt;
import com.android.sdklib.SdkConstants;
@@ -90,7 +90,7 @@ public class AndroidConstants {
/** Name of the android sources directory */
public static final String FD_ANDROID_SOURCES = "sources"; //$NON-NLS-1$
/** Resource java class filename, i.e. "R.java" */
public final static String FN_RESOURCE_CLASS = "R.java"; //$NON-NLS-1$
/** Resource class file filename, i.e. "R.class" */
@@ -104,15 +104,11 @@ public class AndroidConstants {
/** Temporary packaged resources file name for a specific set of configuration */
public final static String FN_RESOURCES_S_AP_ = "resources-%s.ap_"; //$NON-NLS-1$
public final static Pattern PATTERN_RESOURCES_S_AP_ =
Pattern.compile("resources-.*\\.ap_", Pattern.CASE_INSENSITIVE);
Pattern.compile("resources-.*\\.ap_", Pattern.CASE_INSENSITIVE); //$NON-NLS-1$
public final static String FN_ADB =
(SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
"adb.exe" : "adb"; //$NON-NLS-1$ //$NON-NLS-2$
public final static String FN_ADB = SdkConstants.FN_ADB;
public final static String FN_EMULATOR =
(SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
"emulator.exe" : "emulator"; //$NON-NLS-1$ //$NON-NLS-2$
public final static String FN_EMULATOR = SdkConstants.FN_EMULATOR;
public final static String FN_TRACEVIEW =
(SdkConstants.CURRENT_PLATFORM == SdkConstants.PLATFORM_WINDOWS) ?
@@ -128,8 +124,8 @@ public class AndroidConstants {
public final static String WS_ASSETS = WS_SEP + SdkConstants.FD_ASSETS;
/** Leaf of the javaDoc folder. Does not start with a separator. */
public final static String WS_JAVADOC_FOLDER_LEAF = SdkConstants.FD_DOCS + "/" +
SdkConstants.FD_DOCS_REFERENCE; //$NON-NLS-1$
public final static String WS_JAVADOC_FOLDER_LEAF = SdkConstants.FD_DOCS + "/" + //$NON-NLS-1$
SdkConstants.FD_DOCS_REFERENCE;
/** Path of the samples directory relative to the sdk folder.
* This is an OS path, ending with a separator.
@@ -159,10 +155,10 @@ public class AndroidConstants {
/** aidl marker error. */
public final static String MARKER_AIDL = COMMON_PLUGIN_ID + ".aidlProblem"; //$NON-NLS-1$
/** android marker error */
public final static String MARKER_ANDROID = COMMON_PLUGIN_ID + ".androidProblem"; //$NON-NLS-1$
/** Name for the "type" marker attribute */
public final static String MARKER_ATTR_TYPE = "android.type"; //$NON-NLS-1$
/** Name for the "class" marker attribute */
@@ -176,9 +172,9 @@ public class AndroidConstants {
/** provider value for marker attribute "type" */
public final static String MARKER_ATTR_TYPE_PROVIDER = "provider"; //$NON-NLS-1$
public final static String CLASS_ACTIVITY = "android.app.Activity"; //$NON-NLS-1$
public final static String CLASS_SERVICE = "android.app.Service"; //$NON-NLS-1$
public final static String CLASS_BROADCASTRECEIVER = "android.content.BroadcastReceiver"; //$NON-NLS-1$
public final static String CLASS_ACTIVITY = "android.app.Activity"; //$NON-NLS-1$
public final static String CLASS_SERVICE = "android.app.Service"; //$NON-NLS-1$
public final static String CLASS_BROADCASTRECEIVER = "android.content.BroadcastReceiver"; //$NON-NLS-1$
public final static String CLASS_CONTENTPROVIDER = "android.content.ContentProvider"; //$NON-NLS-1$
public final static String CLASS_INSTRUMENTATION = "android.app.Instrumentation"; //$NON-NLS-1$
public final static String CLASS_INSTRUMENTATION_RUNNER =
@@ -202,7 +198,7 @@ public class AndroidConstants {
"android.preference." + CLASS_NAME_PREFERENCE_SCREEN; //$NON-NLS-1$
public final static String CLASS_PREFERENCEGROUP = "android.preference.PreferenceGroup"; //$NON-NLS-1$
public final static String CLASS_PARCELABLE = "android.os.Parcelable"; //$NON-NLS-1$
public final static String CLASS_BRIDGE = "com.android.layoutlib.bridge.Bridge"; //$NON-NLS-1$
/**
@@ -219,6 +215,6 @@ public class AndroidConstants {
/** The base URL where to find the Android class & manifest documentation */
public static final String CODESITE_BASE_URL = "http://code.google.com/android"; //$NON-NLS-1$
public static final String LIBRARY_TEST_RUNNER = "android.test.runner"; // $NON-NLS-1$
}

View File

@@ -16,6 +16,10 @@ public class Messages extends NLS {
public static String AdtPlugin_Parsing_Resources;
public static String Console_Data_Project_Tag;
public static String Console_Date_Tag;
public static String Could_Not_Find;
public static String Could_Not_Find_Folder;

View File

@@ -14,8 +14,10 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt;
package com.android.ide.eclipse.adt.internal;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.Messages;
import com.android.ide.eclipse.adt.AdtPlugin.CheckSdkErrorHandler;
import com.android.sdklib.SdkConstants;
@@ -32,7 +34,7 @@ import java.util.regex.Pattern;
/**
* Class handling the version check for the plugin vs. the SDK.<br>
* The plugin must be able to support all version of the SDK.
*
*
* <p/>An SDK can require a new version of the plugin.
* <p/>The SDK contains a file with the minimum version for the plugin. This file is inside the
* <code>tools/lib</code> directory, and is called <code>plugin.prop</code>.<br>
@@ -40,7 +42,7 @@ import java.util.regex.Pattern;
* against the current plugin version.<br>
*
*/
final class VersionCheck {
public final class VersionCheck {
/**
* Pattern to get the minimum plugin version supported by the SDK. This is read from
* the file <code>$SDK/tools/lib/plugin.prop</code>.

View File

@@ -14,10 +14,11 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt.project;
package com.android.ide.eclipse.adt.internal.actions;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;

View File

@@ -14,7 +14,10 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt.project;
package com.android.ide.eclipse.adt.internal.actions;
import com.android.ide.eclipse.adt.internal.project.AndroidNature;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt.build;
package com.android.ide.eclipse.adt.internal.build;
import com.android.ide.eclipse.adt.build.BaseBuilder.BaseDeltaVisitor;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.build.BaseBuilder.BaseDeltaVisitor;
import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IFile;

View File

@@ -14,16 +14,16 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt.build;
package com.android.ide.eclipse.adt.internal.build;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.adt.sdk.LoadStatus;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.common.project.XmlErrorHandler;
import com.android.ide.eclipse.common.project.XmlErrorHandler.XmlErrorListener;
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.XmlErrorListener;
import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
@@ -146,7 +146,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
*/
private final static Pattern sPattern7Line1 = Pattern.compile(
"^ERROR:\\s+9-patch\\s+image\\s+(.+)\\s+malformed\\.$"); //$NON-NLS-1$
private final static Pattern sPattern8Line1 = Pattern.compile(
"^(invalid resource directory name): (.*)$"); //$NON-NLS-1$
@@ -179,7 +179,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
public BaseDeltaVisitor(BaseBuilder builder) {
mBuilder = builder;
}
/**
* Finds a matching Source folder for the current path. This checkds if the current path
* leads to, or is a source folder.
@@ -189,18 +189,18 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
*/
protected static String[] findMatchingSourceFolder(ArrayList<IPath> sourceFolders,
String[] pathSegments) {
for (IPath p : sourceFolders) {
// check if we are inside one of those source class path
// get the segments
String[] srcSegments = p.segments();
// compare segments. We want the path of the resource
// we're visiting to be
boolean valid = true;
int segmentCount = pathSegments.length;
for (int i = 0 ; i < segmentCount; i++) {
String s1 = pathSegments[i];
String s2 = srcSegments[i];
@@ -210,7 +210,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
break;
}
}
if (valid) {
// this folder, or one of this children is a source
// folder!
@@ -218,7 +218,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
return srcSegments;
}
}
return null;
}
@@ -278,7 +278,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
/**
* Adds a marker to the current project.
*
*
* @param markerId The id of the marker to add.
* @param message the message associated with the mark
* @param severity the severity of the marker.
@@ -350,9 +350,9 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
protected final int grabProcessOutput(final Process process,
final ArrayList<String> results)
throws InterruptedException {
// Due to the limited buffer size on windows for the standard io (stderr, stdout), we
// *need* to read both stdout and stderr all the time. If we don't and a process output
// a large amount, this could deadlock the process.
// Due to the limited buffer size on windows for the standard io (stderr, stdout), we
// *need* to read both stdout and stderr all the time. If we don't and a process output
// a large amount, this could deadlock the process.
// read the lines as they come. if null is returned, it's
// because the process finished
@@ -576,7 +576,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
// success, go to the next line
continue;
}
m = sPattern8Line1.matcher(p);
if (m.matches()) {
String location = m.group(2);
@@ -596,7 +596,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
if (m.matches()) {
String badConfig = m.group(1);
String msg = String.format("APK Configuration filter '%1$s' is invalid", badConfig);
// skip the next line
i++;
@@ -825,7 +825,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
// get a java project from it
IJavaProject javaProject = JavaCore.create(project);
IWorkspaceRoot wsRoot = ResourcesPlugin.getWorkspace().getRoot();
ArrayList<String> oslibraryList = new ArrayList<String>();
@@ -836,7 +836,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
// if this is a classpath variable reference, we resolve it.
if (e.getEntryKind() == IClasspathEntry.CPE_VARIABLE) {
e = JavaCore.getResolvedClasspathEntry(e);
e = JavaCore.getResolvedClasspathEntry(e);
}
// get the IPath
@@ -878,15 +878,15 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
return oslibraryList.toArray(new String[oslibraryList.size()]);
}
/**
* Aborts the build if the SDK/project setups are broken. This does not
* display any errors.
*
*
* @param project The {@link IJavaProject} being compiled.
* @throws CoreException
*/
protected final void abortOnBadSetup(IProject project) throws CoreException {
protected void abortOnBadSetup(IProject project) throws CoreException {
// check if we have finished loading the SDK.
if (AdtPlugin.getDefault().getSdkLoadStatus() != LoadStatus.LOADED) {
// we exit silently
@@ -896,22 +896,22 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
// abort if there are TARGET or ADT type markers
IMarker[] markers = project.findMarkers(AdtConstants.MARKER_TARGET,
false /*includeSubtypes*/, IResource.DEPTH_ZERO);
if (markers.length > 0) {
stopBuild("");
}
markers = project.findMarkers(AdtConstants.MARKER_ADT, false /*includeSubtypes*/,
IResource.DEPTH_ZERO);
if (markers.length > 0) {
stopBuild("");
}
}
/**
* Throws an exception to cancel the build.
*
*
* @param error the error message
* @param args the printf-style arguments to the error message.
* @throws CoreException
@@ -920,7 +920,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder {
throw new CoreException(new Status(IStatus.CANCEL, AdtPlugin.PLUGIN_ID,
String.format(error, args)));
}
/**
* Recursively delete all the derived resources.
*/

View File

@@ -1,10 +1,10 @@
package com.android.ide.eclipse.adt.build;
package com.android.ide.eclipse.adt.internal.build;
import org.eclipse.osgi.util.NLS;
public class Messages extends NLS {
private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.build.build_messages"; //$NON-NLS-1$
private static final String BUNDLE_NAME = "com.android.ide.eclipse.adt.internal.build.build_messages"; //$NON-NLS-1$
public static String AAPT_Error;

View File

@@ -14,16 +14,16 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt.build;
package com.android.ide.eclipse.adt.internal.build;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.project.FixLaunchConfig;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.common.project.XmlErrorHandler.BasicXmlErrorListener;
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.FixLaunchConfig;
import com.android.ide.eclipse.adt.internal.project.XmlErrorHandler.BasicXmlErrorListener;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;
@@ -271,8 +271,7 @@ public class PreCompilerBuilder extends BaseBuilder {
// if there was some XML errors, we just return w/o doing
// anything since we've put some markers in the files anyway.
if (dv != null && dv.mXmlError) {
AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project,
Messages.Xml_Error);
AdtPlugin.printErrorToConsole(project, Messages.Xml_Error);
// This interrupts the build. The next builders will not run.
stopBuild(Messages.Xml_Error);

View File

@@ -14,15 +14,15 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt.build;
package com.android.ide.eclipse.adt.internal.build;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.build.BaseBuilder.BaseDeltaVisitor;
import com.android.ide.eclipse.adt.build.PreCompilerBuilder.AidlData;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.AndroidManifestParser;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.build.BaseBuilder.BaseDeltaVisitor;
import com.android.ide.eclipse.adt.internal.build.PreCompilerBuilder.AidlData;
import com.android.ide.eclipse.adt.internal.project.AndroidManifestParser;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IContainer;

View File

@@ -14,14 +14,14 @@
* limitations under the License.
*/
package com.android.ide.eclipse.adt.build;
package com.android.ide.eclipse.adt.internal.build;
import com.android.ide.eclipse.adt.AdtConstants;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.project.ProjectHelper;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.project.BaseProjectHelper;
import com.android.ide.eclipse.adt.internal.project.ProjectHelper;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.SdkConstants;

View File

@@ -14,22 +14,24 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors;
package com.android.ide.eclipse.adt.internal.editors;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.TextValueDescriptor;
import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiFlagAttributeNode;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.internal.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.adt.internal.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.IDescriptorProvider;
import com.android.ide.eclipse.adt.internal.editors.descriptors.SeparatorAttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.TextAttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.TextValueDescriptor;
import com.android.ide.eclipse.adt.internal.editors.descriptors.XmlnsAttributeDescriptor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiFlagAttributeNode;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.sdklib.SdkConstants;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.ITextViewer;
@@ -74,7 +76,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
/** Regexp to detect an element tag name */
private static Pattern sFirstElementWord = Pattern.compile("^[a-zA-Z0-9_:]+"); //$NON-NLS-1$
/** Regexp to detect whitespace */
private static Pattern sWhitespace = Pattern.compile("\\s+"); //$NON-NLS-1$
@@ -86,11 +88,11 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
private ElementDescriptor mRootDescriptor;
private final int mDescriptorId;
private AndroidEditor mEditor;
/**
* Constructor for AndroidContentAssist
* Constructor for AndroidContentAssist
* @param descriptorId An id for {@link AndroidTargetData#getDescriptorProvider(int)}.
* The Id can be one of {@link AndroidTargetData#DESCRIPTOR_MANIFEST},
* {@link AndroidTargetData#DESCRIPTOR_LAYOUT},
@@ -110,17 +112,22 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
* @param viewer the viewer whose document is used to compute the proposals
* @param offset an offset within the document for which completions should be computed
* @return an array of completion proposals or <code>null</code> if no proposals are possible
*
*
* @see org.eclipse.jface.text.contentassist.IContentAssistProcessor#computeCompletionProposals(org.eclipse.jface.text.ITextViewer, int)
*/
public ICompletionProposal[] computeCompletionProposals(ITextViewer viewer, int offset) {
if (mEditor == null) {
mEditor = getAndroidEditor(viewer);
if (mEditor == null) {
// This should not happen. Duck and forget.
AdtPlugin.log(IStatus.ERROR, "Editor not found during completion");
return null;
}
}
UiElementNode rootUiNode = mEditor.getUiRootNode();
Object[] choices = null; /* An array of ElementDescriptor, or AttributeDescriptor
or String or null */
String parent = ""; //$NON-NLS-1$
@@ -136,7 +143,12 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
// check to see if we can find a UiElementNode matching this XML node
UiElementNode currentUiNode =
rootUiNode == null ? null : rootUiNode.findXmlNode(currentNode);
if (currentNode == null) {
// Should not happen (an XML doc always has at least a doc node). Just give up.
return null;
}
if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
parent = currentNode.getNodeName();
@@ -154,7 +166,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
// We're editing attributes in an element node (either the attributes' names
// or their values).
choices = getChoicesForAttribute(parent, currentNode, currentUiNode, info);
if (info.correctedPrefix != null) {
wordPrefix = info.correctedPrefix;
}
@@ -180,7 +192,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
needTag = '<';
}
}
// get the selection length
int selectionLength = 0;
ISelection selection = viewer.getSelectionProvider().getSelection();
@@ -196,7 +208,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
/**
* Returns the namespace prefix matching the Android Resource URI.
* If no such declaration is found, returns the default "android" prefix.
*
*
* @param node The current node. Must not be null.
* @param nsUri The namespace URI of which the prefix is to be found,
* e.g. {@link SdkConstants#NS_RESOURCES}
@@ -210,9 +222,9 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
if (XmlnsAttributeDescriptor.XMLNS_URI.equals(nsUri)) {
return "xmlns"; //$NON-NLS-1$
}
HashSet<String> visited = new HashSet<String>();
String prefix = null;
for (; prefix == null &&
node != null &&
@@ -230,7 +242,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
}
}
}
// Use a sensible default prefix if we can't find one.
// We need to make sure the prefix is not one that was declared in the scope
// visited above.
@@ -251,7 +263,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
* <p/>
* Example: <manifest><applic*cursor* => returns the list of all elements that
* can be found under <manifest>, of which <application> is one of the choices.
*
*
* @return an ElementDescriptor[] or null if no valid element was found.
*/
private Object[] getChoicesForElement(String parent, Node current_node) {
@@ -287,8 +299,8 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
* lenient as suitable for attribute values.
* - AttribInfo.needTag will be non-zero if we find that the attribute completion proposal
* must be double-quoted.
* @param currentUiNode
*
* @param currentUiNode
*
* @return an AttributeDescriptor[] if the user is editing an attribute name.
* a String[] if the user is editing an attribute value with some known values,
* or null if nothing is known about the context.
@@ -309,7 +321,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
} else {
attrInfo.needTag = '"';
}
if (currentUiNode != null) {
// look for an UI attribute matching the current attribute name
String attrName = attrInfo.name;
@@ -329,7 +341,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
if (currAttrNode != null) {
choices = currAttrNode.getPossibleValues(value);
if (currAttrNode instanceof UiFlagAttributeNode) {
// A "flag" can consist of several values separated by "or" (|).
// If the correct prefix contains such a pipe character, we change
@@ -345,7 +357,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
if (choices == null) {
// fallback on the older descriptor-only based lookup.
// in order to properly handle the special case of the name attribute in
// the action tag, we need the grandparent of the action node, to know
// what type of actions we need.
@@ -358,7 +370,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
greatGrandParentName = greatGrandParent.getLocalName();
}
}
AndroidTargetData data = mEditor.getTargetData();
if (data != null) {
choices = data.getAttributeValues(parent, attrInfo.name, greatGrandParentName);
@@ -382,7 +394,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
* This means the user is editing outside of any XML element or attribute.
* Simply return the list of XML elements that can be present there, based on the
* parent of the current node.
*
*
* @return An ElementDescriptor[] or null.
*/
private Object[] getChoicesForTextNode(Node currentNode) {
@@ -413,7 +425,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
* - AttributeDescriptor: a possible attribute descriptor which XML name should be completed.
* - String: string values to display as-is to the user. Typically those are possible
* values for a given attribute.
*
*
* @return The ICompletionProposal[] to display to the user.
*/
private ICompletionProposal[] computeProposals(int offset, Node currentNode,
@@ -421,7 +433,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
boolean is_attribute, int selectionLength) {
ArrayList<CompletionProposal> proposals = new ArrayList<CompletionProposal>();
HashMap<String, String> nsUriMap = new HashMap<String, String>();
for (Object choice : choices) {
String keyword = null;
String nsPrefix = null;
@@ -441,7 +453,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
if (choice instanceof TextAttributeDescriptor) {
tooltip = ((TextAttributeDescriptor) choice).getTooltip();
}
// Get the namespace URI for the attribute. Note that some attributes
// do not have a namespace and thus return null here.
String nsUri = ((AttributeDescriptor)choice).getNamespaceUri();
@@ -455,13 +467,13 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
if (nsPrefix != null) {
nsPrefix += ":"; //$NON-NLS-1$
}
} else if (choice instanceof String) {
keyword = (String) choice;
} else {
continue; // discard unknown choice
}
String nsKeyword = nsPrefix == null ? keyword : (nsPrefix + keyword);
if (keyword.startsWith(wordPrefix) ||
@@ -499,7 +511,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
proposals.add(proposal);
}
}
return proposals.toArray(new ICompletionProposal[proposals.size()]);
}
@@ -510,7 +522,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
* <p/>
* Elements can have children if the descriptor has children element descriptors
* or if one of the attributes is a TextValueDescriptor.
*
*
* @param descriptor An ElementDescriptor or an AttributeDescriptor
* @return True if the descriptor is an ElementDescriptor that can have children or a text value
*/
@@ -548,7 +560,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
/**
* Returns the characters which when entered by the user should
* automatically trigger the presentation of possible completions.
*
*
* In our case, we auto-activate on opening tags and attributes namespace.
*
* @return the auto activation characters for completion proposal or <code>null</code>
@@ -569,7 +581,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
public String getErrorMessage() {
return null;
}
/**
* Heuristically extracts the prefix used for determining template relevance
* from the viewer's document. The default implementation returns the String from
@@ -578,7 +590,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
*
* The part were we access the docment was extracted from
* org.eclipse.jface.text.templatesTemplateCompletionProcessor and adapted to our needs.
*
*
* @param viewer the viewer
* @param offset offset into document
* @return the prefix to consider
@@ -611,7 +623,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
return ""; //$NON-NLS-1$
}
}
/**
* Extracts the character at the given offset.
* Returns 0 if the offset is invalid.
@@ -676,7 +688,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
// text will contain the full string of the current element,
// i.e. whatever is after the "<" to the current cursor
String text = document.get(offset, n - offset);
// Normalize whitespace to single spaces
text = sWhitespace.matcher(text).replaceAll(" "); //$NON-NLS-1$
@@ -684,13 +696,13 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
// any whitespace. If there's nothing left, no attribute has been defined yet.
// Be sure to keep any whitespace after the initial word if any, as it matters.
text = sFirstElementWord.matcher(text).replaceFirst(""); //$NON-NLS-1$
// There MUST be space after the element name. If not, the cursor is still
// defining the element name.
if (!text.startsWith(" ")) { //$NON-NLS-1$
return null;
}
// Remove full attributes:
// Syntax:
// name = "..." quoted string with all but < and "
@@ -709,7 +721,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
// merged with the previous one.
// - string with an = sign, optionally followed by a quote (' or "): the user is
// writing the value of the attribute.
int pos_equal = text.indexOf('=');
int pos_equal = text.indexOf('=');
if (pos_equal == -1) {
info.isInValue = false;
info.name = text.trim();
@@ -749,7 +761,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
return node;
}
/**
* Computes (if needed) and returns the root descriptor.
*/
@@ -758,17 +770,17 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
AndroidTargetData data = mEditor.getTargetData();
if (data != null) {
IDescriptorProvider descriptorProvider = data.getDescriptorProvider(mDescriptorId);
if (descriptorProvider != null) {
mRootDescriptor = new ElementDescriptor("",
descriptorProvider.getRootElementDescriptors());
}
}
}
return mRootDescriptor;
}
/**
* Returns the active {@link AndroidEditor} matching this source viewer.
*/
@@ -789,7 +801,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
return null;
}
}

View File

@@ -14,13 +14,13 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors;
package com.android.ide.eclipse.adt.internal.editors;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
import com.android.sdklib.IAndroidTarget;
import org.eclipse.core.resources.IFile;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors;
package com.android.ide.eclipse.adt.internal.editors;
import org.eclipse.jface.text.IAutoEditStrategy;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors;
package com.android.ide.eclipse.adt.internal.editors;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;

View File

@@ -15,7 +15,7 @@
*/
package com.android.ide.eclipse.editors;
package com.android.ide.eclipse.adt.internal.editors;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.sdklib.SdkConstants;

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.sdklib.SdkConstants;
import org.eclipse.swt.graphics.Image;

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.uimodel.UiAbstractTextAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAbstractTextAttributeNode;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ILabelProviderListener;

View File

@@ -14,9 +14,9 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.uimodel.UiListAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
/**
* Describes a text attribute that can only contain boolean values.

View File

@@ -14,15 +14,15 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.resources.ResourceType;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo.Format;
import com.android.ide.eclipse.editors.layout.LayoutConstants;
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.AndroidConstants;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutConstants;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.resources.ResourceType;
import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo;
import com.android.ide.eclipse.adt.internal.resources.DeclareStyleableInfo.AttributeInfo.Format;
import com.android.sdklib.SdkConstants;
import org.eclipse.swt.graphics.Image;
@@ -57,7 +57,7 @@ public final class DescriptorsUtils {
public static final String MANIFEST_SDK_URL = "/reference/android/R.styleable.html#"; //$NON-NLS-1$
public static final String IMAGE_KEY = "image"; //$NON-NLS-1$
private static final String CODE = "$code"; //$NON-NLS-1$
private static final String LINK = "$link"; //$NON-NLS-1$
private static final String ELEM = "$elem"; //$NON-NLS-1$
@@ -72,7 +72,7 @@ public final class DescriptorsUtils {
/**
* Creates a new {@link TextAttributeDescriptor} instance for the given XML name,
* UI name and tooltip.
*
*
* @param xmlName The XML attribute name.
* @param uiName The UI attribute name.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
@@ -86,7 +86,7 @@ public final class DescriptorsUtils {
/**
* Add all {@link AttributeInfo} to the the array of {@link AttributeDescriptor}.
*
*
* @param attributes The list of {@link AttributeDescriptor} to append to
* @param elementXmlName Optional XML local name of the element to which attributes are
* being added. When not null, this is used to filter overrides.
@@ -120,7 +120,7 @@ public final class DescriptorsUtils {
/**
* Add an {@link AttributeInfo} to the the array of {@link AttributeDescriptor}.
*
*
* @param attributes The list of {@link AttributeDescriptor} to append to
* @param elementXmlName Optional XML local name of the element to which attributes are
* being added. When not null, this is used to filter overrides.
@@ -145,13 +145,13 @@ public final class DescriptorsUtils {
if (required) {
uiName += "*"; //$NON-NLS-1$
}
String tooltip = null;
String rawTooltip = info.getJavaDoc();
if (rawTooltip == null) {
rawTooltip = "";
}
String deprecated = info.getDeprecatedDoc();
if (deprecated != null) {
if (rawTooltip.length() > 0) {
@@ -172,7 +172,7 @@ public final class DescriptorsUtils {
if (flen > 0) {
// Fill the formats in a set for faster access
HashSet<Format> formats_set = new HashSet<Format>();
StringBuilder sb = new StringBuilder();
if (rawTooltip != null && rawTooltip.length() > 0) {
sb.append(rawTooltip);
@@ -220,7 +220,7 @@ public final class DescriptorsUtils {
overrideAttrLocalName = elements[elements.length - 1];
elements = elements[0].split(","); //$NON-NLS-1$
}
if (overrideAttrLocalName == null ||
!overrideAttrLocalName.equals(xmlLocalName)) {
continue;
@@ -236,7 +236,7 @@ public final class DescriptorsUtils {
}
}
}
if (!ok_element) {
continue;
}
@@ -247,7 +247,7 @@ public final class DescriptorsUtils {
// The override is instance of the class to create, which must
// have a constructor compatible with TextAttributeDescriptor.
@SuppressWarnings("unchecked") //$NON-NLS-1$
Class<? extends TextAttributeDescriptor> clazz =
Class<? extends TextAttributeDescriptor> clazz =
(Class<? extends TextAttributeDescriptor>) override;
Constructor<? extends TextAttributeDescriptor> cons;
cons = clazz.getConstructor(new Class<?>[] {
@@ -310,7 +310,7 @@ public final class DescriptorsUtils {
* Indicates the the given {@link AttributeInfo} already exists in the ArrayList of
* {@link AttributeDescriptor}. This test for the presence of a descriptor with the same
* XML name.
*
*
* @param attributes The list of {@link AttributeDescriptor} to compare to.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
* See {@link SdkConstants#NS_RESOURCES} for a common value.
@@ -370,9 +370,9 @@ public final class DescriptorsUtils {
buf.append(c);
}
}
name = buf.toString();
// Replace these acronyms by upper-case versions
// - (?<=^| ) means "if preceded by a space or beginning of string"
// - (?=$| ) means "if followed by a space or end of string"
@@ -381,11 +381,11 @@ public final class DescriptorsUtils {
return name;
}
/**
* Capitalizes the string, i.e. transforms the initial [a-z] into [A-Z].
* Returns the string unmodified if the first character is not [a-z].
*
*
* @param str The string to capitalize.
* @return The capitalized string
*/
@@ -393,7 +393,7 @@ public final class DescriptorsUtils {
if (str == null || str.length() < 1 || str.charAt(0) < 'a' || str.charAt(0) > 'z') {
return str;
}
StringBuilder sb = new StringBuilder();
sb.append((char)(str.charAt(0) + 'A' - 'a'));
sb.append(str.substring(1));
@@ -405,7 +405,7 @@ public final class DescriptorsUtils {
*/
public static String formatTooltip(String javadoc) {
ArrayList<String> spans = scanJavadoc(javadoc);
StringBuilder sb = new StringBuilder();
boolean needBreak = false;
@@ -430,7 +430,7 @@ public final class DescriptorsUtils {
if (text != null) {
text = text.trim();
}
// If there's no text, use the anchor if there's one
if (text == null || text.length() == 0) {
text = anchor;
@@ -441,12 +441,12 @@ public final class DescriptorsUtils {
// If we still have no text, use the base as text
text = base;
}
}
}
if (text != null) {
sb.append(text);
}
} else if (ELEM.equals(s)) {
s = spans.get(++i);
if (s != null) {
@@ -462,17 +462,17 @@ public final class DescriptorsUtils {
needBreak = false;
}
}
return sb.toString();
}
/**
* Formats the javadoc tooltip to be usable in a FormText.
* <p/>
* If the descriptor can provide an icon, the caller should provide
* elementsDescriptor.getIcon() as "image" to FormText, e.g.:
* <code>formText.setImage(IMAGE_KEY, elementsDescriptor.getIcon());</code>
*
*
* @param javadoc The javadoc to format. Cannot be null.
* @param elementDescriptor The element descriptor parent of the javadoc. Cannot be null.
* @param androidDocBaseUrl The base URL for the documentation. Cannot be null. Should be
@@ -488,9 +488,9 @@ public final class DescriptorsUtils {
if (sdkUrl != null && sdkUrl.startsWith(MANIFEST_SDK_URL)) {
fullSdkUrl = androidDocBaseUrl + sdkUrl;
}
StringBuilder sb = new StringBuilder();
Image icon = elementDescriptor.getIcon();
if (icon != null) {
sb.append("<form><li style=\"image\" value=\"" + //$NON-NLS-1$
@@ -516,7 +516,7 @@ public final class DescriptorsUtils {
String base = spans.get(++i);
String anchor = spans.get(++i);
String text = spans.get(++i);
if (base != null) {
base = base.trim();
}
@@ -526,7 +526,7 @@ public final class DescriptorsUtils {
if (text != null) {
text = text.trim();
}
// If there's no text, use the anchor if there's one
if (text == null || text.length() == 0) {
text = anchor;
@@ -560,7 +560,7 @@ public final class DescriptorsUtils {
// If we still have no text, use the base as text
text = base;
}
}
}
if (url != null && text != null) {
sb.append("<a href=\""); //$NON-NLS-1$
@@ -600,15 +600,15 @@ public final class DescriptorsUtils {
private static ArrayList<String> scanJavadoc(String javadoc) {
ArrayList<String> spans = new ArrayList<String>();
// Standardize all whitespace in the javadoc to single spaces.
if (javadoc != null) {
javadoc = javadoc.replaceAll("[ \t\f\r\n]+", " "); //$NON-NLS-1$ //$NON-NLS-2$
}
// Detects {@link <base>#<name> <text>} where all 3 are optional
Pattern p_link = Pattern.compile("\\{@link\\s+([^#\\}\\s]*)(?:#([^\\s\\}]*))?(?:\\s*([^\\}]*))?\\}(.*)"); //$NON-NLS-1$
// Detects <code>blah</code>
// Detects <code>blah</code>
Pattern p_code = Pattern.compile("<code>(.+?)</code>(.*)"); //$NON-NLS-1$
// Detects @blah@, used in hard-coded tooltip descriptors
Pattern p_elem = Pattern.compile("@([\\w -]+)@(.*)"); //$NON-NLS-1$
@@ -621,7 +621,7 @@ public final class DescriptorsUtils {
int currentLength = 0;
String text = null;
while(javadoc != null && javadoc.length() > 0) {
Matcher m;
String s = null;
@@ -665,7 +665,7 @@ public final class DescriptorsUtils {
}
if (s != null && s.length() > 0) {
s = cleanupJavadocHtml(s);
if (currentLength >= JAVADOC_BREAK_LENGTH) {
spans.add(BREAK);
currentLength = 0;
@@ -680,12 +680,12 @@ public final class DescriptorsUtils {
currentLength = 0;
s = s.substring(pos + 1);
}
spans.add(s);
currentLength += s.length();
}
}
return spans;
}
@@ -722,15 +722,13 @@ public final class DescriptorsUtils {
fill ? LayoutConstants.VALUE_FILL_PARENT : LayoutConstants.VALUE_WRAP_CONTENT,
false /* override */);
String widget_id = getFreeWidgetId(ui_node.getUiRoot(),
new Object[] { ui_node.getDescriptor().getXmlLocalName(), null, null, null });
String widget_id = getFreeWidgetId(ui_node);
if (widget_id != null) {
ui_node.setAttributeValue(LayoutConstants.ATTR_ID, "@+id/" + widget_id, //$NON-NLS-1$
false /* override */);
ui_node.setAttributeValue(LayoutConstants.ATTR_ID, widget_id, false /* override */);
}
ui_node.setAttributeValue(LayoutConstants.ATTR_TEXT, widget_id, false /*override*/);
if (updateLayout) {
UiElementNode ui_parent = ui_node.getUiParent();
if (ui_parent != null &&
@@ -752,19 +750,26 @@ public final class DescriptorsUtils {
/**
* Given a UI root node, returns the first available id that matches the
* pattern "prefix%02d".
*
* <p/>TabWidget is a special case and the method will always return "@android:id/tabs".
*
* @param uiNode The UI node that gives the prefix to match.
* @return A suitable generated id
* @return A suitable generated id in the attribute form needed by the XML id tag
* (e.g. "@+id/something")
*/
public static String getFreeWidgetId(UiElementNode uiNode) {
return getFreeWidgetId(uiNode.getUiRoot(),
new Object[] { uiNode.getDescriptor().getXmlLocalName(), null, null, null });
String name = uiNode.getDescriptor().getXmlLocalName();
if ("TabWidget".equals(name)) { //$NON-NLS-1$
return "@android:id/tabs"; //$NON-NLS-1$
}
return "@+id/" + getFreeWidgetId(uiNode.getUiRoot(), //$NON-NLS-1$
new Object[] { name, null, null, null });
}
/**
* Given a UI root node, returns the first available id that matches the
* pattern "prefix%02d".
*
*
* For recursion purposes, a "context" is given. Since Java doesn't have in-out parameters
* in methods and we're not going to do a dedicated type, we just use an object array which
* must contain one initial item and several are built on the fly just for internal storage:
@@ -775,7 +780,7 @@ public final class DescriptorsUtils {
* <li> map(Set<String>): A set of the ids collected so far when walking through the widget
* hierarchy. Must start with null.
* </ul>
*
*
* @param uiRoot The Ui root node where to start searching recursively. For the initial call
* you want to pass the document root.
* @param params An in-out context of parameters used during recursion, as explained above.
@@ -837,9 +842,9 @@ public final class DescriptorsUtils {
for (UiElementNode uiChild : uiRoot.getUiChildren()) {
getFreeWidgetId(uiChild, params);
}
// Note: return params[2] (not "generated") since it could have changed during recursion.
return (String) params[2];
}
}

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
/**
* {@link DocumentDescriptor} describes the properties expected for an XML document node.

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.sdklib.SdkConstants;
import org.eclipse.jface.resource.ImageDescriptor;

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiListAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
/**
* Describes a text attribute that can only contains some predefined values.

View File

@@ -14,13 +14,13 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.ui.FlagValueCellEditor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiFlagAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiListAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.ui.FlagValueCellEditor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiFlagAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.swt.widgets.Composite;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
public interface IDescriptorProvider {

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.ui.ListValueCellEditor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiListAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.ui.ListValueCellEditor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiListAttributeNode;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.swt.widgets.Composite;

View File

@@ -14,13 +14,13 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.common.resources.ResourceType;
import com.android.ide.eclipse.editors.ui.ResourceValueCellEditor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiResourceAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.ui.ResourceValueCellEditor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiResourceAttributeNode;
import com.android.ide.eclipse.adt.internal.resources.ResourceType;
import com.android.sdklib.SdkConstants;
import org.eclipse.jface.viewers.CellEditor;

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiSeparatorAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiSeparatorAttributeNode;
/**
* {@link SeparatorAttributeDescriptor} does not represent any real attribute.

View File

@@ -14,12 +14,12 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.ui.TextValueCellEditor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiTextAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.ui.TextValueCellEditor;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextAttributeNode;
import com.android.sdklib.SdkConstants;
import org.eclipse.jface.viewers.CellEditor;

View File

@@ -14,11 +14,11 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiTextValueNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiTextValueNode;
/**

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.descriptors;
package com.android.ide.eclipse.adt.internal.editors.descriptors;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
/**

View File

@@ -14,13 +14,13 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.layout;
package com.android.ide.eclipse.adt.internal.editors.layout;
import com.android.ide.eclipse.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
import com.android.ide.eclipse.editors.layout.parts.ElementCreateCommand;
import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
import com.android.ide.eclipse.adt.internal.editors.layout.parts.ElementCreateCommand;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
import org.eclipse.gef.DefaultEditDomain;
import org.eclipse.gef.ui.parts.GraphicalEditorWithPalette;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.layout;
package com.android.ide.eclipse.adt.internal.editors.layout;
import com.android.layoutlib.api.IXmlPullParser;

View File

@@ -14,51 +14,51 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.layout;
package com.android.ide.eclipse.adt.internal.editors.layout;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.sdk.LoadStatus;
import com.android.ide.eclipse.adt.sdk.Sdk;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData.LayoutBridge;
import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.adt.ui.ConfigurationSelector.DensityVerifier;
import com.android.ide.eclipse.adt.ui.ConfigurationSelector.DimensionVerifier;
import com.android.ide.eclipse.adt.ui.ConfigurationSelector.LanguageRegionVerifier;
import com.android.ide.eclipse.adt.ui.ConfigurationSelector.MobileCodeVerifier;
import com.android.ide.eclipse.common.resources.ResourceType;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.layout.LayoutEditor.UiEditorActions;
import com.android.ide.eclipse.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.editors.layout.parts.ElementCreateCommand;
import com.android.ide.eclipse.editors.layout.parts.UiElementEditPart;
import com.android.ide.eclipse.editors.layout.parts.UiElementsEditPartFactory;
import com.android.ide.eclipse.editors.resources.configurations.CountryCodeQualifier;
import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.editors.resources.configurations.KeyboardStateQualifier;
import com.android.ide.eclipse.editors.resources.configurations.LanguageQualifier;
import com.android.ide.eclipse.editors.resources.configurations.NavigationMethodQualifier;
import com.android.ide.eclipse.editors.resources.configurations.NetworkCodeQualifier;
import com.android.ide.eclipse.editors.resources.configurations.PixelDensityQualifier;
import com.android.ide.eclipse.editors.resources.configurations.RegionQualifier;
import com.android.ide.eclipse.editors.resources.configurations.ScreenDimensionQualifier;
import com.android.ide.eclipse.editors.resources.configurations.ScreenOrientationQualifier;
import com.android.ide.eclipse.editors.resources.configurations.TextInputMethodQualifier;
import com.android.ide.eclipse.editors.resources.configurations.TouchScreenQualifier;
import com.android.ide.eclipse.editors.resources.configurations.KeyboardStateQualifier.KeyboardState;
import com.android.ide.eclipse.editors.resources.configurations.NavigationMethodQualifier.NavigationMethod;
import com.android.ide.eclipse.editors.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
import com.android.ide.eclipse.editors.resources.configurations.TextInputMethodQualifier.TextInputMethod;
import com.android.ide.eclipse.editors.resources.configurations.TouchScreenQualifier.TouchScreenType;
import com.android.ide.eclipse.editors.resources.manager.ProjectResources;
import com.android.ide.eclipse.editors.resources.manager.ResourceFile;
import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
import com.android.ide.eclipse.editors.resources.manager.ResourceManager;
import com.android.ide.eclipse.editors.ui.tree.CopyCutAction;
import com.android.ide.eclipse.editors.ui.tree.PasteAction;
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditor.UiEditorActions;
import com.android.ide.eclipse.adt.internal.editors.layout.LayoutReloadMonitor.ILayoutReloadListener;
import com.android.ide.eclipse.adt.internal.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.adt.internal.editors.layout.parts.ElementCreateCommand;
import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiElementEditPart;
import com.android.ide.eclipse.adt.internal.editors.layout.parts.UiElementsEditPartFactory;
import com.android.ide.eclipse.adt.internal.editors.ui.tree.CopyCutAction;
import com.android.ide.eclipse.adt.internal.editors.ui.tree.PasteAction;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.adt.internal.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.adt.internal.resources.ResourceType;
import com.android.ide.eclipse.adt.internal.resources.configurations.CountryCodeQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.LanguageQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.NetworkCodeQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.PixelDensityQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.RegionQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenDimensionQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier;
import com.android.ide.eclipse.adt.internal.resources.configurations.KeyboardStateQualifier.KeyboardState;
import com.android.ide.eclipse.adt.internal.resources.configurations.NavigationMethodQualifier.NavigationMethod;
import com.android.ide.eclipse.adt.internal.resources.configurations.ScreenOrientationQualifier.ScreenOrientation;
import com.android.ide.eclipse.adt.internal.resources.configurations.TextInputMethodQualifier.TextInputMethod;
import com.android.ide.eclipse.adt.internal.resources.configurations.TouchScreenQualifier.TouchScreenType;
import com.android.ide.eclipse.adt.internal.resources.manager.ProjectResources;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFile;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceManager;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
import com.android.ide.eclipse.adt.internal.sdk.LoadStatus;
import com.android.ide.eclipse.adt.internal.sdk.Sdk;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData.LayoutBridge;
import com.android.ide.eclipse.adt.internal.sdk.Sdk.ITargetChangeListener;
import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.DensityVerifier;
import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.DimensionVerifier;
import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.LanguageRegionVerifier;
import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.MobileCodeVerifier;
import com.android.layoutlib.api.ILayoutLog;
import com.android.layoutlib.api.ILayoutResult;
import com.android.layoutlib.api.IProjectCallback;

View File

@@ -14,7 +14,7 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.layout;
package com.android.ide.eclipse.adt.internal.editors.layout;
/**
* A bunch of constants that map to either:

View File

@@ -14,10 +14,10 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.layout;
package com.android.ide.eclipse.adt.internal.editors.layout;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
import com.android.ide.eclipse.editors.AndroidContentAssist;
import com.android.ide.eclipse.adt.internal.editors.AndroidContentAssist;
import com.android.ide.eclipse.adt.internal.sdk.AndroidTargetData;
/**
* Content Assist Processor for /res/layout XML files

View File

@@ -14,14 +14,14 @@
* limitations under the License.
*/
package com.android.ide.eclipse.editors.layout;
package com.android.ide.eclipse.adt.internal.editors.layout;
import com.android.ide.eclipse.adt.ui.ConfigurationSelector;
import com.android.ide.eclipse.adt.ui.ConfigurationSelector.ConfigurationState;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier;
import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType;
import com.android.ide.eclipse.adt.internal.editors.IconFactory;
import com.android.ide.eclipse.adt.internal.resources.configurations.FolderConfiguration;
import com.android.ide.eclipse.adt.internal.resources.configurations.ResourceQualifier;
import com.android.ide.eclipse.adt.internal.resources.manager.ResourceFolderType;
import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector;
import com.android.ide.eclipse.adt.internal.ui.ConfigurationSelector.ConfigurationState;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.jface.dialogs.TrayDialog;

Some files were not shown because too many files have changed in this diff Show More