diff options
author | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 14:03:58 -0800 |
---|---|---|
committer | The Android Open Source Project <initial-contribution@android.com> | 2009-03-03 14:03:58 -0800 |
commit | c9432be76d50a527da232d518f633add2f76242b (patch) | |
tree | c6a908295dcbece6bb31f644b3d4698f04abee20 | |
parent | 382f18c205f459fdd9ff6c0657beadcbfe3c5b01 (diff) | |
download | sdk-c9432be76d50a527da232d518f633add2f76242b.zip sdk-c9432be76d50a527da232d518f633add2f76242b.tar.gz sdk-c9432be76d50a527da232d518f633add2f76242b.tar.bz2 |
auto import from //depot/cupcake/@132589
60 files changed, 726 insertions, 2344 deletions
diff --git a/apkbuilder/etc/apkbuilder.bat b/apkbuilder/etc/apkbuilder.bat index c4689c6..7ab3e6c 100755 --- a/apkbuilder/etc/apkbuilder.bat +++ b/apkbuilder/etc/apkbuilder.bat @@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks, rem and set up progdir to be the fully-qualified pathname of its directory. set prog=%~f0 -rem Change current directory and drive to where the script is, to avoid -rem issues with directories containing whitespaces. -cd /d %~dp0 +rem Change current directory to where ddms is, to avoid issues with directories +rem containing whitespaces. +cd %~dp0 set jarfile=apkbuilder.jar set frameworkdir= diff --git a/ddms/app/etc/ddms.bat b/ddms/app/etc/ddms.bat index 5da9fb5..8d941b9 100755 --- a/ddms/app/etc/ddms.bat +++ b/ddms/app/etc/ddms.bat @@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks, rem and set up progdir to be the fully-qualified pathname of its directory. set prog=%~f0 -rem Change current directory and drive to where the script is, to avoid -rem issues with directories containing whitespaces. -cd /d %~dp0 +rem Change current directory to where ddms is, to avoid issues with directories +rem containing whitespaces. +cd %~dp0 set jarfile=ddms.jar set frameworkdir= diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java index 866d578..a4576aa 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Client.java @@ -94,7 +94,7 @@ public class Client { * is only used for data generated within Client. */ private static final int INITIAL_BUF_SIZE = 2*1024; - private static final int MAX_BUF_SIZE = 200*1024*1024; + private static final int MAX_BUF_SIZE = 2*1024*1024; private ByteBuffer mReadBuffer; private static final int WRITE_BUF_SIZE = 256; diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java index 0e7f0bb..34ef432 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java @@ -30,7 +30,7 @@ import java.util.Map; /** * 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 { @@ -62,10 +62,10 @@ public final class Device implements IDevice { return null; } } - + /** Emulator Serial Number regexp. */ final static String RE_EMULATOR_SN = "emulator-(\\d+)"; //$NON-NLS-1$ - + /** Serial number of the device */ String serialNumber = null; @@ -74,7 +74,7 @@ public final class Device implements IDevice { /** State of the device. */ DeviceState state = null; - + /** Device properties. */ private final Map<String, String> mProperties = new HashMap<String, String>(); @@ -85,29 +85,29 @@ public final class Device implements IDevice { * Socket for the connection monitoring client connection/disconnection. */ private SocketChannel mSocketChannel; - - /* + + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getSerialNumber() */ public String getSerialNumber() { return serialNumber; } - + public String getAvdName() { return mAvdName; } - - /* + + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getState() */ public DeviceState getState() { return state; } - - /* + + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getProperties() */ @@ -115,7 +115,7 @@ public final class Device implements IDevice { return Collections.unmodifiableMap(mProperties); } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getPropertyCount() */ @@ -123,21 +123,21 @@ public final class Device implements IDevice { return mProperties.size(); } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getProperty(java.lang.String) */ public String getProperty(String name) { return mProperties.get(name); } - + @Override public String toString() { return serialNumber; } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#isOnline() */ @@ -145,7 +145,7 @@ public final class Device implements IDevice { return state == DeviceState.ONLINE; } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#isEmulator() */ @@ -153,7 +153,7 @@ public final class Device implements IDevice { return serialNumber.matches(RE_EMULATOR_SN); } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#isOffline() */ @@ -161,7 +161,7 @@ public final class Device implements IDevice { return state == DeviceState.OFFLINE; } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#isBootLoader() */ @@ -169,7 +169,7 @@ public final class Device implements IDevice { return state == DeviceState.BOOTLOADER; } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#hasClients() */ @@ -177,7 +177,7 @@ public final class Device implements IDevice { return mClients.size() > 0; } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getClients() */ @@ -186,8 +186,8 @@ public final class Device implements IDevice { return mClients.toArray(new Client[mClients.size()]); } } - - /* + + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getClient(java.lang.String) */ @@ -204,7 +204,7 @@ public final class Device implements IDevice { return null; } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getSyncService() */ @@ -217,7 +217,7 @@ public final class Device implements IDevice { return null; } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getFileListingService() */ @@ -225,7 +225,7 @@ public final class Device implements IDevice { return new FileListingService(this); } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getScreenshot() */ @@ -233,7 +233,7 @@ public final class Device implements IDevice { return AdbHelper.getFrameBuffer(AndroidDebugBridge.sSocketAddr, this); } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#executeShellCommand(java.lang.String, com.android.ddmlib.IShellOutputReceiver) */ @@ -242,25 +242,16 @@ public final class Device implements IDevice { AdbHelper.executeRemoteCommand(AndroidDebugBridge.sSocketAddr, command, this, receiver); } - - /* + + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#runEventLogService(com.android.ddmlib.log.LogReceiver) */ public void runEventLogService(LogReceiver receiver) throws IOException { AdbHelper.runEventLogService(AndroidDebugBridge.sSocketAddr, this, receiver); } - - /* - * (non-Javadoc) - * @see com.android.ddmlib.IDevice#runLogService(com.android.ddmlib.log.LogReceiver) - */ - public void runLogService(String logname, - LogReceiver receiver) throws IOException { - AdbHelper.runLogService(AndroidDebugBridge.sSocketAddr, this, logname, receiver); - } - - /* + + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#createForward(int, int) */ @@ -274,7 +265,7 @@ public final class Device implements IDevice { } } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#removeForward(int, int) */ @@ -288,7 +279,7 @@ public final class Device implements IDevice { } } - /* + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getClientName(int) */ @@ -334,7 +325,7 @@ public final class Device implements IDevice { return false; } - + void clearClientList() { synchronized (mClients) { mClients.clear(); diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java index 5dbce92..664b0c9 100755 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java @@ -44,7 +44,7 @@ public interface IDevice { * Returns the serial number of the device. */ public String getSerialNumber(); - + /** * Returns the name of the AVD the emulator is running. * <p/>This is only valid if {@link #isEmulator()} returns true. @@ -152,14 +152,6 @@ public interface IDevice { public void runEventLogService(LogReceiver receiver) throws IOException; /** - * Runs the log service for the given log and outputs the log to the {@link LogReceiver}. - * @param logname the logname of the log to read from. - * @param receiver the receiver to receive the event log entries. - * @throws IOException - */ - public void runLogService(String logname, LogReceiver receiver) throws IOException; - - /** * Creates a port forwarding between a local and a remote port. * @param localPort the local port to forward * @param remotePort the remote port. diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java index b61a698..4c0d9de 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/ITestRunListener.java @@ -17,69 +17,56 @@ package com.android.ddmlib.testrunner; /** - * Receives event notifications during instrumentation test runs. - * Patterned after {@link junit.runner.TestRunListener}. + * Listener for instrumentation test runs + * + * Modeled after junit.runner.TestRunListener */ public interface ITestRunListener { - - /** - * Types of test failures. - */ - enum TestFailure { - /** Test failed due to unanticipated uncaught exception. */ - ERROR, - /** Test failed due to a false assertion. */ - FAILURE - } + public static final int STATUS_ERROR = 1; + public static final int STATUS_FAILURE = 2; /** - * Reports the start of a test run. - * - * @param testCount total number of tests in test run - */ + * Reports the start of a test run + * @param testCount - total number of tests in test run + * */ public void testRunStarted(int testCount); /** - * Reports end of test run. - * - * @param elapsedTime device reported elapsed time, in milliseconds + * Reports end of test run + * @param elapsedTime - device reported elapsed time, in milliseconds */ public void testRunEnded(long elapsedTime); /** - * Reports test run stopped before completion. - * - * @param elapsedTime device reported elapsed time, in milliseconds + * Reports test run stopped before completion + * @param elapsedTime - device reported elapsed time, in milliseconds */ public void testRunStopped(long elapsedTime); /** - * Reports the start of an individual test case. - * - * @param test identifies the test + * Reports the start of an individual test case */ - public void testStarted(TestIdentifier test); + public void testStarted(String className, String testName); /** - * Reports the execution end of an individual test case. - * If {@link #testFailed} was not invoked, this test passed. - * - * @param test identifies the test + * Reports the execution end of an individual test case + * If no testFailed has been reported, this is a passed test */ - public void testEnded(TestIdentifier test); + public void testEnded(String className, String testName); /** - * Reports the failure of a individual test case. - * Will be called between testStarted and testEnded. + * Reports the failure of a individual test case + * Will be called between testStarted and testEnded * - * @param status failure type - * @param test identifies the test - * @param trace stack trace of failure + * @param status - one of STATUS_ERROR, STATUS_FAILURE + * @param className - name of test class + * @param testName - name of test method + * @param trace - stack trace of failure */ - public void testFailed(TestFailure status, TestIdentifier test, String trace); + public void testFailed(int status, String className, String testName, String trace); /** - * Reports test run failed to execute due to a fatal error. + * Reports test run failed to execute due to a fatal error */ public void testRunFailed(String errorMessage); } diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java index bc1834f..d47bd56 100755 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/InstrumentationResultParser.java @@ -20,21 +20,24 @@ import com.android.ddmlib.IShellOutputReceiver; import com.android.ddmlib.Log; import com.android.ddmlib.MultiLineReceiver; +import java.util.Hashtable; +import java.util.Map; + /** - * Parses the 'raw output mode' results of an instrumentation test run from shell and informs a - * ITestRunListener of the results. + * Parses the 'raw output mode' results of an instrument test run from shell, and informs a + * ITestRunListener of the results * - * <p>Expects the following output: + * Expects the following output: * - * <p>If fatal error occurred when attempted to run the tests: - * <pre> INSTRUMENTATION_FAILED: </pre> + * If fatal error occurred when attempted to run the tests: + * <i> INSTRUMENTATION_FAILED: </i> * - * <p>Otherwise, expect a series of test results, each one containing a set of status key/value + * Otherwise, expect a series of test results, each one containing a set of status key/value * pairs, delimited by a start(1)/pass(0)/fail(-2)/error(-1) status code result. At end of test * run, expects that the elapsed test time in seconds will be displayed * - * <p>For example: - * <pre> + * i.e. + * <i> * INSTRUMENTATION_STATUS_CODE: 1 * INSTRUMENTATION_STATUS: class=com.foo.FooTest * INSTRUMENTATION_STATUS: test=testFoo @@ -45,85 +48,64 @@ import com.android.ddmlib.MultiLineReceiver; * ... * * Time: X - * </pre> - * <p>Note that the "value" portion of the key-value pair may wrap over several text lines + * </i> + * + * Note that the "value" portion of the key-value pair may wrap over several text lines */ public class InstrumentationResultParser extends MultiLineReceiver { - /** Relevant test status keys. */ - private static class StatusKeys { - private static final String TEST = "test"; - private static final String CLASS = "class"; - private static final String STACK = "stack"; - private static final String NUMTESTS = "numtests"; - } + // relevant test status keys + private static final String CODE_KEY = "code"; + private static final String TEST_KEY = "test"; + private static final String CLASS_KEY = "class"; + private static final String STACK_KEY = "stack"; + private static final String NUMTESTS_KEY = "numtests"; - /** Test result status codes. */ - private static class StatusCodes { - private static final int FAILURE = -2; - private static final int START = 1; - private static final int ERROR = -1; - private static final int OK = 0; - } + // test result status codes + private static final int FAILURE_STATUS_CODE = -2; + private static final int START_STATUS_CODE = 1; + private static final int ERROR_STATUS_CODE = -1; + private static final int OK_STATUS_CODE = 0; - /** Prefixes used to identify output. */ - private static class Prefixes { - private static final String STATUS = "INSTRUMENTATION_STATUS: "; - private static final String STATUS_CODE = "INSTRUMENTATION_STATUS_CODE: "; - private static final String STATUS_FAILED = "INSTRUMENTATION_FAILED: "; - private static final String TIME_REPORT = "Time: "; - } + // recognized output patterns + private static final String STATUS_PREFIX = "INSTRUMENTATION_STATUS: "; + private static final String STATUS_PREFIX_CODE = "INSTRUMENTATION_STATUS_CODE: "; + private static final String STATUS_FAILED = "INSTRUMENTATION_FAILED: "; + private static final String TIME_REPORT = "Time: "; private final ITestRunListener mTestListener; - - /** - * Test result data - */ - private static class TestResult { - private Integer mCode = null; - private String mTestName = null; - private String mTestClass = null; - private String mStackTrace = null; - private Integer mNumTests = null; - - /** Returns true if all expected values have been parsed */ - boolean isComplete() { - return mCode != null && mTestName != null && mTestClass != null; - } - } - - /** Stores the status values for the test result currently being parsed */ - private TestResult mCurrentTestResult = null; - - /** Stores the current "key" portion of the status key-value being parsed. */ - private String mCurrentKey = null; - - /** Stores the current "value" portion of the status key-value being parsed. */ - private StringBuilder mCurrentValue = null; - - /** True if start of test has already been reported to listener. */ - private boolean mTestStartReported = false; - - /** The elapsed time of the test run, in milliseconds. */ - private long mTestTime = 0; - - /** True if current test run has been canceled by user. */ - private boolean mIsCancelled = false; + /** key-value map for current test */ + private Map<String, String> mStatusValues; + /** stores the current "key" portion of the status key-value being parsed */ + private String mCurrentKey; + /** stores the current "value" portion of the status key-value being parsed */ + private StringBuilder mCurrentValue; + /** true if start of test has already been reported to listener */ + private boolean mTestStartReported; + /** the elapsed time of the test run, in ms */ + private long mTestTime; + /** true if current test run has been canceled by user */ + private boolean mIsCancelled; private static final String LOG_TAG = "InstrumentationResultParser"; /** - * Creates the InstrumentationResultParser. - * - * @param listener informed of test results as the tests are executing + * Creates the InstrumentationResultParser + * @param listener - listener to report results to. will be informed of test results as the + * tests are executing */ public InstrumentationResultParser(ITestRunListener listener) { + mStatusValues = new Hashtable<String, String>(); + mCurrentKey = null; + setTrimLine(false); mTestListener = listener; + mTestStartReported = false; + mTestTime = 0; + mIsCancelled = false; } /** - * Processes the instrumentation test output from shell. - * + * Processes the instrumentation test output from shell * @see MultiLineReceiver#processNewLines */ @Override @@ -134,37 +116,31 @@ public class InstrumentationResultParser extends MultiLineReceiver { } /** - * Parse an individual output line. Expects a line that is one of: - * <ul> - * <li> - * The start of a new status line (starts with Prefixes.STATUS or Prefixes.STATUS_CODE), - * and thus there is a new key=value pair to parse, and the previous key-value pair is - * finished. - * </li> - * <li> - * A continuation of the previous status (the "value" portion of the key has wrapped - * to the next line). - * </li> - * <li> A line reporting a fatal error in the test run (Prefixes.STATUS_FAILED) </li> - * <li> A line reporting the total elapsed time of the test run. (Prefixes.TIME_REPORT) </li> - * </ul> + * Parse an individual output line. Expects a line that either is: + * a) the start of a new status line (ie. starts with STATUS_PREFIX or STATUS_PREFIX_CODE), + * and thus there is a new key=value pair to parse, and the previous key-value pair is + * finished + * b) a continuation of the previous status (ie the "value" portion of the key has wrapped + * to the next line. + * c) a line reporting a fatal error in the test run (STATUS_FAILED) + * d) a line reporting the total elapsed time of the test run. * - * @param line Text output line + * @param line - text output line */ private void parse(String line) { - if (line.startsWith(Prefixes.STATUS_CODE)) { + if (line.startsWith(STATUS_PREFIX_CODE)) { // Previous status key-value has been collected. Store it. submitCurrentKeyValue(); parseStatusCode(line); - } else if (line.startsWith(Prefixes.STATUS)) { + } else if (line.startsWith(STATUS_PREFIX)) { // Previous status key-value has been collected. Store it. submitCurrentKeyValue(); - parseKey(line, Prefixes.STATUS.length()); - } else if (line.startsWith(Prefixes.STATUS_FAILED)) { + parseKey(line, STATUS_PREFIX.length()); + } else if (line.startsWith(STATUS_FAILED)) { Log.e(LOG_TAG, "test run failed " + line); mTestListener.testRunFailed(line); - } else if (line.startsWith(Prefixes.TIME_REPORT)) { - parseTime(line, Prefixes.TIME_REPORT.length()); + } else if (line.startsWith(TIME_REPORT)) { + parseTime(line, TIME_REPORT.length()); } else { if (mCurrentValue != null) { // this is a value that has wrapped to next line. @@ -177,53 +153,21 @@ public class InstrumentationResultParser extends MultiLineReceiver { } /** - * Stores the currently parsed key-value pair into mCurrentTestInfo. + * Stores the currently parsed key-value pair in the status map */ private void submitCurrentKeyValue() { if (mCurrentKey != null && mCurrentValue != null) { - TestResult testInfo = getCurrentTestInfo(); - String statusValue = mCurrentValue.toString(); - - if (mCurrentKey.equals(StatusKeys.CLASS)) { - testInfo.mTestClass = statusValue.trim(); - } - else if (mCurrentKey.equals(StatusKeys.TEST)) { - testInfo.mTestName = statusValue.trim(); - } - else if (mCurrentKey.equals(StatusKeys.NUMTESTS)) { - try { - testInfo.mNumTests = Integer.parseInt(statusValue); - } - catch (NumberFormatException e) { - Log.e(LOG_TAG, "Unexpected integer number of tests, received " + statusValue); - } - } - else if (mCurrentKey.equals(StatusKeys.STACK)) { - testInfo.mStackTrace = statusValue; - } - + mStatusValues.put(mCurrentKey, mCurrentValue.toString()); mCurrentKey = null; mCurrentValue = null; } } - private TestResult getCurrentTestInfo() { - if (mCurrentTestResult == null) { - mCurrentTestResult = new TestResult(); - } - return mCurrentTestResult; - } - - private void clearCurrentTestInfo() { - mCurrentTestResult = null; - } - /** - * Parses the key from the current line. - * Expects format of "key=value". - * - * @param line full line of text to parse - * @param keyStartPos the starting position of the key in the given line + * Parses the key from the current line + * Expects format of "key=value", + * @param line - full line of text to parse + * @param keyStartPos - the starting position of the key in the given line */ private void parseKey(String line, int keyStartPos) { int endKeyPos = line.indexOf('=', keyStartPos); @@ -234,8 +178,7 @@ public class InstrumentationResultParser extends MultiLineReceiver { } /** - * Parses the start of a key=value pair. - * + * Parses the start of a key=value pair. * @param line - full line of text to parse * @param valueStartPos - the starting position of the value in the given line */ @@ -245,25 +188,20 @@ public class InstrumentationResultParser extends MultiLineReceiver { } /** - * Parses out a status code result. + * Parses out a status code result. For consistency, stores the result as a CODE entry in + * key-value status map */ private void parseStatusCode(String line) { - String value = line.substring(Prefixes.STATUS_CODE.length()).trim(); - TestResult testInfo = getCurrentTestInfo(); - try { - testInfo.mCode = Integer.parseInt(value); - } - catch (NumberFormatException e) { - Log.e(LOG_TAG, "Expected integer status code, received: " + value); - } + String value = line.substring(STATUS_PREFIX_CODE.length()).trim(); + mStatusValues.put(CODE_KEY, value); // this means we're done with current test result bundle - reportResult(testInfo); - clearCurrentTestInfo(); + reportResult(mStatusValues); + mStatusValues.clear(); } /** - * Returns true if test run canceled. + * Returns true if test run canceled * * @see IShellOutputReceiver#isCancelled() */ @@ -272,7 +210,7 @@ public class InstrumentationResultParser extends MultiLineReceiver { } /** - * Requests cancellation of test run. + * Requests cancellation of test result parsing */ public void cancel() { mIsCancelled = true; @@ -281,62 +219,82 @@ public class InstrumentationResultParser extends MultiLineReceiver { /** * Reports a test result to the test run listener. Must be called when a individual test * result has been fully parsed. - * - * @param statusMap key-value status pairs of test result + * @param statusMap - key-value status pairs of test result */ - private void reportResult(TestResult testInfo) { - if (!testInfo.isComplete()) { - Log.e(LOG_TAG, "invalid instrumentation status bundle " + testInfo.toString()); + private void reportResult(Map<String, String> statusMap) { + String className = statusMap.get(CLASS_KEY); + String testName = statusMap.get(TEST_KEY); + String statusCodeString = statusMap.get(CODE_KEY); + + if (className == null || testName == null || statusCodeString == null) { + Log.e(LOG_TAG, "invalid instrumentation status bundle " + statusMap.toString()); return; } - reportTestRunStarted(testInfo); - TestIdentifier testId = new TestIdentifier(testInfo.mTestClass, testInfo.mTestName); + className = className.trim(); + testName = testName.trim(); - switch (testInfo.mCode) { - case StatusCodes.START: - mTestListener.testStarted(testId); - break; - case StatusCodes.FAILURE: - mTestListener.testFailed(ITestRunListener.TestFailure.FAILURE, testId, - getTrace(testInfo)); - mTestListener.testEnded(testId); - break; - case StatusCodes.ERROR: - mTestListener.testFailed(ITestRunListener.TestFailure.ERROR, testId, - getTrace(testInfo)); - mTestListener.testEnded(testId); - break; - case StatusCodes.OK: - mTestListener.testEnded(testId); - break; - default: - Log.e(LOG_TAG, "Unknown status code received: " + testInfo.mCode); - mTestListener.testEnded(testId); - break; + reportTestStarted(statusMap); + + try { + int statusCode = Integer.parseInt(statusCodeString); + + switch (statusCode) { + case START_STATUS_CODE: + mTestListener.testStarted(className, testName); + break; + case FAILURE_STATUS_CODE: + mTestListener.testFailed(ITestRunListener.STATUS_FAILURE, className, testName, + getTrace(statusMap)); + mTestListener.testEnded(className, testName); + break; + case ERROR_STATUS_CODE: + mTestListener.testFailed(ITestRunListener.STATUS_ERROR, className, testName, + getTrace(statusMap)); + mTestListener.testEnded(className, testName); + break; + case OK_STATUS_CODE: + mTestListener.testEnded(className, testName); + break; + default: + Log.e(LOG_TAG, "Expected status code, received: " + statusCodeString); + mTestListener.testEnded(className, testName); + break; + } + } + catch (NumberFormatException e) { + Log.e(LOG_TAG, "Expected integer status code, received: " + statusCodeString); } - } /** * Reports the start of a test run, and the total test count, if it has not been previously - * reported. - * - * @param testInfo current test status values + * reported + * @param statusMap - key-value status pairs */ - private void reportTestRunStarted(TestResult testInfo) { + private void reportTestStarted(Map<String, String> statusMap) { // if start test run not reported yet - if (!mTestStartReported && testInfo.mNumTests != null) { - mTestListener.testRunStarted(testInfo.mNumTests); - mTestStartReported = true; + if (!mTestStartReported) { + String numTestsString = statusMap.get(NUMTESTS_KEY); + if (numTestsString != null) { + try { + int numTests = Integer.parseInt(numTestsString); + mTestListener.testRunStarted(numTests); + mTestStartReported = true; + } + catch (NumberFormatException e) { + Log.e(LOG_TAG, "Unexpected numTests format " + numTestsString); + } + } } } /** - * Returns the stack trace of the current failed test, from the provided testInfo. + * Returns the stack trace of the current failed test, from the provided key-value status map */ - private String getTrace(TestResult testInfo) { - if (testInfo.mStackTrace != null) { - return testInfo.mStackTrace; + private String getTrace(Map<String, String> statusMap) { + String stackTrace = statusMap.get(STACK_KEY); + if (stackTrace != null) { + return stackTrace; } else { Log.e(LOG_TAG, "Could not find stack trace for failed test "); @@ -345,7 +303,7 @@ public class InstrumentationResultParser extends MultiLineReceiver { } /** - * Parses out and store the elapsed time. + * Parses out and store the elapsed time */ private void parseTime(String line, int startPos) { String timeString = line.substring(startPos); diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java index 4edbbbb..5de632e 100644 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java +++ b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunner.java @@ -23,7 +23,7 @@ import com.android.ddmlib.Log; import java.io.IOException; /** - * Runs a Android test command remotely and reports results. + * Runs a Android test command remotely and reports results */ public class RemoteAndroidTestRunner { @@ -43,12 +43,11 @@ public class RemoteAndroidTestRunner { "android.test.InstrumentationTestRunner"; /** - * Creates a remote Android test runner. - * - * @param packageName the Android application package that contains the tests to run - * @param runnerName the instrumentation test runner to execute. If null, will use default + * Creates a remote android test runner. + * @param packageName - the Android application package that contains the tests to run + * @param runnerName - the instrumentation test runner to execute. If null, will use default * runner - * @param remoteDevice the Android device to execute tests on + * @param remoteDevice - the Android device to execute tests on */ public RemoteAndroidTestRunner(String packageName, String runnerName, @@ -63,10 +62,9 @@ public class RemoteAndroidTestRunner { } /** - * Alternate constructor. Uses default instrumentation runner. - * - * @param packageName the Android application package that contains the tests to run - * @param remoteDevice the Android device to execute tests on + * Alternate constructor. Uses default instrumentation runner + * @param packageName - the Android application package that contains the tests to run + * @param remoteDevice - the Android device to execute tests on */ public RemoteAndroidTestRunner(String packageName, IDevice remoteDevice) { @@ -74,14 +72,14 @@ public class RemoteAndroidTestRunner { } /** - * Returns the application package name. + * Returns the application package name */ public String getPackageName() { return mPackageName; } /** - * Returns the runnerName. + * Returns the runnerName */ public String getRunnerName() { if (mRunnerName == null) { @@ -91,7 +89,7 @@ public class RemoteAndroidTestRunner { } /** - * Returns the complete instrumentation component path. + * Returns the complete instrumentation component path */ private String getRunnerPath() { return getPackageName() + RUNNER_SEPARATOR + getRunnerName(); @@ -99,9 +97,8 @@ public class RemoteAndroidTestRunner { /** * Sets to run only tests in this class - * Must be called before 'run'. - * - * @param className fully qualified class name (eg x.y.z) + * Must be called before 'run' + * @param className - fully qualified class name (eg x.y.z) */ public void setClassName(String className) { mClassArg = className; @@ -109,12 +106,10 @@ public class RemoteAndroidTestRunner { /** * Sets to run only tests in the provided classes - * Must be called before 'run'. - * <p> + * Must be called before 'run' * If providing more than one class, requires a InstrumentationTestRunner that supports - * the multiple class argument syntax. - * - * @param classNames array of fully qualified class names (eg x.y.z) + * the multiple class argument syntax + * @param classNames - array of fully qualified class name (eg x.y.z) */ public void setClassNames(String[] classNames) { StringBuilder classArgBuilder = new StringBuilder(); @@ -130,10 +125,9 @@ public class RemoteAndroidTestRunner { /** * Sets to run only specified test method - * Must be called before 'run'. - * - * @param className fully qualified class name (eg x.y.z) - * @param testName method name + * Must be called before 'run' + * @param className - fully qualified class name (eg x.y.z) + * @param testName - method name */ public void setMethodName(String className, String testName) { mClassArg = className + METHOD_SEPARATOR + testName; @@ -141,9 +135,8 @@ public class RemoteAndroidTestRunner { /** * Sets extra arguments to include in instrumentation command. - * Must be called before 'run'. - * - * @param instrumentationArgs must not be null + * Must be called before 'run' + * @param instrumentationArgs - must not be null */ public void setExtraArgs(String instrumentationArgs) { if (instrumentationArgs == null) { @@ -153,23 +146,23 @@ public class RemoteAndroidTestRunner { } /** - * Returns the extra instrumentation arguments. + * Returns the extra instrumentation arguments */ public String getExtraArgs() { return mExtraArgs; } /** - * Sets this test run to log only mode - skips test execution. + * Sets this test run to log only mode - skips test execution */ public void setLogOnly(boolean logOnly) { mLogOnlyMode = logOnly; } /** - * Execute this test run. + * Execute this test run * - * @param listener listens for test results + * @param listener - listener to report results to */ public void run(ITestRunListener listener) { final String runCaseCommandStr = "am instrument -w -r " @@ -186,7 +179,7 @@ public class RemoteAndroidTestRunner { } /** - * Requests cancellation of this test run. + * Requests cancellation of this test run */ public void cancel() { if (mParser != null) { @@ -195,7 +188,7 @@ public class RemoteAndroidTestRunner { } /** - * Returns the test class argument. + * Returns the test class argument */ private String getClassArg() { return mClassArg; @@ -203,7 +196,7 @@ public class RemoteAndroidTestRunner { /** * Returns the full instrumentation command which specifies the test classes to execute. - * Returns an empty string if no classes were specified. + * Returns an empty string if no classes were specified */ private String getClassCmd() { String classArg = getClassArg(); @@ -215,7 +208,7 @@ public class RemoteAndroidTestRunner { /** * Returns the full command to enable log only mode - if specified. Otherwise returns an - * empty string. + * empty string */ private String getLogCmd() { if (mLogOnlyMode) { diff --git a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java b/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java deleted file mode 100644 index 4d3b108..0000000 --- a/ddms/libs/ddmlib/src/com/android/ddmlib/testrunner/TestIdentifier.java +++ /dev/null @@ -1,76 +0,0 @@ -/* - * 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.ddmlib.testrunner; - -/** - * Identifies a parsed instrumentation test - */ -public class TestIdentifier { - - private final String mClassName; - private final String mTestName; - - /** - * Creates a test identifier - * - * @param className fully qualified class name of the test. Cannot be null. - * @param testName name of the test. Cannot be null. - */ - public TestIdentifier(String className, String testName) { - if (className == null || testName == null) { - throw new IllegalArgumentException("className and testName must " + - "be non-null"); - } - mClassName = className; - mTestName = testName; - } - - /** - * Returns the fully qualified class name of the test - */ - public String getClassName() { - return mClassName; - } - - /** - * Returns the name of the test - */ - public String getTestName() { - return mTestName; - } - - /** - * Tests equality by comparing class and method name - */ - @Override - public boolean equals(Object other) { - if (!(other instanceof TestIdentifier)) { - return false; - } - TestIdentifier otherTest = (TestIdentifier)other; - return getClassName().equals(otherTest.getClassName()) && - getTestName().equals(otherTest.getTestName()); - } - - /** - * Generates hashCode based on class and method name. - */ - @Override - public int hashCode() { - return getClassName().hashCode() * 31 + getTestName().hashCode(); - } -} diff --git a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java index 77d10c1..67f6198 100644 --- a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java +++ b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/InstrumentationResultParserTest.java @@ -20,7 +20,7 @@ import junit.framework.TestCase; /** - * Tests InstrumentationResultParser. + * Tests InstrumentationResultParser */ public class InstrumentationResultParserTest extends TestCase { @@ -51,7 +51,7 @@ public class InstrumentationResultParserTest extends TestCase { /** * Tests that the test run started and test start events is sent on first - * bundle received. + * bundle received */ public void testTestStarted() { StringBuilder output = buildCommonResult(); @@ -63,7 +63,7 @@ public class InstrumentationResultParserTest extends TestCase { } /** - * Tests that a single successful test execution. + * Tests that a single successful test execution */ public void testTestSuccess() { StringBuilder output = buildCommonResult(); @@ -74,11 +74,11 @@ public class InstrumentationResultParserTest extends TestCase { injectTestString(output.toString()); assertCommonAttributes(); assertEquals(1, mTestResult.mNumTestsRun); - assertEquals(null, mTestResult.mTestStatus); + assertEquals(0, mTestResult.mTestStatus); } /** - * Test basic parsing of failed test case. + * Test basic parsing of failed test case */ public void testTestFailed() { StringBuilder output = buildCommonResult(); @@ -91,12 +91,12 @@ public class InstrumentationResultParserTest extends TestCase { assertCommonAttributes(); assertEquals(1, mTestResult.mNumTestsRun); - assertEquals(ITestRunListener.TestFailure.FAILURE, mTestResult.mTestStatus); + assertEquals(ITestRunListener.STATUS_FAILURE, mTestResult.mTestStatus); assertEquals(STACK_TRACE, mTestResult.mTrace); } /** - * Test basic parsing and conversion of time from output. + * Test basic parsing and conversion of time from output */ public void testTimeParsing() { final String timeString = "Time: 4.9"; @@ -105,7 +105,7 @@ public class InstrumentationResultParserTest extends TestCase { } /** - * builds a common test result using TEST_NAME and TEST_CLASS. + * builds a common test result using TEST_NAME and TEST_CLASS */ private StringBuilder buildCommonResult() { StringBuilder output = new StringBuilder(); @@ -118,7 +118,7 @@ public class InstrumentationResultParserTest extends TestCase { } /** - * Adds common status results to the provided output. + * Adds common status results to the provided output */ private void addCommonStatus(StringBuilder output) { addStatusKey(output, "stream", "\r\n" + CLASS_NAME); @@ -130,7 +130,7 @@ public class InstrumentationResultParserTest extends TestCase { } /** - * Adds a stack trace status bundle to output. + * Adds a stack trace status bundle to output */ private void addStackTrace(StringBuilder output) { addStatusKey(output, "stack", STACK_TRACE); @@ -138,7 +138,7 @@ public class InstrumentationResultParserTest extends TestCase { } /** - * Helper method to add a status key-value bundle. + * Helper method to add a status key-value bundle */ private void addStatusKey(StringBuilder outputBuilder, String key, String value) { @@ -168,7 +168,7 @@ public class InstrumentationResultParserTest extends TestCase { } /** - * inject a test string into the result parser. + * inject a test string into the result parser * * @param result */ @@ -185,7 +185,7 @@ public class InstrumentationResultParserTest extends TestCase { } /** - * A specialized test listener that stores a single test events. + * A specialized test listener that stores a single test events */ private class VerifyingTestResult implements ITestRunListener { @@ -194,28 +194,29 @@ public class InstrumentationResultParserTest extends TestCase { int mNumTestsRun; String mTestName; long mTestTime; - TestFailure mTestStatus; + int mTestStatus; String mTrace; boolean mStopped; VerifyingTestResult() { mNumTestsRun = 0; - mTestStatus = null; + mTestStatus = 0; mStopped = false; } - public void testEnded(TestIdentifier test) { + public void testEnded(String className, String testName) { mNumTestsRun++; - assertEquals("Unexpected class name", mSuiteName, test.getClassName()); - assertEquals("Unexpected test ended", mTestName, test.getTestName()); + assertEquals("Unexpected class name", mSuiteName, className); + assertEquals("Unexpected test ended", mTestName, testName); } - public void testFailed(TestFailure status, TestIdentifier test, String trace) { + public void testFailed(int status, String className, String testName, + String trace) { mTestStatus = status; mTrace = trace; - assertEquals("Unexpected class name", mSuiteName, test.getClassName()); - assertEquals("Unexpected test ended", mTestName, test.getTestName()); + assertEquals("Unexpected class name", mSuiteName, className); + assertEquals("Unexpected test ended", mTestName, testName); } public void testRunEnded(long elapsedTime) { @@ -232,9 +233,9 @@ public class InstrumentationResultParserTest extends TestCase { mStopped = true; } - public void testStarted(TestIdentifier test) { - mSuiteName = test.getClassName(); - mTestName = test.getTestName(); + public void testStarted(String className, String testName) { + mSuiteName = className; + mTestName = testName; } public void testRunFailed(String errorMessage) { diff --git a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java index 9acaaf9..54ffae8 100644 --- a/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java +++ b/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java @@ -31,16 +31,16 @@ import java.io.IOException; import java.util.Map; /** - * Tests RemoteAndroidTestRunner. + * Test RemoteAndroidTestRunner. */ public class RemoteAndroidTestRunnerTest extends TestCase { private RemoteAndroidTestRunner mRunner; private MockDevice mMockDevice; - + private static final String TEST_PACKAGE = "com.test"; private static final String TEST_RUNNER = "com.test.InstrumentationTestRunner"; - + /** * @see junit.framework.TestCase#setUp() */ @@ -49,40 +49,40 @@ public class RemoteAndroidTestRunnerTest extends TestCase { mMockDevice = new MockDevice(); mRunner = new RemoteAndroidTestRunner(TEST_PACKAGE, TEST_RUNNER, mMockDevice); } - + /** - * Test the basic case building of the instrumentation runner command with no arguments. + * Test the basic case building of the instrumentation runner command with no arguments */ public void testRun() { mRunner.run(new EmptyListener()); - assertStringsEquals(String.format("am instrument -w -r %s/%s", TEST_PACKAGE, TEST_RUNNER), + assertStringsEquals(String.format("am instrument -w -r %s/%s", TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand()); } /** - * Test the building of the instrumentation runner command with log set. + * Test the building of the instrumentation runner command with log set */ public void testRunWithLog() { mRunner.setLogOnly(true); mRunner.run(new EmptyListener()); - assertStringsEquals(String.format("am instrument -w -r -e log true %s/%s", TEST_PACKAGE, + assertStringsEquals(String.format("am instrument -w -r -e log true %s/%s", TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand()); } /** - * Test the building of the instrumentation runner command with method set. + * Test the building of the instrumentation runner command with method set */ public void testRunWithMethod() { final String className = "FooTest"; final String testName = "fooTest"; mRunner.setMethodName(className, testName); mRunner.run(new EmptyListener()); - assertStringsEquals(String.format("am instrument -w -r -e class %s#%s %s/%s", className, + assertStringsEquals(String.format("am instrument -w -r -e class %s#%s %s/%s", className, testName, TEST_PACKAGE, TEST_RUNNER), mMockDevice.getLastShellCommand()); } - + /** - * Test the building of the instrumentation runner command with extra args set. + * Test the building of the instrumentation runner command with extra args set */ public void testRunWithExtraArgs() { final String extraArgs = "blah"; @@ -94,37 +94,37 @@ public class RemoteAndroidTestRunnerTest extends TestCase { /** - * Assert two strings are equal ignoring whitespace. + * Assert two strings are equal ignoring whitespace */ private void assertStringsEquals(String str1, String str2) { String strippedStr1 = str1.replaceAll(" ", ""); String strippedStr2 = str2.replaceAll(" ", ""); assertEquals(strippedStr1, strippedStr2); } - + /** - * A dummy device that does nothing except store the provided executed shell command for - * later retrieval. + * A dummy device that does nothing except store the provided executed shell command for + * later retrieval */ private static class MockDevice implements IDevice { private String mLastShellCommand; - + /** - * Stores the provided command for later retrieval from getLastShellCommand. + * Stores the provided command for later retrieval from getLastShellCommand */ public void executeShellCommand(String command, IShellOutputReceiver receiver) throws IOException { mLastShellCommand = command; } - + /** - * Get the last command provided to executeShellCommand. + * Get the last command provided to executeShellCommand */ public String getLastShellCommand() { return mLastShellCommand; } - + public boolean createForward(int localPort, int remotePort) { throw new UnsupportedOperationException(); } @@ -201,26 +201,22 @@ public class RemoteAndroidTestRunnerTest extends TestCase { throw new UnsupportedOperationException(); } - public void runLogService(String logname, LogReceiver receiver) throws IOException { - throw new UnsupportedOperationException(); - } - public String getAvdName() { return ""; } } - - /** - * An empty implementation of ITestRunListener. + + /** An empty implementation of TestRunListener */ private static class EmptyListener implements ITestRunListener { - public void testEnded(TestIdentifier test) { + public void testEnded(String className, String testName) { // ignore } - public void testFailed(TestFailure status, TestIdentifier test, String trace) { + public void testFailed(int status, String className, String testName, + String trace) { // ignore } @@ -240,9 +236,9 @@ public class RemoteAndroidTestRunnerTest extends TestCase { // ignore } - public void testStarted(TestIdentifier test) { + public void testStarted(String className, String testName) { // ignore } - + } } diff --git a/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java b/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java index 46461bf..149d689 100644 --- a/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java +++ b/ddms/libs/ddmuilib/src/com/android/ddmuilib/NativeHeapPanel.java @@ -237,7 +237,7 @@ public final class NativeHeapPanel extends BaseHeapPanel { */ private HashMap<Long, NativeStackCallInfo> mSourceCache = new HashMap<Long,NativeStackCallInfo>(); - private long mTotalSize; + private int mTotalSize; private Button mSaveButton; private Button mSymbolsButton; diff --git a/draw9patch/etc/draw9patch.bat b/draw9patch/etc/draw9patch.bat index e267b06..1d56d85 100755 --- a/draw9patch/etc/draw9patch.bat +++ b/draw9patch/etc/draw9patch.bat @@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks, rem and set up progdir to be the fully-qualified pathname of its directory. set prog=%~f0 -rem Change current directory and drive to where the script is, to avoid -rem issues with directories containing whitespaces. -cd /d %~dp0 +rem Change current directory to where ddms is, to avoid issues with directories +rem containing whitespaces. +cd %~dp0 set jarfile=draw9patch.jar set frameworkdir= diff --git a/eclipse/changes.txt b/eclipse/changes.txt index 781930c..5cb8245 100644 --- a/eclipse/changes.txt +++ b/eclipse/changes.txt @@ -1,18 +1,14 @@ 0.9.0 (work in progress) -- 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. - * Project properties (right click project in Package Explorer, then "Properties"), lets you edit project target. - * New Launch configuration option to choose debug deployment target. -- Ability to export multiple apk from one project, using resource filters. See the 'android' property for Android projects. +- Support for SDK with multiple versions of the Android platform and vendor supplied add-ons. 0.8.1: -- Alternate Layout wizard. In the layout editor, the "create" button is now enabled to easily create alternate versions of the current layout. +- Alternate Layout wizard. In the layout editor, the "create" button is now enabled, and allows to easily create alternate versions. - Fixed issue with custom themes/styles in the layout editor. -- Export Wizard: To export an application for release, and sign it with a non debug key. Accessible from the export menu, from the Android Tools contextual menu, or from the overview page of the manifest editor. +- Export Wizard: To export an application for release, sign with a non debug key. Accessible from the export menu, from the Android Tools contextual menu, or from the overview page of the manifest editor. - New XML File Wizard: To easily create new XML resources file in the /res directory. - New checks on launch when attempting to debug on a device. -- Basic support for drag'n'drop in Graphical layout editor. You can add new items by drag'n'drop from the palette. There is no support for moving/resizing yet. +- Basic support for drag'n'drop in Graphical layout editor. You can add new items by drag'n'drop from the palette. There's is no support for moving/resizing yet. - Undo/redo support in all XML form editors and Graphical layout editor. 0.8.0: diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png b/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png Binary files differdeleted file mode 100644 index 0f0e883..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_adt_project.png +++ /dev/null diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png b/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png Binary files differdeleted file mode 100644 index 8273185..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/icons/new_xml.png +++ /dev/null diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml index d6c9ac1..f7c366d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml +++ b/eclipse/plugins/com.android.ide.eclipse.adt/plugin.xml @@ -18,14 +18,6 @@ <persistent value="true"/> </extension> <extension - id="com.android.ide.eclipse.common.aapt2Problem" - name="Android AAPT Problem" - point="org.eclipse.core.resources.markers"> - <super type="org.eclipse.core.resources.problemmarker"/> - <super type="org.eclipse.core.resources.textmarker"/> - <persistent value="true"/> - </extension> - <extension id="com.android.ide.eclipse.common.aidlProblem" name="Android AIDL Problem" point="org.eclipse.core.resources.markers"> @@ -472,31 +464,4 @@ </enabledWhen> </page> </extension> - <extension - point="org.eclipse.ui.actionSets"> - <actionSet - description="Android Wizards" - id="adt.actionSet1" - label="Android Wizards" - visible="true"> - <action - class="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction" - icon="icons/new_adt_project.png" - id="com.android.ide.eclipse.adt.wizards.actions.NewProjectAction" - label="New Android Project" - style="push" - toolbarPath="android_project" - tooltip="Opens a wizard to help create a new Android project"> - </action> - <action - class="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction" - icon="icons/new_xml.png" - id="com.android.ide.eclipse.adt.wizards.actions.NewXmlFileAction" - label="New Android XML File" - style="push" - toolbarPath="android_project" - tooltip="Opens a wizard to help create a new Android XML file"> - </action> - </actionSet> - </extension> </plugin> diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java index 61be3e5..9aa9354 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/AdtPlugin.java @@ -28,7 +28,6 @@ import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerIni 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.common.AndroidConstants; import com.android.ide.eclipse.common.EclipseUiHelper; import com.android.ide.eclipse.common.SdkStatsHelper; @@ -174,8 +173,7 @@ public class AdtPlugin extends AbstractUIPlugin { private final ArrayList<IJavaProject> mPostLoadProjectsToCheck = new ArrayList<IJavaProject>(); private ResourceMonitor mResourceMonitor; - private ArrayList<ITargetChangeListener> mTargetChangeListeners = - new ArrayList<ITargetChangeListener>(); + private ArrayList<Runnable> mResourceRefreshListener = new ArrayList<Runnable>(); /** * Custom PrintStream for Dx output. This class overrides the method @@ -863,6 +861,7 @@ public class AdtPlugin extends AbstractUIPlugin { /** * Returns the lock object for SDK loading. If you wish to do things while the SDK is loading, * you must synchronize on this object. + * @return */ public final Object getSdkLockObject() { return mPostLoadProjectsToResolve; @@ -987,7 +986,7 @@ public class AdtPlugin extends AbstractUIPlugin { Constants.BUNDLE_VERSION); Version version = new Version(versionString); - SdkStatsHelper.pingUsageServer("adt", version); //$NON-NLS-1$ + SdkStatsHelper.pingUsageServer("editors", version); //$NON-NLS-1$ return Status.OK_STATUS; } catch (Throwable t) { @@ -1020,27 +1019,24 @@ public class AdtPlugin extends AbstractUIPlugin { progress.setTaskName(Messages.AdtPlugin_Parsing_Resources); - int n = sdk.getTargets().length; - if (n > 0) { - int w = 60 / n; - for (IAndroidTarget target : sdk.getTargets()) { - SubMonitor p2 = progress.newChild(w); - IStatus status = new AndroidTargetParser(target).run(p2); - if (status.getCode() != IStatus.OK) { - synchronized (getSdkLockObject()) { - mSdkIsLoaded = LoadStatus.FAILED; - mPostLoadProjectsToResolve.clear(); - } - return status; + for (IAndroidTarget target : sdk.getTargets()) { + IStatus status = new AndroidTargetParser(target).run(progress); + if (status.getCode() != IStatus.OK) { + synchronized (getSdkLockObject()) { + mSdkIsLoaded = LoadStatus.FAILED; + mPostLoadProjectsToResolve.clear(); } + return status; } } + // FIXME: move this per platform, or somewhere else. + progress = SubMonitor.convert(monitor, + Messages.AdtPlugin_Parsing_Resources, 20); + synchronized (getSdkLockObject()) { mSdkIsLoaded = LoadStatus.LOADED; - progress.setTaskName("Check Projects"); - // check the projects that need checking. // The method modifies the list (it removes the project that // do not need to be resolved again). @@ -1056,33 +1052,25 @@ public class AdtPlugin extends AbstractUIPlugin { AndroidClasspathContainerInitializer.updateProjects(array); mPostLoadProjectsToResolve.clear(); } - - progress.worked(10); } } // Notify resource changed listeners - progress.setTaskName("Refresh UI"); - progress.setWorkRemaining(mTargetChangeListeners.size()); + progress.subTask("Refresh UI"); + progress.setWorkRemaining(mResourceRefreshListener.size()); // Clone the list before iterating, to avoid Concurrent Modification // exceptions - final List<ITargetChangeListener> listeners = - (List<ITargetChangeListener>)mTargetChangeListeners.clone(); - final SubMonitor progress2 = progress; - AdtPlugin.getDisplay().syncExec(new Runnable() { - public void run() { - for (ITargetChangeListener listener : listeners) { - try { - listener.onTargetsLoaded(); - } catch (Exception e) { - AdtPlugin.log(e, "Failed to update a TargetChangeListener."); //$NON-NLS-1$ - } finally { - progress2.worked(1); - } - } + List<Runnable> listeners = (List<Runnable>)mResourceRefreshListener.clone(); + for (Runnable listener : listeners) { + try { + AdtPlugin.getDisplay().syncExec(listener); + } catch (Exception e) { + AdtPlugin.log(e, "ResourceRefreshListener Failed"); //$NON-NLS-1$ + } finally { + progress.worked(1); } - }); + } } finally { if (monitor != null) { monitor.done(); @@ -1328,42 +1316,12 @@ public class AdtPlugin extends AbstractUIPlugin { }, IResourceDelta.ADDED | IResourceDelta.CHANGED); } - /** - * Adds a new {@link ITargetChangeListener} to be notified when a new SDK is loaded, or when - * a project has its target changed. - */ - public void addTargetListener(ITargetChangeListener listener) { - mTargetChangeListeners.add(listener); - } - - /** - * Removes an existing {@link ITargetChangeListener}. - * @see #addTargetListener(ITargetChangeListener) - */ - public void removeTargetListener(ITargetChangeListener listener) { - mTargetChangeListeners.remove(listener); + public void addResourceChangedListener(Runnable resourceRefreshListener) { + mResourceRefreshListener.add(resourceRefreshListener); } - /** - * Updates all the {@link ITargetChangeListener} that a target has changed for a given project. - * <p/>Only editors related to that project should reload. - */ - @SuppressWarnings("unchecked") - public void updateTargetListener(final IProject project) { - final List<ITargetChangeListener> listeners = - (List<ITargetChangeListener>)mTargetChangeListeners.clone(); - - AdtPlugin.getDisplay().asyncExec(new Runnable() { - public void run() { - for (ITargetChangeListener listener : listeners) { - try { - listener.onProjectTargetChange(project); - } catch (Exception e) { - AdtPlugin.log(e, "Failed to update a TargetChangeListener."); //$NON-NLS-1$ - } - } - } - }); + public void removeResourceChangedListener(Runnable resourceRefreshListener) { + mResourceRefreshListener.remove(resourceRefreshListener); } public static synchronized OutputStream getErrorStream() { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java index e71ae47..96068c2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/ApkBuilder.java @@ -203,9 +203,6 @@ public class ApkBuilder extends BaseBuilder { // get a project object IProject project = getProject(); - // Top level check to make sure the build can move forward. - abortOnBadSetup(project); - // get the list of referenced projects. IProject[] referencedProjects = ProjectHelper.getReferencedProjects(project); IJavaProject[] referencedJavaProjects = getJavaProjects(referencedProjects); @@ -265,79 +262,19 @@ public class ApkBuilder extends BaseBuilder { } } } - - // store the build status in the persistent storage - saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX , mConvertToDex); - saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources); - saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage); - - if (dv != null && dv.mXmlError) { - AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, - Messages.Xml_Error); - - // if there was some XML errors, we just return w/o doing - // anything since we've put some markers in the files anyway - return referencedProjects; - } - - if (outputFolder == null) { - // mark project and exit - markProject(AdtConstants.MARKER_ADT, Messages.Failed_To_Get_Output, - IMarker.SEVERITY_ERROR); - return referencedProjects; - } - - // first thing we do is check that the SDK directory has been setup. - String osSdkFolder = AdtPlugin.getOsSdkFolder(); - - if (osSdkFolder.length() == 0) { - // this has already been checked in the precompiler. Therefore, - // while we do have to cancel the build, we don't have to return - // any error or throw anything. - return referencedProjects; - } - - // get the extra configs for the project. - // The map contains (name, filter) where 'name' is a name to be used in the apk filename, - // and filter is the resource filter to be used in the aapt -c parameters to restrict - // which resource configurations to package in the apk. - Map<String, String> configs = Sdk.getCurrent().getProjectApkConfigs(project); // do some extra check, in case the output files are not present. This // will force to recreate them. IResource tmp = null; - if (mPackageResources == false) { - // check the full resource package + if (mPackageResources == false && outputFolder != null) { tmp = outputFolder.findMember(AndroidConstants.FN_RESOURCES_AP_); if (tmp == null || tmp.exists() == false) { mPackageResources = true; mBuildFinalPackage = true; - } else { - // if the full package is present, we check the filtered resource packages as well - if (configs != null) { - Set<Entry<String, String>> entrySet = configs.entrySet(); - - for (Entry<String, String> entry : entrySet) { - String filename = String.format(AndroidConstants.FN_RESOURCES_S_AP_, - entry.getKey()); - - tmp = outputFolder.findMember(filename); - if (tmp == null || (tmp instanceof IFile && - tmp.exists() == false)) { - String msg = String.format(Messages.s_Missing_Repackaging, filename); - AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg); - mPackageResources = true; - mBuildFinalPackage = true; - break; - } - } - } } } - - // check classes.dex is present. If not we force to recreate it. - if (mConvertToDex == false) { + if (mConvertToDex == false && outputFolder != null) { tmp = outputFolder.findMember(AndroidConstants.FN_CLASSES_DEX); if (tmp == null || tmp.exists() == false) { mConvertToDex = true; @@ -345,17 +282,22 @@ public class ApkBuilder extends BaseBuilder { } } + // get the extra configs for the project. This will give us a list of custom apk + // to build based on a restricted set of resources. + Map<String, String> configs = Sdk.getCurrent().getProjectApkConfigs(project); + // also check the final file(s)! String finalPackageName = getFileName(project, null /*config*/); - if (mBuildFinalPackage == false) { + if (mBuildFinalPackage == false && outputFolder != null) { tmp = outputFolder.findMember(finalPackageName); if (tmp == null || (tmp instanceof IFile && tmp.exists() == false)) { String msg = String.format(Messages.s_Missing_Repackaging, finalPackageName); AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg); mBuildFinalPackage = true; - } else if (configs != null) { - // if the full apk is present, we check the filtered apk as well + } + + if (configs != null) { Set<Entry<String, String>> entrySet = configs.entrySet(); for (Entry<String, String> entry : entrySet) { @@ -364,7 +306,8 @@ public class ApkBuilder extends BaseBuilder { tmp = outputFolder.findMember(filename); if (tmp == null || (tmp instanceof IFile && tmp.exists() == false)) { - String msg = String.format(Messages.s_Missing_Repackaging, filename); + String msg = String.format(Messages.s_Missing_Repackaging, + finalPackageName); AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, msg); mBuildFinalPackage = true; break; @@ -373,6 +316,41 @@ public class ApkBuilder extends BaseBuilder { } } + // store the build status in the persistent storage + saveProjectBooleanProperty(PROPERTY_CONVERT_TO_DEX , mConvertToDex); + saveProjectBooleanProperty(PROPERTY_PACKAGE_RESOURCES, mPackageResources); + saveProjectBooleanProperty(PROPERTY_BUILD_APK, mBuildFinalPackage); + + // At this point, we can abort the build if we have to, as we have computed + // our resource delta and stored the result. + abortOnBadSetup(project); + + if (dv != null && dv.mXmlError) { + AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, + Messages.Xml_Error); + + // if there was some XML errors, we just return w/o doing + // anything since we've put some markers in the files anyway + return referencedProjects; + } + + if (outputFolder == null) { + // mark project and exit + markProject(AdtConstants.MARKER_ADT, Messages.Failed_To_Get_Output, + IMarker.SEVERITY_ERROR); + return referencedProjects; + } + + // first thing we do is check that the SDK directory has been setup. + String osSdkFolder = AdtPlugin.getOsSdkFolder(); + + if (osSdkFolder.length() == 0) { + // this has already been checked in the precompiler. Therefore, + // while we do have to cancel the build, we don't have to return + // any error or throw anything. + return referencedProjects; + } + // at this point we know if we need to recreate the temporary apk // or the dex file, but we don't know if we simply need to recreate them // because they are missing @@ -418,9 +396,6 @@ public class ApkBuilder extends BaseBuilder { // first we check if we need to package the resources. if (mPackageResources) { - // remove some aapt_package only markers. - removeMarkersFromContainer(project, AndroidConstants.MARKER_AAPT_PACKAGE); - // need to figure out some path before we can execute aapt; // resource to the AndroidManifest.xml file @@ -577,8 +552,7 @@ public class ApkBuilder extends BaseBuilder { * @param osAssetsPath The path to the assets folder. This can be null. * @param osOutFilePath The path to the temporary resource file to create. * @param configFilter The configuration filter for the resources to include - * (used with -c option, for example "port,en,fr" to include portrait, English and French - * resources.) + * (used with -c option) * @return true if success, false otherwise. */ private boolean executeAapt(IProject project, String osManifestPath, diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java index e2e9728..6b0810a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/BaseBuilder.java @@ -149,15 +149,6 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { private final static Pattern sPattern8Line1 = Pattern.compile( "^(invalid resource directory name): (.*)$"); //$NON-NLS-1$ - /** - * 2 line aapt error<br> - * "ERROR: Invalid configuration: foo"<br> - * " ^^^"<br> - * There's no need to parse the 2nd line. - */ - private final static Pattern sPattern9Line1 = Pattern.compile( - "^Invalid configuration: (.+)$"); //$NON-NLS-1$ - /** SAX Parser factory. */ private SAXParserFactory mParserFactory; @@ -449,8 +440,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { String location = m.group(1); // check the values and attempt to mark the file. - if (checkAndMark(location, lineStr, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) { + if (checkAndMark(location, lineStr, msg, osRoot, + project, IMarker.SEVERITY_ERROR) == false) { return true; } continue; @@ -474,7 +465,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { // display the error if (checkAndMark(location, null, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) { + IMarker.SEVERITY_ERROR) == false) { return true; } @@ -497,8 +488,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { String lineStr = m.group(2); // check the values and attempt to mark the file. - if (checkAndMark(location, lineStr, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) { + if (checkAndMark(location, lineStr, msg, osRoot, + project, IMarker.SEVERITY_ERROR) == false) { return true; } continue; @@ -511,8 +502,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { String msg = m.group(3); // check the values and attempt to mark the file. - if (checkAndMark(location, lineStr, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) { + if (checkAndMark(location, lineStr, msg, osRoot, + project, IMarker.SEVERITY_ERROR) == false) { return true; } @@ -535,8 +526,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { String lineStr = m.group(2); // check the values and attempt to mark the file. - if (checkAndMark(location, lineStr, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) { + if (checkAndMark(location, lineStr, msg, osRoot, + project, IMarker.SEVERITY_ERROR) == false) { return true; } @@ -551,8 +542,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { String msg = m.group(3); // check the values and attempt to mark the file. - if (checkAndMark(location, lineStr, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_WARNING) == false) { + if (checkAndMark(location, lineStr, msg, osRoot, + project,IMarker.SEVERITY_WARNING) == false) { return true; } @@ -567,8 +558,8 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { String msg = m.group(3); // check the values and attempt to mark the file. - if (checkAndMark(location, lineStr, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) { + if (checkAndMark(location, lineStr, msg, osRoot, + project, IMarker.SEVERITY_ERROR) == false) { return true; } @@ -583,25 +574,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { // check the values and attempt to mark the file. if (checkAndMark(location, null, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_COMPILE, IMarker.SEVERITY_ERROR) == false) { - return true; - } - - // success, go to the next line - continue; - } - - m = sPattern9Line1.matcher(p); - 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++; - - // check the values and attempt to mark the file. - if (checkAndMark(null /*location*/, null, msg, osRoot, project, - AndroidConstants.MARKER_AAPT_PACKAGE, IMarker.SEVERITY_ERROR) == false) { + IMarker.SEVERITY_ERROR) == false) { return true; } @@ -686,25 +659,23 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { /** * Check if the parameters gotten from the error output are valid, and mark * the file with an AAPT marker. - * @param location the full OS path of the error file. If null, the project is marked + * @param location * @param lineStr * @param message * @param root The root directory of the project, in OS specific format. * @param project - * @param markerId The marker id to put. * @param severity The severity of the marker to put (IMarker.SEVERITY_*) - * @return true if the parameters were valid and the file was marked successfully. + * @return true if the parameters were valid and the file was marked + * sucessfully. * * @see IMarker */ private final boolean checkAndMark(String location, String lineStr, - String message, String root, IProject project, String markerId, int severity) { + String message, String root, IProject project, int severity) { // check this is in fact a file - if (location != null) { - File f = new File(location); - if (f.exists() == false) { - return false; - } + File f = new File(location); + if (f.exists() == false) { + return false; } // get the line number @@ -721,18 +692,16 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { } // add the marker - IResource f2 = project; - if (location != null) { - f2 = getResourceFromFullPath(location, root, project); - if (f2 == null) { - return false; - } + IResource f2 = getResourceFromFullPath(location, root, project); + if (f2 == null) { + return false; } // check if there's a similar marker already, since aapt is launched twice boolean markerAlreadyExists = false; try { - IMarker[] markers = f2.findMarkers(markerId, true, IResource.DEPTH_ZERO); + IMarker[] markers = f2.findMarkers(AndroidConstants.MARKER_AAPT, true, + IResource.DEPTH_ZERO); for (IMarker marker : markers) { int tmpLine = marker.getAttribute(IMarker.LINE_NUMBER, -1); @@ -763,10 +732,10 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { if (markerAlreadyExists == false) { if (line != -1) { - BaseProjectHelper.addMarker(f2, markerId, message, line, + BaseProjectHelper.addMarker(f2, AndroidConstants.MARKER_AAPT, message, line, severity); } else { - BaseProjectHelper.addMarker(f2, markerId, message, severity); + BaseProjectHelper.addMarker(f2, AndroidConstants.MARKER_AAPT, message, severity); } } @@ -882,7 +851,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { * Aborts the build if the SDK/project setups are broken. This does not * display any errors. * - * @param project The {@link IJavaProject} being compiled. + * @param javaProject The {@link IJavaProject} being compiled. * @throws CoreException */ protected final void abortOnBadSetup(IProject project) throws CoreException { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/DexWrapper.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/DexWrapper.java index 65ad4f5..26d96d7 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/DexWrapper.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/DexWrapper.java @@ -57,11 +57,8 @@ public final class DexWrapper { private Field mConsoleErr; /** - * Loads the dex library from a file path. - * - * The loaded library can be used via - * {@link DexWrapper#run(String, String[], boolean, PrintStream, PrintStream)}. - * + * Loads the dex library from a file path. The loaded library can be used with the + * {@link DexWrapper} object returned by {@link #getWrapper()} * @param osFilepath the location of the dex.jar file. * @return an IStatus indicating the result of the load. */ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java index a0e446c..958cac2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java @@ -234,10 +234,6 @@ public class PreCompilerBuilder extends BaseBuilder { // get the project objects IProject project = getProject(); - - // Top level check to make sure the build can move forward. - abortOnBadSetup(project); - IJavaProject javaProject = JavaCore.create(project); IAndroidTarget projectTarget = Sdk.getCurrent().getTarget(project); @@ -288,6 +284,10 @@ public class PreCompilerBuilder extends BaseBuilder { saveProjectBooleanProperty(PROPERTY_COMPILE_RESOURCES , mCompileResources); // TODO also needs to store the list of aidl to compile/remove + // At this point we have stored what needs to be build, so we can + // do some high level test and abort if needed. + abortOnBadSetup(project); + // 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) { @@ -381,7 +381,7 @@ public class PreCompilerBuilder extends BaseBuilder { // mark the manifest file String message = String.format(Messages.Package_s_Doesnt_Exist_Error, mManifestPackage); - BaseProjectHelper.addMarker(manifest, AndroidConstants.MARKER_AAPT_COMPILE, message, + BaseProjectHelper.addMarker(manifest, AndroidConstants.MARKER_AAPT, message, IMarker.SEVERITY_ERROR); AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, message); @@ -409,8 +409,8 @@ public class PreCompilerBuilder extends BaseBuilder { String osManifestPath = manifestLocation.toOSString(); // remove the aapt markers - removeMarkersFromFile(manifest, AndroidConstants.MARKER_AAPT_COMPILE); - removeMarkersFromContainer(resFolder, AndroidConstants.MARKER_AAPT_COMPILE); + removeMarkersFromFile(manifest, AndroidConstants.MARKER_AAPT); + removeMarkersFromContainer(resFolder, AndroidConstants.MARKER_AAPT); AdtPlugin.printBuildToConsole(AdtConstants.BUILD_VERBOSE, project, Messages.Preparing_Generated_Files); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/AndroidPreferencePage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/AndroidPreferencePage.java index 458f78e..c27c106 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/AndroidPreferencePage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/AndroidPreferencePage.java @@ -17,19 +17,11 @@ package com.android.ide.eclipse.adt.preferences; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.sdk.Sdk; -import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener; -import com.android.sdklib.IAndroidTarget; -import com.android.sdkuilib.SdkTargetSelector; -import org.eclipse.core.resources.IProject; import org.eclipse.jface.preference.DirectoryFieldEditor; import org.eclipse.jface.preference.FieldEditorPreferencePage; import org.eclipse.jface.resource.JFaceResources; -import org.eclipse.swt.SWT; -import org.eclipse.swt.layout.GridData; import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Text; import org.eclipse.ui.IWorkbench; import org.eclipse.ui.IWorkbenchPreferencePage; @@ -88,9 +80,6 @@ public class AndroidPreferencePage extends FieldEditorPreferencePage implements */ private static class SdkDirectoryFieldEditor extends DirectoryFieldEditor { - private SdkTargetSelector mTargetSelector; - private TargetChangedListener mTargetChangeListener; - public SdkDirectoryFieldEditor(String name, String labelText, Composite parent) { super(name, labelText, parent); setEmptyStringAllowed(false); @@ -142,68 +131,5 @@ public class AndroidPreferencePage extends FieldEditorPreferencePage implements setValidateStrategy(VALIDATE_ON_KEY_STROKE); return super.getTextControl(parent); } - - /* (non-Javadoc) - * Method declared on StringFieldEditor (and FieldEditor). - */ - @Override - protected void doFillIntoGrid(Composite parent, int numColumns) { - super.doFillIntoGrid(parent, numColumns); - - GridData gd; - Label l = new Label(parent, SWT.NONE); - l.setText("Note: The list of SDK Targets below is only reloaded once you hit 'Apply' or 'OK'."); - gd = new GridData(GridData.FILL_HORIZONTAL); - gd.horizontalSpan = numColumns; - l.setLayoutData(gd); - - try { - // We may not have an sdk if the sdk path pref is empty or not valid. - Sdk sdk = Sdk.getCurrent(); - IAndroidTarget[] targets = sdk != null ? sdk.getTargets() : null; - - mTargetSelector = new SdkTargetSelector(parent, - targets, - false, /*allowSelection*/ - false /*multipleSelection*/); - gd = (GridData) mTargetSelector.getLayoutData(); - gd.horizontalSpan = numColumns; - - if (mTargetChangeListener == null) { - mTargetChangeListener = new TargetChangedListener(); - AdtPlugin.getDefault().addTargetListener(mTargetChangeListener); - } - } catch (Exception e) { - // We need to catch *any* exception that arises here, otherwise it disables - // the whole pref panel. We can live without the Sdk target selector but - // not being able to actually set an sdk path. - AdtPlugin.log(e, "SdkTargetSelector failed"); - } - } - - @Override - public void dispose() { - super.dispose(); - if (mTargetChangeListener != null) { - AdtPlugin.getDefault().removeTargetListener(mTargetChangeListener); - mTargetChangeListener = null; - } - } - - private class TargetChangedListener implements ITargetChangeListener { - public void onProjectTargetChange(IProject changedProject) { - // do nothing. - } - - public void onTargetsLoaded() { - if (mTargetSelector != null) { - // We may not have an sdk if the sdk path pref is empty or not valid. - Sdk sdk = Sdk.getCurrent(); - IAndroidTarget[] targets = sdk != null ? sdk.getTargets() : null; - - mTargetSelector.setTargets(targets); - } - } - } } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java index d686830..339dcd0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java @@ -266,6 +266,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit // We schedule a new job to put the marker after. final String fmessage = markerMessage; Job markerJob = new Job("Android SDK: Resolving error markers") { + @SuppressWarnings("unchecked") @Override protected IStatus run(IProgressMonitor monitor) { try { @@ -295,6 +296,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit // In some cases, the workspace may be locked for modification when we pass // here, so we schedule a new job to put the marker after. Job markerJob = new Job("Android SDK: Resolving error markers") { + @SuppressWarnings("unchecked") @Override protected IStatus run(IProgressMonitor monitor) { try { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/properties/AndroidPropertyPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/properties/AndroidPropertyPage.java index a4c019f..584dd0d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/properties/AndroidPropertyPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/properties/AndroidPropertyPage.java @@ -18,7 +18,6 @@ package com.android.ide.eclipse.adt.project.properties; import com.android.ide.eclipse.adt.sdk.Sdk; import com.android.sdklib.IAndroidTarget; -import com.android.sdkuilib.ApkConfigWidget; import com.android.sdkuilib.SdkTargetSelector; import org.eclipse.core.resources.IProject; @@ -33,8 +32,6 @@ import org.eclipse.swt.widgets.Label; import org.eclipse.ui.IWorkbenchPropertyPage; import org.eclipse.ui.dialogs.PropertyPage; -import java.util.Map; - /** * Property page for "Android" project. * This is accessible from the Package Explorer when right clicking a project and choosing @@ -45,7 +42,6 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope private IProject mProject; private SdkTargetSelector mSelector; - private ApkConfigWidget mApkConfigWidget; public AndroidPropertyPage() { // pass @@ -55,14 +51,7 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope protected Control createContents(Composite parent) { // get the element (this is not yet valid in the constructor). mProject = (IProject)getElement(); - - // get the targets from the sdk - IAndroidTarget[] targets = null; - if (Sdk.getCurrent() != null) { - targets = Sdk.getCurrent().getTargets(); - } - - // build the UI. + Composite top = new Composite(parent, SWT.NONE); top.setLayoutData(new GridData(GridData.FILL_BOTH)); top.setLayout(new GridLayout(1, false)); @@ -70,28 +59,20 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope Label l = new Label(top, SWT.NONE); l.setText("Project Target"); + // get the targets from the sdk + IAndroidTarget[] targets = null; + if (Sdk.getCurrent() != null) { + targets = Sdk.getCurrent().getTargets(); + } + + // build the UI. mSelector = new SdkTargetSelector(top, targets, false /*allowMultipleSelection*/); - l = new Label(top, SWT.SEPARATOR | SWT.HORIZONTAL); - l.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - l = new Label(top, SWT.NONE); - l.setText("Project APK Configurations"); - - mApkConfigWidget = new ApkConfigWidget(top); - - // fill the ui - Sdk currentSdk = Sdk.getCurrent(); - if (currentSdk != null && mProject.isOpen()) { - // get the target - IAndroidTarget target = currentSdk.getTarget(mProject); + if (Sdk.getCurrent() != null) { + IAndroidTarget target = Sdk.getCurrent().getTarget(mProject); if (target != null) { mSelector.setSelection(target); } - - // get the apk configurations - Map<String, String> configs = currentSdk.getProjectApkConfigs(mProject); - mApkConfigWidget.fillTable(configs); } mSelector.setSelectionListener(new SelectionAdapter() { @@ -102,20 +83,14 @@ public class AndroidPropertyPage extends PropertyPage implements IWorkbenchPrope setValid(target != null); } }); - - if (mProject.isOpen() == false) { - // disable the ui. - } return top; } @Override public boolean performOk() { - Sdk currentSdk = Sdk.getCurrent(); - if (currentSdk != null) { - currentSdk.setProject(mProject, mSelector.getFirstSelected(), - mApkConfigWidget.getApkConfigs()); + if (Sdk.getCurrent() != null) { + Sdk.getCurrent().setProject(mProject, mSelector.getFirstSelected()); } return true; diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetData.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetData.java index a8852e7..2309181 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetData.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetData.java @@ -27,7 +27,6 @@ import com.android.ide.eclipse.editors.resources.manager.ProjectResources; import com.android.ide.eclipse.editors.xml.descriptors.XmlDescriptors; import com.android.layoutlib.api.ILayoutBridge; import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.IAndroidTarget.IOptionalLibrary; import java.util.Hashtable; import java.util.Map; @@ -44,7 +43,6 @@ public class AndroidTargetData { public final static int DESCRIPTOR_RESOURCES = 5; public final static int DESCRIPTOR_SEARCHABLE = 6; public final static int DESCRIPTOR_PREFERENCES = 7; - public final static int DESCRIPTOR_GADGET_PROVIDER = 8; public final static class LayoutBridge { /** Link to the layout bridge */ @@ -53,8 +51,6 @@ public class AndroidTargetData { public LoadStatus status = LoadStatus.LOADING; public ClassLoader classLoader; - - public int apiLevel; } private final IAndroidTarget mTarget; @@ -97,7 +93,6 @@ public class AndroidTargetData { /** * Creates an AndroidTargetData object. - * @param optionalLibraries */ void setExtraData(IResourceRepository systemResourceRepository, AndroidManifestDescriptors manifestDescriptors, @@ -110,7 +105,6 @@ public class AndroidTargetData { String[] broadcastIntentActionValues, String[] serviceIntentActionValues, String[] intentCategoryValues, - IOptionalLibrary[] optionalLibraries, ProjectResources resources, LayoutBridge layoutBridge) { @@ -126,9 +120,8 @@ public class AndroidTargetData { setPermissions(permissionValues); setIntentFilterActionsAndCategories(activityIntentActionValues, broadcastIntentActionValues, serviceIntentActionValues, intentCategoryValues); - setOptionalLibraries(optionalLibraries); } - + public DexWrapper getDexWrapper() { return mDexWrapper; } @@ -158,8 +151,6 @@ public class AndroidTargetData { return ResourcesDescriptors.getInstance(); case DESCRIPTOR_PREFERENCES: return mXmlDescriptors.getPreferencesProvider(); - case DESCRIPTOR_GADGET_PROVIDER: - return mXmlDescriptors.getGadgetProvider(); case DESCRIPTOR_SEARCHABLE: return mXmlDescriptors.getSearchableProvider(); default : @@ -292,20 +283,6 @@ public class AndroidTargetData { setValues("(service,action,android:name)", serviceIntentActions); //$NON-NLS-1$ setValues("(category,android:name)", intentCategoryValues); //$NON-NLS-1$ } - - private void setOptionalLibraries(IOptionalLibrary[] optionalLibraries) { - String[] values; - - if (optionalLibraries == null) { - values = new String[0]; - } else { - values = new String[optionalLibraries.length]; - for (int i = 0; i < optionalLibraries.length; i++) { - values[i] = optionalLibraries[i].getName(); - } - } - setValues("(uses-library,android:name)", values); - } /** * Sets a (name, values) pair in the hash map. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java index 04baeba..aab660d 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java @@ -92,7 +92,7 @@ public final class AndroidTargetParser { try { SubMonitor progress = SubMonitor.convert(monitor, String.format("Parsing SDK %1$s", mAndroidTarget.getName()), - 14); + 200); AndroidTargetData targetData = new AndroidTargetData(mAndroidTarget); @@ -107,14 +107,15 @@ public final class AndroidTargetParser { // we have loaded dx. targetData.setDexWrapper(dexWrapper); - progress.worked(1); // parse the rest of the data. + progress.setWorkRemaining(120); AndroidJarLoader classLoader = new AndroidJarLoader(mAndroidTarget.getPath(IAndroidTarget.ANDROID_JAR)); preload(classLoader, progress.newChild(40, SubMonitor.SUPPRESS_NONE)); + progress.setWorkRemaining(80); if (progress.isCanceled()) { return Status.CANCEL_STATUS; @@ -123,7 +124,7 @@ public final class AndroidTargetParser { // get the resource Ids. progress.subTask("Resource IDs"); IResourceRepository frameworkRepository = collectResourceIds(classLoader); - progress.worked(1); + progress.worked(5); if (progress.isCanceled()) { return Status.CANCEL_STATUS; @@ -132,7 +133,7 @@ public final class AndroidTargetParser { // get the permissions progress.subTask("Permissions"); String[] permissionValues = collectPermissions(classLoader); - progress.worked(1); + progress.worked(5); if (progress.isCanceled()) { return Status.CANCEL_STATUS; @@ -146,7 +147,7 @@ public final class AndroidTargetParser { ArrayList<String> categories = new ArrayList<String>(); collectIntentFilterActionsAndCategories(activity_actions, broadcast_actions, service_actions, categories); - progress.worked(1); + progress.worked(5); if (progress.isCanceled()) { return Status.CANCEL_STATUS; @@ -157,14 +158,12 @@ public final class AndroidTargetParser { AttrsXmlParser attrsXmlParser = new AttrsXmlParser( mAndroidTarget.getPath(IAndroidTarget.ATTRIBUTES)); attrsXmlParser.preload(); - progress.worked(1); progress.subTask("Manifest definitions"); AttrsXmlParser attrsManifestXmlParser = new AttrsXmlParser( mAndroidTarget.getPath(IAndroidTarget.MANIFEST_ATTRIBUTES), attrsXmlParser); attrsManifestXmlParser.preload(); - progress.worked(1); Collection<ViewClassInfo> mainList = new ArrayList<ViewClassInfo>(); Collection<ViewClassInfo> groupList = new ArrayList<ViewClassInfo>(); @@ -172,7 +171,7 @@ public final class AndroidTargetParser { // collect the layout/widgets classes progress.subTask("Widgets and layouts"); collectLayoutClasses(classLoader, attrsXmlParser, mainList, groupList, - progress.newChild(1)); + progress.newChild(40)); if (progress.isCanceled()) { return Status.CANCEL_STATUS; @@ -186,7 +185,7 @@ public final class AndroidTargetParser { mainList.clear(); groupList.clear(); collectPreferenceClasses(classLoader, attrsXmlParser, mainList, groupList, - progress.newChild(1)); + progress.newChild(5)); if (progress.isCanceled()) { return Status.CANCEL_STATUS; @@ -203,11 +202,6 @@ public final class AndroidTargetParser { attrsManifestXmlParser); Map<String, Map<String, Integer>> enumValueMap = attrsXmlParser.getEnumFlagValues(); - Map<String, DeclareStyleableInfo> xmlGadgetMap = null; - if (mAndroidTarget.getApiVersionNumber() >= 3) { - xmlGadgetMap = collectGadgetDefinitions(attrsXmlParser); - } - if (progress.isCanceled()) { return Status.CANCEL_STATUS; } @@ -216,7 +210,7 @@ public final class AndroidTargetParser { // the PlatformData object. AndroidManifestDescriptors manifestDescriptors = new AndroidManifestDescriptors(); manifestDescriptors.updateDescriptors(manifestMap); - progress.worked(1); + progress.worked(10); if (progress.isCanceled()) { return Status.CANCEL_STATUS; @@ -224,7 +218,7 @@ public final class AndroidTargetParser { LayoutDescriptors layoutDescriptors = new LayoutDescriptors(); layoutDescriptors.updateDescriptors(layoutViewsInfo, layoutGroupsInfo); - progress.worked(1); + progress.worked(10); if (progress.isCanceled()) { return Status.CANCEL_STATUS; @@ -232,28 +226,25 @@ public final class AndroidTargetParser { MenuDescriptors menuDescriptors = new MenuDescriptors(); menuDescriptors.updateDescriptors(xmlMenuMap); - progress.worked(1); + progress.worked(10); if (progress.isCanceled()) { return Status.CANCEL_STATUS; } XmlDescriptors xmlDescriptors = new XmlDescriptors(); - xmlDescriptors.updateDescriptors( - xmlSearchableMap, - xmlGadgetMap, - preferencesInfo, + xmlDescriptors.updateDescriptors(xmlSearchableMap, preferencesInfo, preferenceGroupsInfo); - progress.worked(1); + progress.worked(10); // load the framework resources. ProjectResources resources = ResourceManager.getInstance().loadFrameworkResources( mAndroidTarget); - progress.worked(1); + progress.worked(10); // now load the layout lib bridge LayoutBridge layoutBridge = loadLayoutBridge(); - progress.worked(1); + progress.worked(10); // and finally create the PlatformData with all that we loaded. targetData.setExtraData(frameworkRepository, @@ -267,7 +258,6 @@ public final class AndroidTargetParser { broadcast_actions.toArray(new String[broadcast_actions.size()]), service_actions.toArray(new String[service_actions.size()]), categories.toArray(new String[categories.size()]), - mAndroidTarget.getOptionalLibraries(), resources, layoutBridge); @@ -278,6 +268,10 @@ public final class AndroidTargetParser { AdtPlugin.logAndPrintError(e, TAG, "SDK parser failed"); //$NON-NLS-1$ AdtPlugin.printToConsole("SDK parser failed", e.getMessage()); return new Status(IStatus.ERROR, AdtPlugin.PLUGIN_ID, "SDK parser failed", e); + } finally { + if (monitor != null) { + monitor.done(); + } } } @@ -611,31 +605,6 @@ public final class AndroidTargetParser { } /** - * Collects all gadgetProviderInfo definition information from the attrs.xml and returns it. - * - * @param attrsXmlParser The parser of the attrs.xml file - */ - private Map<String, DeclareStyleableInfo> collectGadgetDefinitions( - AttrsXmlParser attrsXmlParser) { - Map<String, DeclareStyleableInfo> map = attrsXmlParser.getDeclareStyleableList(); - Map<String, DeclareStyleableInfo> map2 = new HashMap<String, DeclareStyleableInfo>(); - for (String key : new String[] { "GadgetProviderInfo" }) { //$NON-NLS-1$ - if (map.containsKey(key)) { - map2.put(key, map.get(key)); - } else { - AdtPlugin.log(IStatus.WARNING, - "Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$ - key, attrsXmlParser.getOsAttrsXmlPath()); - AdtPlugin.printErrorToConsole("Android Framework Parser", - String.format("Gadget declare-styleable %1$s not found in file %2$s", //$NON-NLS-1$ - key, attrsXmlParser.getOsAttrsXmlPath())); - } - } - - return Collections.unmodifiableMap(map2); - } - - /** * Collects all manifest definition information from the attrs_manifest.xml and returns it. */ private Map<String, DeclareStyleableInfo> collectManifestDefinitions( @@ -681,15 +650,6 @@ public final class AndroidTargetParser { layoutBridge.status = LoadStatus.FAILED; AdtPlugin.log(IStatus.ERROR, "Failed to load " + AndroidConstants.CLASS_BRIDGE); //$NON-NLS-1$ } else { - // get the api level - try { - layoutBridge.apiLevel = layoutBridge.bridge.getApiLevel(); - } catch (AbstractMethodError e) { - // the first version of the api did not have this method - layoutBridge.apiLevel = 1; - } - - // and mark the lib as loaded. layoutBridge.status = LoadStatus.LOADED; } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java index ba0b568..c7773cc 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java @@ -18,7 +18,6 @@ package com.android.ide.eclipse.adt.sdk; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer; -import com.android.ide.eclipse.adt.sdk.AndroidTargetData.LayoutBridge; import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor; import com.android.ide.eclipse.editors.resources.manager.ResourceMonitor.IProjectListener; import com.android.prefs.AndroidLocation.AndroidLocationException; @@ -34,7 +33,6 @@ import com.android.sdklib.project.ProjectProperties.PropertyType; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; @@ -71,22 +69,6 @@ public class Sdk implements IProjectListener { private final String mDocBaseUrl; /** - * Classes implementing this interface will receive notification when targets are changed. - */ - public interface ITargetChangeListener { - /** - * Sent when project has its target changed. - */ - void onProjectTargetChange(IProject changedProject); - - /** - * Called when the targets are loaded (either the SDK finished loading when Eclipse starts, - * or the SDK is changed). - */ - void onTargetsLoaded(); - } - - /** * Loads an SDK and returns an {@link Sdk} object if success. * @param sdkLocation the OS path to the SDK. */ @@ -181,87 +163,24 @@ public class Sdk implements IProjectListener { } /** - * Sets a new target and a new list of Apk configuration for a given project. - * - * @param project the project to receive the new apk configurations - * @param target The new target to set, or <code>null</code> to not change the current target. - * @param apkConfigMap a map of apk configurations. The map contains (name, filter) where name - * is the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of - * resource configuration to include in the apk (see aapt -c). Can be <code>null</code> if the - * apk configurations should not be updated. + * Associates an {@link IProject} and an {@link IAndroidTarget}. */ - public void setProject(IProject project, IAndroidTarget target, - Map<String, String> apkConfigMap) { + public void setProject(IProject project, IAndroidTarget target) { synchronized (mProjectTargetMap) { - boolean resolveProject = false; - boolean compileProject = false; - boolean cleanProject = false; - - ProjectProperties properties = ProjectProperties.load( - project.getLocation().toOSString(), PropertyType.DEFAULT); - if (properties == null) { - // doesn't exist yet? we create it. - properties = ProjectProperties.create(project.getLocation().toOSString(), - PropertyType.DEFAULT); - } - - if (target != null) { - // look for the current target of the project - IAndroidTarget previousTarget = mProjectTargetMap.get(project); - - if (target != previousTarget) { - // save the target hash string in the project persistent property - properties.setAndroidTarget(target); - - // put it in a local map for easy access. - mProjectTargetMap.put(project, target); - - resolveProject = true; - } - } + // look for the current target of the project + IAndroidTarget previousTarget = mProjectTargetMap.get(project); - if (apkConfigMap != null) { - // save the apk configs in the project persistent property - cleanProject = ApkConfigurationHelper.setConfigs(properties, apkConfigMap); - - // put it in a local map for easy access. - mProjectApkConfigMap.put(project, apkConfigMap); + if (target != previousTarget) { + // save the target hash string in the project persistent property + setProjectTargetHashString(project, target.hashString()); - compileProject = true; - } + // put it in a local map for easy access. + mProjectTargetMap.put(project, target); - // we are done with the modification. Save the property file. - try { - properties.save(); - } catch (IOException e) { - AdtPlugin.log(e, "Failed to save default.properties for project '%s'", - project.getName()); - } - - if (resolveProject) { - // force a resolve of the project by updating the classpath container. + // recompile the project if needed. IJavaProject javaProject = JavaCore.create(project); AndroidClasspathContainerInitializer.updateProjects( new IJavaProject[] { javaProject }); - } else if (compileProject) { - // If there was removed configs, we clean instead of build - // (to remove the obsolete ap_ and apk file from removed configs). - try { - project.build(cleanProject ? - IncrementalProjectBuilder.CLEAN_BUILD : - IncrementalProjectBuilder.FULL_BUILD, - null); - } catch (CoreException e) { - // failed to build? force resolve instead. - IJavaProject javaProject = JavaCore.create(project); - AndroidClasspathContainerInitializer.updateProjects( - new IJavaProject[] { javaProject }); - } - } - - // finally, update the opened editors. - if (resolveProject) { - AdtPlugin.getDefault().updateTargetListener(project); } } } @@ -299,12 +218,7 @@ public class Sdk implements IProjectListener { */ private static String loadProjectProperties(IProject project, Sdk sdkStorage) { // load the default.properties from the project folder. - IPath location = project.getLocation(); - if (location == null) { // can return null when the project is being deleted. - // do nothing and return null; - return null; - } - ProjectProperties properties = ProjectProperties.load(location.toOSString(), + ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(), PropertyType.DEFAULT); if (properties == null) { AdtPlugin.log(IStatus.ERROR, "Failed to load properties file for project '%s'", @@ -315,7 +229,7 @@ public class Sdk implements IProjectListener { if (sdkStorage != null) { Map<String, String> configMap = ApkConfigurationHelper.getConfigs(properties); - if (configMap != null) { + if (configMap.size() > 0) { sdkStorage.mProjectApkConfigMap.put(project, configMap); } } @@ -382,6 +296,40 @@ public class Sdk implements IProjectListener { return mProjectApkConfigMap.get(project); } + public void setProjectApkConfigs(IProject project, Map<String, String> configMap) + throws CoreException { + // first set the new map + mProjectApkConfigMap.put(project, configMap); + + // Now we write this in default.properties. + // Because we don't want to erase other properties from default.properties, we first load + // them + ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(), + PropertyType.DEFAULT); + if (properties == null) { + // doesn't exist yet? we create it. + properties = ProjectProperties.create(project.getLocation().toOSString(), + PropertyType.DEFAULT); + } + + // sets the configs in the property file. + boolean hasRemovedConfig = ApkConfigurationHelper.setConfigs(properties, configMap); + + // and rewrite the file. + try { + properties.save(); + } catch (IOException e) { + AdtPlugin.log(e, "Failed to save default.properties for project '%s'", + project.getName()); + } + + // we're done, force a rebuild. If there was removed config, we clean instead of build + // (to remove the obsolete ap_ and apk file from removed configs). + project.build(hasRemovedConfig ? + IncrementalProjectBuilder.CLEAN_BUILD : IncrementalProjectBuilder.FULL_BUILD, + null); + } + /** * Returns the {@link AvdManager}. If the AvdManager failed to parse the AVD folder, this could * be <code>null</code>. @@ -454,24 +402,8 @@ public class Sdk implements IProjectListener { } public void projectClosed(IProject project) { - // get the target project - synchronized (mProjectTargetMap) { - IAndroidTarget target = mProjectTargetMap.get(project); - if (target != null) { - // get the bridge for the target, and clear the cache for this project. - AndroidTargetData data = mTargetDataMap.get(target); - if (data != null) { - LayoutBridge bridge = data.getLayoutBridge(); - if (bridge != null && bridge.status == LoadStatus.LOADED) { - bridge.bridge.clearCaches(project); - } - } - } - - // now remove the project for the maps. - mProjectTargetMap.remove(project); - mProjectApkConfigMap.remove(project); - } + mProjectTargetMap.remove(project); + mProjectApkConfigMap.remove(project); } public void projectDeleted(IProject project) { diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewProjectAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewProjectAction.java deleted file mode 100644 index e0d0d5e..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewProjectAction.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * - * 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.ide.eclipse.adt.wizards.actions; - -import com.android.ide.eclipse.adt.wizards.newproject.NewProjectWizard; - -import org.eclipse.jface.action.IAction; -import org.eclipse.ui.IWorkbenchWizard; - -/** - * Delegate for the toolbar action "Android Project". - * It displays the Android New Project wizard. - */ -public class NewProjectAction extends OpenWizardAction { - - @Override - protected IWorkbenchWizard instanciateWizard(IAction action) { - return new NewProjectWizard(); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewXmlFileAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewXmlFileAction.java deleted file mode 100644 index 8c4a115..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/NewXmlFileAction.java +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * - * 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.ide.eclipse.adt.wizards.actions; - -import com.android.ide.eclipse.editors.wizards.NewXmlFileWizard; - -import org.eclipse.jface.action.IAction; -import org.eclipse.ui.IWorkbenchWizard; - -/** - * Delegate for the toolbar action "Android Project". - * It displays the Android New XML file wizard. - */ -public class NewXmlFileAction extends OpenWizardAction { - - @Override - protected IWorkbenchWizard instanciateWizard(IAction action) { - return new NewXmlFileWizard(); - } -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/OpenWizardAction.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/OpenWizardAction.java deleted file mode 100644 index 4fc9dee..0000000 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/actions/OpenWizardAction.java +++ /dev/null @@ -1,139 +0,0 @@ -/* - * Copyright (C) 2009 The Android Open Source Project - * - * Licensed under the Eclipse Public License, Version 1.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.eclipse.org/org/documents/epl-v10.php - * - * 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.ide.eclipse.adt.wizards.actions; - -import org.eclipse.jface.action.IAction; -import org.eclipse.jface.viewers.ISelection; -import org.eclipse.jface.viewers.IStructuredSelection; -import org.eclipse.jface.viewers.StructuredSelection; -import org.eclipse.jface.wizard.WizardDialog; -import org.eclipse.swt.graphics.Point; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.ui.IEditorInput; -import org.eclipse.ui.IEditorPart; -import org.eclipse.ui.IWorkbench; -import org.eclipse.ui.IWorkbenchPart; -import org.eclipse.ui.IWorkbenchWindow; -import org.eclipse.ui.IWorkbenchWindowActionDelegate; -import org.eclipse.ui.IWorkbenchWizard; -import org.eclipse.ui.PlatformUI; -import org.eclipse.ui.internal.IWorkbenchHelpContextIds; -import org.eclipse.ui.internal.LegacyResourceSupport; -import org.eclipse.ui.internal.actions.NewWizardShortcutAction; -import org.eclipse.ui.internal.util.Util; - -/** - * An abstract action that displays one of our wizards. - * Derived classes must provide the actual wizard to display. - */ -/*package*/ abstract class OpenWizardAction implements IWorkbenchWindowActionDelegate { - - /** - * The wizard dialog width, extracted from {@link NewWizardShortcutAction} - */ - private static final int SIZING_WIZARD_WIDTH = 500; - - /** - * The wizard dialog height, extracted from {@link NewWizardShortcutAction} - */ - private static final int SIZING_WIZARD_HEIGHT = 500; - - - /* (non-Javadoc) - * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#dispose() - */ - public void dispose() { - // pass - } - - /* (non-Javadoc) - * @see org.eclipse.ui.IWorkbenchWindowActionDelegate#init(org.eclipse.ui.IWorkbenchWindow) - */ - public void init(IWorkbenchWindow window) { - // pass - } - - /** - * Opens and display the Android New Project Wizard. - * <p/> - * Most of this implementation is extracted from {@link NewWizardShortcutAction#run()}. - * - * @see org.eclipse.ui.IActionDelegate#run(org.eclipse.jface.action.IAction) - */ - public void run(IAction action) { - - // get the workbench and the current window - IWorkbench workbench = PlatformUI.getWorkbench(); - IWorkbenchWindow window = workbench.getActiveWorkbenchWindow(); - - // This code from NewWizardShortcutAction#run() gets the current window selection - // and converts it to a workbench structured selection for the wizard, if possible. - ISelection selection = window.getSelectionService().getSelection(); - IStructuredSelection selectionToPass = StructuredSelection.EMPTY; - if (selection instanceof IStructuredSelection) { - selectionToPass = (IStructuredSelection) selection; - } else { - // Build the selection from the IFile of the editor - IWorkbenchPart part = window.getPartService().getActivePart(); - if (part instanceof IEditorPart) { - IEditorInput input = ((IEditorPart) part).getEditorInput(); - Class<?> fileClass = LegacyResourceSupport.getFileClass(); - if (input != null && fileClass != null) { - Object file = Util.getAdapter(input, fileClass); - if (file != null) { - selectionToPass = new StructuredSelection(file); - } - } - } - } - - // Create the wizard and initialize it with the selection - IWorkbenchWizard wizard = instanciateWizard(action); - wizard.init(workbench, selectionToPass); - - // It's not visible yet until a dialog is created and opened - Shell parent = window.getShell(); - WizardDialog dialog = new WizardDialog(parent, wizard); - dialog.create(); - - // This code comes straight from NewWizardShortcutAction#run() - Point defaultSize = dialog.getShell().getSize(); - dialog.getShell().setSize( - Math.max(SIZING_WIZARD_WIDTH, defaultSize.x), - Math.max(SIZING_WIZARD_HEIGHT, defaultSize.y)); - window.getWorkbench().getHelpSystem().setHelp(dialog.getShell(), - IWorkbenchHelpContextIds.NEW_WIZARD_SHORTCUT); - - dialog.open(); - } - - /** - * Called by {@link #run(IAction)} to instantiate the actual wizard. - * - * @param action The action parameter from {@link #run(IAction)}. - * @return A new wizard instance. Must not be null. - */ - protected abstract IWorkbenchWizard instanciateWizard(IAction action); - - /* (non-Javadoc) - * @see org.eclipse.ui.IActionDelegate#selectionChanged(org.eclipse.jface.action.IAction, org.eclipse.jface.viewers.ISelection) - */ - public void selectionChanged(IAction action, ISelection selection) { - // pass - } - -} diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java index cb79796..607159a 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java @@ -105,8 +105,6 @@ public class NewProjectWizard extends Wizard implements INewWizard { SdkConstants.FD_LAYOUT + AndroidConstants.WS_SEP; private static final String VALUES_DIRECTORY = SdkConstants.FD_VALUES + AndroidConstants.WS_SEP; - private static final String GEN_SRC_DIRECTORY = - SdkConstants.FD_GEN_SOURCES + AndroidConstants.WS_SEP; private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$ private static final String TEMPLATE_MANIFEST = TEMPLATES_DIRECTORY @@ -116,7 +114,7 @@ public class NewProjectWizard extends Wizard implements INewWizard { private static final String TEMPLATE_USES_SDK = TEMPLATES_DIRECTORY + "uses-sdk.template"; //$NON-NLS-1$ private static final String TEMPLATE_INTENT_LAUNCHER = TEMPLATES_DIRECTORY - + "launcher_intent_filter.template"; //$NON-NLS-1$ + + "launcher_intent_filter.template"; //$NON-NLS-1$ private static final String TEMPLATE_STRINGS = TEMPLATES_DIRECTORY + "strings.template"; //$NON-NLS-1$ @@ -343,20 +341,15 @@ public class NewProjectWizard extends Wizard implements INewWizard { // Create folders in the project if they don't already exist addDefaultDirectories(project, AndroidConstants.WS_ROOT, DEFAULT_DIRECTORIES, monitor); - String[] sourceFolders = new String[] { - (String) parameters.get(PARAM_SRC_FOLDER), - GEN_SRC_DIRECTORY - }; - addDefaultDirectories(project, AndroidConstants.WS_ROOT, sourceFolders, monitor); + String[] sourceFolder = new String[] { (String) parameters.get(PARAM_SRC_FOLDER) }; + addDefaultDirectories(project, AndroidConstants.WS_ROOT, sourceFolder, monitor); // Create the resource folders in the project if they don't already exist. addDefaultDirectories(project, RES_DIRECTORY, RES_DIRECTORIES, monitor); // Setup class path IJavaProject javaProject = JavaCore.create(project); - for (String sourceFolder : sourceFolders) { - setupSourceFolder(javaProject, sourceFolder, monitor); - } + setupSourceFolder(javaProject, sourceFolder[0], monitor); if (((Boolean) parameters.get(PARAM_IS_NEW_PROJECT)).booleanValue()) { // Create files in the project if they don't already exist @@ -366,7 +359,7 @@ public class NewProjectWizard extends Wizard implements INewWizard { addIcon(project, monitor); // Create the default package components - addSampleCode(project, sourceFolders[0], parameters, stringDictionary, monitor); + addSampleCode(project, sourceFolder[0], parameters, stringDictionary, monitor); // add the string definition file if needed if (stringDictionary.size() > 0) { @@ -378,8 +371,7 @@ public class NewProjectWizard extends Wizard implements INewWizard { monitor); } - Sdk.getCurrent().setProject(project, (IAndroidTarget) parameters.get(PARAM_SDK_TARGET), - null /* apkConfigMap*/); + Sdk.getCurrent().setProject(project, (IAndroidTarget) parameters.get(PARAM_SDK_TARGET)); // Fix the project to make sure all properties are as expected. // Necessary for existing projects and good for new ones to. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java index e201132..b1c57a6 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java @@ -148,11 +148,8 @@ public class AndroidConstants { /** The old common plug-in ID. Please do not use for new features. */ public static final String COMMON_PLUGIN_ID = "com.android.ide.eclipse.common"; //$NON-NLS-1$ - /** aapt marker error when running the compile command */ - public final static String MARKER_AAPT_COMPILE = COMMON_PLUGIN_ID + ".aaptProblem"; //$NON-NLS-1$ - - /** aapt marker error when running the package command */ - public final static String MARKER_AAPT_PACKAGE = COMMON_PLUGIN_ID + ".aapt2Problem"; //$NON-NLS-1$ + /** aapt marker error. */ + public final static String MARKER_AAPT = COMMON_PLUGIN_ID + ".aaptProblem"; //$NON-NLS-1$ /** XML marker error. */ public final static String MARKER_XML = COMMON_PLUGIN_ID + ".xmlProblem"; //$NON-NLS-1$ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java index c7541e9..dca7db0 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java @@ -19,7 +19,6 @@ package com.android.ide.eclipse.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.sdklib.IAndroidTarget; @@ -98,9 +97,8 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang private StructuredTextEditor mTextEditor; /** Listener for the XML model from the StructuredEditor */ private XmlModelStateListener mXmlModelStateListener; - /** Listener to update the root node if the target of the file is changed because of a - * SDK location change or a project target change */ - private ITargetChangeListener mTargetListener; + /** Listener to update the root node if the resource framework changes */ + private Runnable mResourceRefreshListener; /** * Creates a form editor. @@ -109,21 +107,15 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang super(); ResourcesPlugin.getWorkspace().addResourceChangeListener(this); - mTargetListener = new ITargetChangeListener() { - public void onProjectTargetChange(IProject changedProject) { - if (changedProject == getProject()) { - onTargetsLoaded(); - } - } - - public void onTargetsLoaded() { + mResourceRefreshListener = new Runnable() { + public void run() { commitPages(false /* onSave */); - + // recreate the ui root node always initUiRootNode(true /*force*/); } }; - AdtPlugin.getDefault().addTargetListener(mTargetListener); + AdtPlugin.getDefault().addResourceChangedListener(mResourceRefreshListener); } // ---- Abstract Methods ---- @@ -348,9 +340,9 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang } ResourcesPlugin.getWorkspace().removeResourceChangeListener(this); - if (mTargetListener != null) { - AdtPlugin.getDefault().removeTargetListener(mTargetListener); - mTargetListener = null; + if (mResourceRefreshListener != null) { + AdtPlugin.getDefault().removeResourceChangedListener(mResourceRefreshListener); + mResourceRefreshListener = null; } super.dispose(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java index f1d62a1..cc923bf 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java @@ -313,7 +313,7 @@ public final class DescriptorsUtils { * * @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. + * See {@link AndroidConstants#NS_RESOURCES} for a common value. * @param info The {@link AttributeInfo} to know whether it is included in the above list. * @return True if this {@link AttributeInfo} is already present in * the {@link AttributeDescriptor} list. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/GraphicalLayoutEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/GraphicalLayoutEditor.java index eb7dee6..ca7cac5 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/GraphicalLayoutEditor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/GraphicalLayoutEditor.java @@ -21,7 +21,6 @@ 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.common.resources.ResourceType; import com.android.ide.eclipse.editors.IconFactory; import com.android.ide.eclipse.editors.layout.LayoutEditor.UiEditorActions; @@ -199,21 +198,13 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette private ProjectCallback mProjectCallback; private ILayoutLog mLogger; - private boolean mNeedsXmlReload = false; private boolean mNeedsRecompute = false; private int mPlatformThemeCount = 0; private boolean mDisableUpdates = false; + private boolean mActive = false; - /** Listener to update the root node if the target of the file is changed because of a - * SDK location change or a project target change */ - private ITargetChangeListener mTargetListener = new ITargetChangeListener() { - public void onProjectTargetChange(IProject changedProject) { - if (changedProject == getLayoutEditor().getProject()) { - onTargetsLoaded(); - } - } - - public void onTargetsLoaded() { + private Runnable mFrameworkResourceChangeListener = new Runnable() { + public void run() { // because the SDK changed we must reset the configured framework resource. mConfiguredFrameworkRes = null; @@ -237,7 +228,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette private final Runnable mConditionalRecomputeRunnable = new Runnable() { public void run() { - if (mLayoutEditor.isGraphicalEditorActive()) { + if (mActive) { recomputeLayout(); } else { mNeedsRecompute = true; @@ -262,7 +253,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette mMatchImage = factory.getIcon("match"); //$NON-NLS-1$ mErrorImage = factory.getIcon("error"); //$NON-NLS-1$ - AdtPlugin.getDefault().addTargetListener(mTargetListener); + AdtPlugin.getDefault().addResourceChangedListener(mFrameworkResourceChangeListener); } // ------------------------------------ @@ -570,9 +561,10 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette @Override public void dispose() { - if (mTargetListener != null) { - AdtPlugin.getDefault().removeTargetListener(mTargetListener); - mTargetListener = null; + if (mFrameworkResourceChangeListener != null) { + AdtPlugin.getDefault().removeResourceChangedListener( + mFrameworkResourceChangeListener); + mFrameworkResourceChangeListener = null; } LayoutReloadMonitor.getMonitor().removeListener(mEditedFile.getProject(), this); @@ -1034,36 +1026,25 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette } /** - * Callback for XML model changed. Only update/recompute the layout if the editor is visible + * Update the layout editor when the Xml model is changed. */ void onXmlModelChanged() { + GraphicalViewer viewer = getGraphicalViewer(); + + // try to preserve the selection before changing the content + SelectionManager selMan = viewer.getSelectionManager(); + ISelection selection = selMan.getSelection(); + + try { + viewer.setContents(getModel()); + } finally { + selMan.setSelection(selection); + } + if (mLayoutEditor.isGraphicalEditorActive()) { - doXmlReload(true /* force */); recomputeLayout(); } else { - mNeedsXmlReload = true; - } - } - - /** - * Actually performs the XML reload - * @see #onXmlModelChanged() - */ - private void doXmlReload(boolean force) { - if (force || mNeedsXmlReload) { - GraphicalViewer viewer = getGraphicalViewer(); - - // try to preserve the selection before changing the content - SelectionManager selMan = viewer.getSelectionManager(); - ISelection selection = selMan.getSelection(); - - try { - viewer.setContents(getModel()); - } finally { - selMan.setSelection(selection); - } - - mNeedsXmlReload = false; + mNeedsRecompute = true; } } @@ -1667,9 +1648,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette /** * Recomputes the layout with the help of layoutlib. */ - @SuppressWarnings("deprecation") void recomputeLayout() { - doXmlReload(false /* force */); try { // check that the resource exists. If the file is opened but the project is closed // or deleted for some reason (changed from outside of eclipse), then this will @@ -1784,47 +1763,20 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette if (themeIndex != -1) { String theme = mThemeCombo.getItem(themeIndex); + // change the string if it's a custom theme to make sure we can + // differentiate them + if (themeIndex >= mPlatformThemeCount) { + theme = "*" + theme; //$NON-NLS-1$ + } + // Compute the layout UiElementPullParser parser = new UiElementPullParser(getModel()); Rectangle rect = getBounds(); - ILayoutResult result = null; - if (bridge.apiLevel >= 3) { - // call the new api with proper theme differentiator and - // density/dpi support. - boolean isProjectTheme = themeIndex >= mPlatformThemeCount; - - // FIXME pass the density/dpi from somewhere (resource config or skin). - result = bridge.bridge.computeLayout(parser, - iProject /* projectKey */, - rect.width, rect.height, 160, 160.f, 160.f, - theme, isProjectTheme, - mConfiguredProjectRes, frameworkResources, mProjectCallback, - mLogger); - } else if (bridge.apiLevel == 2) { - // api with boolean for separation of project/framework theme - boolean isProjectTheme = themeIndex >= mPlatformThemeCount; - - result = bridge.bridge.computeLayout(parser, - iProject /* projectKey */, - rect.width, rect.height, theme, isProjectTheme, - mConfiguredProjectRes, frameworkResources, mProjectCallback, - mLogger); - } else { - // oldest api with no density/dpi, and project theme boolean mixed - // into the theme name. - - // change the string if it's a custom theme to make sure we can - // differentiate them - if (themeIndex >= mPlatformThemeCount) { - theme = "*" + theme; //$NON-NLS-1$ - } - - result = bridge.bridge.computeLayout(parser, - iProject /* projectKey */, - rect.width, rect.height, theme, - mConfiguredProjectRes, frameworkResources, mProjectCallback, - mLogger); - } + ILayoutResult result = bridge.bridge.computeLayout(parser, + iProject /* projectKey */, + rect.width, rect.height, theme, + mConfiguredProjectRes, frameworkResources, mProjectCallback, + mLogger); // update the UiElementNode with the layout info. if (result.getSuccess() == ILayoutResult.SUCCESS) { @@ -1969,7 +1921,8 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette * Responds to a page change that made the Graphical editor page the activated page. */ void activated() { - if (mNeedsRecompute || mNeedsXmlReload) { + mActive = true; + if (mNeedsRecompute) { recomputeLayout(); } } @@ -1978,7 +1931,7 @@ public class GraphicalLayoutEditor extends GraphicalEditorWithPalette * Responds to a page change that made the Graphical editor page the deactivated page */ void deactivated() { - // nothing to be done here for now. + mActive = false; } /** diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutEditor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutEditor.java index dabe797..880ee2b 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutEditor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/LayoutEditor.java @@ -269,12 +269,8 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa protected void pageChange(int newPageIndex) { super.pageChange(newPageIndex); - if (mGraphicalEditor != null) { - if (newPageIndex == mGraphicalEditorIndex) { - mGraphicalEditor.activated(); - } else { - mGraphicalEditor.deactivated(); - } + if (mGraphicalEditor != null && newPageIndex == mGraphicalEditorIndex) { + mGraphicalEditor.activated(); } } @@ -282,12 +278,8 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa public void partActivated(IWorkbenchPart part) { if (part == this) { - if (mGraphicalEditor != null) { - if (getActivePage() == mGraphicalEditorIndex) { - mGraphicalEditor.activated(); - } else { - mGraphicalEditor.deactivated(); - } + if (mGraphicalEditor != null && getActivePage() == mGraphicalEditorIndex) { + mGraphicalEditor.activated(); } } } @@ -342,23 +334,23 @@ public class LayoutEditor extends AndroidEditor implements IShowEditorInput, IPa // ---- Local Methods ---- /** - * Returns true if the Graphics editor page is visible. This <b>must</b> be - * called from the UI thread. + * Returns true if the Graphics editor page is visible. + * This <b>must</b> be called from the UI thread. */ boolean isGraphicalEditorActive() { IWorkbenchPartSite workbenchSite = getSite(); IWorkbenchPage workbenchPage = workbenchSite.getPage(); - + // check if the editor is visible in the workbench page - if (workbenchPage.isPartVisible(this) && workbenchPage.getActiveEditor() == this) { + if (workbenchPage.isPartVisible(this)) { // and then if the page of the editor is visible (not to be confused with // the workbench page) return mGraphicalEditorIndex == getActivePage(); } - + return false; - } - + } + @Override protected void initUiRootNode(boolean force) { // The root UI node is always created, even if there's no corresponding XML node. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java index 77c08b5..61b73a2 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java @@ -195,8 +195,6 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { overrides.put("*/permission", ListAttributeDescriptor.class); //$NON-NLS-1$ overrides.put("*/targetPackage", PackageAttributeDescriptor.class); //$NON-NLS-1$ - overrides.put("uses-library/name", ListAttributeDescriptor.class); //$NON-NLS-1$ - overrides.put("action,category,uses-permission/" + ANDROID_NAME_ATTR, //$NON-NLS-1$ ListAttributeDescriptor.class); overrides.put("application/" + ANDROID_NAME_ATTR, ApplicationAttributeDescriptor.class); //$NON-NLS-1$ diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java index 629b37c..abaf438 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java @@ -16,12 +16,12 @@ package com.android.ide.eclipse.editors.manifest.descriptors; +import com.android.ide.eclipse.common.AndroidConstants; import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor; import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode; import com.android.ide.eclipse.editors.manifest.model.UiClassAttributeNode.IPostTypeCreationAction; import com.android.ide.eclipse.editors.uimodel.UiAttributeNode; import com.android.ide.eclipse.editors.uimodel.UiElementNode; -import com.android.sdklib.SdkConstants; /** * Describes an XML attribute representing a class name. diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiTreeBlock.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiTreeBlock.java index fc384e8..e3255d9 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiTreeBlock.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/UiTreeBlock.java @@ -17,7 +17,6 @@ package com.android.ide.eclipse.editors.ui.tree; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.adt.sdk.Sdk.ITargetChangeListener; import com.android.ide.eclipse.editors.AndroidEditor; import com.android.ide.eclipse.editors.IconFactory; import com.android.ide.eclipse.editors.descriptors.ElementDescriptor; @@ -27,7 +26,6 @@ import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener; import com.android.ide.eclipse.editors.uimodel.UiDocumentNode; import com.android.ide.eclipse.editors.uimodel.UiElementNode; -import org.eclipse.core.resources.IProject; import org.eclipse.jface.action.Action; import org.eclipse.jface.action.IMenuListener; import org.eclipse.jface.action.IMenuManager; @@ -287,21 +285,13 @@ public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml } }; - /** Listener to update the root node if the target of the file is changed because of a - * SDK location change or a project target change */ - final ITargetChangeListener targetListener = new ITargetChangeListener() { - public void onProjectTargetChange(IProject changedProject) { - if (changedProject == mEditor.getProject()) { - onTargetsLoaded(); - } - } - - public void onTargetsLoaded() { + final Runnable resourceRefreshListener = new Runnable() { + public void run() { // If a details part has been created, we need to "refresh" it too. if (mDetailsPart != null) { // The details part does not directly expose access to its internal // page book. Instead it is possible to resize the page book to 0 and then - // back to its original value, which has the side effect of removing all + // back to its original value, which as the side effect of removing all // existing cached pages. int limit = mDetailsPart.getPageLimit(); mDetailsPart.setPageLimit(0); @@ -316,7 +306,7 @@ public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml changeRootAndDescriptors(mUiRootNode, mDescriptorFilters, false /* refresh */); // Listen on resource framework changes to refresh the tree - AdtPlugin.getDefault().addTargetListener(targetListener); + AdtPlugin.getDefault().addResourceChangedListener(resourceRefreshListener); // Remove listeners when the tree widget gets disposed. tree.addDisposeListener(new DisposeListener() { @@ -328,7 +318,7 @@ public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml node.removeUpdateListener(mUiRefreshListener); mUiRootNode.removeUpdateListener(mUiEnableListener); - AdtPlugin.getDefault().removeTargetListener(targetListener); + AdtPlugin.getDefault().removeResourceChangedListener(resourceRefreshListener); if (mClipboard != null) { mClipboard.dispose(); mClipboard = null; @@ -590,11 +580,7 @@ public final class UiTreeBlock extends MasterDetailsBlock implements ICommitXml ui_node = ui_node.getUiParent()) { segments.add(0, ui_node); } - if (segments.size() > 0) { - mTreeViewer.setSelection(new TreeSelection(new TreePath(segments.toArray()))); - } else { - mTreeViewer.setSelection(null); - } + mTreeViewer.setSelection(new TreeSelection(new TreePath(segments.toArray()))); } } diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java index 5781938..4d17176 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java @@ -23,7 +23,6 @@ import com.android.ide.eclipse.common.AndroidConstants; import com.android.ide.eclipse.common.project.ProjectChooserHelper; import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor; import com.android.ide.eclipse.editors.descriptors.ElementDescriptor; -import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider; import com.android.ide.eclipse.editors.menu.descriptors.MenuDescriptors; import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration; import com.android.ide.eclipse.editors.resources.configurations.ResourceQualifier; @@ -82,7 +81,6 @@ class NewXmlFileCreationPage extends WizardPage { private final String mXmlns; private final String mDefaultAttrs; private final String mDefaultRoot; - private final int mTargetApiLevel; public TypeInfo(String uiName, String tooltip, @@ -90,8 +88,7 @@ class NewXmlFileCreationPage extends WizardPage { Object rootSeed, String defaultRoot, String xmlns, - String defaultAttrs, - int targetApiLevel) { + String defaultAttrs) { mUiName = uiName; mResFolderType = resFolderType; mTooltip = tooltip; @@ -99,7 +96,6 @@ class NewXmlFileCreationPage extends WizardPage { mDefaultRoot = defaultRoot; mXmlns = xmlns; mDefaultAttrs = defaultAttrs; - mTargetApiLevel = targetApiLevel; } /** Returns the UI name for the resource type. Unique. Never null. */ @@ -180,13 +176,6 @@ class NewXmlFileCreationPage extends WizardPage { String getDefaultAttrs() { return mDefaultAttrs; } - - /** - * The minimum API level required by the current SDK target to support this feature. - */ - public int getTargetApiLevel() { - return mTargetApiLevel; - } } /** @@ -201,8 +190,7 @@ class NewXmlFileCreationPage extends WizardPage { "LinearLayout", // default root SdkConstants.NS_RESOURCES, // xmlns "android:layout_width=\"wrap_content\"\n" + // default attributes - "android:layout_height=\"wrap_content\"", - 1 // target API level + "android:layout_height=\"wrap_content\"" ), new TypeInfo("Values", // UI name "An XML file with simple values: colors, strings, dimensions, etc.", // tooltip @@ -210,8 +198,7 @@ class NewXmlFileCreationPage extends WizardPage { ResourcesDescriptors.ROOT_ELEMENT, // root seed null, // default root null, // xmlns - null, // default attributes - 1 // target API level + null // default attributes ), new TypeInfo("Menu", // UI name "An XML file that describes an menu.", // tooltip @@ -219,17 +206,7 @@ class NewXmlFileCreationPage extends WizardPage { MenuDescriptors.MENU_ROOT_ELEMENT, // root seed null, // default root SdkConstants.NS_RESOURCES, // xmlns - null, // default attributes - 1 // target API level - ), - new TypeInfo("Gadget Provider", // UI name - "An XML file that describes a gadget provider.", // tooltip - ResourceFolderType.XML, // folder type - AndroidTargetData.DESCRIPTOR_GADGET_PROVIDER, // root seed - null, // default root - SdkConstants.NS_RESOURCES, // xmlns - null, // default attributes - 3 // target API level + null // default attributes ), new TypeInfo("Preference", // UI name "An XML file that describes preferences.", // tooltip @@ -237,17 +214,15 @@ class NewXmlFileCreationPage extends WizardPage { AndroidTargetData.DESCRIPTOR_PREFERENCES, // root seed AndroidConstants.CLASS_PREFERENCE_SCREEN, // default root SdkConstants.NS_RESOURCES, // xmlns - null, // default attributes - 1 // target API level + null // default attributes ), new TypeInfo("Searchable", // UI name - "An XML file that describes a searchable.", // tooltip + "An XML file that describes a searchable [TODO].", // tooltip ResourceFolderType.XML, // folder type AndroidTargetData.DESCRIPTOR_SEARCHABLE, // root seed null, // default root SdkConstants.NS_RESOURCES, // xmlns - null, // default attributes - 1 // target API level + null // default attributes ), new TypeInfo("Animation", // UI name "An XML file that describes an animation.", // tooltip @@ -262,14 +237,10 @@ class NewXmlFileCreationPage extends WizardPage { }, "set", //$NON-NLS-1$ // default root null, // xmlns - null, // default attributes - 1 // target API level + null // default attributes ), }; - /** Number of columns in the grid layout */ - final static int NUM_COL = 4; - /** Absolute destination folder root, e.g. "/res/" */ private static String sResFolderAbs = AndroidConstants.WS_RESOURCES + AndroidConstants.WS_SEP; /** Relative destination folder root, e.g. "res/" */ @@ -319,7 +290,7 @@ class NewXmlFileCreationPage extends WizardPage { initializeDialogUnits(parent); - composite.setLayout(new GridLayout(NUM_COL, false /*makeColumnsEqualWidth*/)); + composite.setLayout(new GridLayout(3, false /*makeColumnsEqualWidth*/)); composite.setLayoutData(new GridData(GridData.FILL_BOTH)); createProjectGroup(composite); @@ -332,9 +303,8 @@ class NewXmlFileCreationPage extends WizardPage { setControl(composite); // Update state the first time - initializeFromSelection(mInitialSelection); initializeRootValues(); - enableTypesBasedOnApi(); + initializeFromSelection(mInitialSelection); validatePage(); } @@ -449,34 +419,16 @@ class NewXmlFileCreationPage extends WizardPage { } /** - * Pads the parent with empty cells to match the number of columns of the parent grid. - * - * @param parent A grid layout with NUM_COL columns - * @param col The current number of columns used. - * @return 0, the new number of columns used, for convenience. - */ - private int padWithEmptyCells(Composite parent, int col) { - for (; col < NUM_COL; ++col) { - emptyCell(parent); - } - col = 0; - return col; - } - - /** * Creates the project & filename fields. * <p/> - * The parent must be a GridLayout with NUM_COL colums. + * The parent must be a GridLayout with 3 colums. */ private void createProjectGroup(Composite parent) { - int col = 0; - // project name String tooltip = "The Android Project where the new resource file will be created."; Label label = new Label(parent, SWT.NONE); label.setText("Project"); label.setToolTipText(tooltip); - ++col; mProjectTextField = new Text(parent, SWT.BORDER); mProjectTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); @@ -486,7 +438,6 @@ class NewXmlFileCreationPage extends WizardPage { onProjectFieldUpdated(); } }); - ++col; mProjectBrowseButton = new Button(parent, SWT.NONE); mProjectBrowseButton.setText("Browse..."); @@ -498,16 +449,12 @@ class NewXmlFileCreationPage extends WizardPage { } }); mProjectChooserHelper = new ProjectChooserHelper(parent.getShell()); - ++col; - col = padWithEmptyCells(parent, col); - // file name tooltip = "The name of the resource file to create."; label = new Label(parent, SWT.NONE); label.setText("File"); label.setToolTipText(tooltip); - ++col; mFileNameTextField = new Text(parent, SWT.BORDER); mFileNameTextField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); @@ -517,32 +464,31 @@ class NewXmlFileCreationPage extends WizardPage { validatePage(); } }); - ++col; - padWithEmptyCells(parent, col); + emptyCell(parent); } /** * Creates the type field, {@link ConfigurationSelector} and the folder field. * <p/> - * The parent must be a GridLayout with NUM_COL colums. + * The parent must be a GridLayout with 3 colums. */ private void createTypeGroup(Composite parent) { // separator Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - label.setLayoutData(newGridData(NUM_COL, GridData.GRAB_HORIZONTAL)); + label.setLayoutData(newGridData(3, GridData.GRAB_HORIZONTAL)); // label before type radios label = new Label(parent, SWT.NONE); label.setText("What type of resource would you like to create?"); - label.setLayoutData(newGridData(NUM_COL)); + label.setLayoutData(newGridData(3)); // display the types on three columns of radio buttons. emptyCell(parent); Composite grid = new Composite(parent, SWT.NONE); - padWithEmptyCells(parent, 2); + emptyCell(parent); - grid.setLayout(new GridLayout(NUM_COL, true /*makeColumnsEqualWidth*/)); + grid.setLayout(new GridLayout(3, true /*makeColumnsEqualWidth*/)); SelectionListener radioListener = new SelectionAdapter() { @Override @@ -555,27 +501,23 @@ class NewXmlFileCreationPage extends WizardPage { }; int n = sTypes.length; - int num_lines = (n + NUM_COL/2) / NUM_COL; - for (int line = 0, k = 0; line < num_lines; line++) { - for (int i = 0; i < NUM_COL; i++, k++) { - if (k < n) { - TypeInfo type = sTypes[k]; - Button radio = new Button(grid, SWT.RADIO); - type.setWidget(radio); - radio.setSelection(false); - radio.setText(type.getUiName()); - radio.setToolTipText(type.getTooltip()); - radio.addSelectionListener(radioListener); - } else { - emptyCell(grid); - } + int num_lines = n/3; + for (int line = 0; line < num_lines; line++) { + for (int i = 0; i < 3; i++) { + TypeInfo type = sTypes[line * 3 + i]; + Button radio = new Button(grid, SWT.RADIO); + type.setWidget(radio); + radio.setSelection(false); + radio.setText(type.getUiName()); + radio.setToolTipText(type.getTooltip()); + radio.addSelectionListener(radioListener); } } // label before configuration selector label = new Label(parent, SWT.NONE); label.setText("What type of resource configuration would you like?"); - label.setLayoutData(newGridData(NUM_COL)); + label.setLayoutData(newGridData(3)); // configuration selector emptyCell(parent); @@ -585,7 +527,6 @@ class NewXmlFileCreationPage extends WizardPage { gd.heightHint = ConfigurationSelector.HEIGHT_HINT; mConfigSelector.setLayoutData(gd); mConfigSelector.setOnChangeListener(new onConfigSelectorUpdated()); - emptyCell(parent); // folder name String tooltip = "The folder where the file will be generated, relative to the project."; @@ -601,23 +542,25 @@ class NewXmlFileCreationPage extends WizardPage { onWsFolderPathUpdated(); } }); + + emptyCell(parent); } /** * Creates the root element combo. * <p/> - * The parent must be a GridLayout with NUM_COL colums. + * The parent must be a GridLayout with 3 colums. */ private void createRootGroup(Composite parent) { // separator Label label = new Label(parent, SWT.SEPARATOR | SWT.HORIZONTAL); - label.setLayoutData(newGridData(NUM_COL, GridData.GRAB_HORIZONTAL)); + label.setLayoutData(newGridData(3, GridData.GRAB_HORIZONTAL)); // label before the root combo String tooltip = "The root element to create in the XML file."; label = new Label(parent, SWT.NONE); label.setText("Select the root element for the XML file:"); - label.setLayoutData(newGridData(NUM_COL)); + label.setLayoutData(newGridData(3)); label.setToolTipText(tooltip); // root combo @@ -629,7 +572,7 @@ class NewXmlFileCreationPage extends WizardPage { mRootElementCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); mRootElementCombo.setToolTipText(tooltip); - padWithEmptyCells(parent, 2); + emptyCell(parent); } /** @@ -747,13 +690,11 @@ class NewXmlFileCreationPage extends WizardPage { // get the AndroidTargetData from the project IAndroidTarget target = Sdk.getCurrent().getTarget(mProject); AndroidTargetData data = Sdk.getCurrent().getTargetData(target); + ElementDescriptor descriptor = data.getDescriptorProvider( + (Integer)rootSeed).getDescriptor(); - IDescriptorProvider provider = data.getDescriptorProvider((Integer)rootSeed); - ElementDescriptor descriptor = provider.getDescriptor(); - if (descriptor != null) { - HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>(); - initRootElementDescriptor(roots, descriptor, visited); - } + HashSet<ElementDescriptor> visited = new HashSet<ElementDescriptor>(); + initRootElementDescriptor(roots, descriptor, visited); // Sort alphabetically. Collections.sort(roots); @@ -802,7 +743,15 @@ class NewXmlFileCreationPage extends WizardPage { } if (found != mProject) { - changeProject(found); + mProject = found; + + // update the Type with the new descriptors. + initializeRootValues(); + + // update the combo + updateRootCombo(getSelectedType()); + + validatePage(); } } @@ -812,27 +761,17 @@ class NewXmlFileCreationPage extends WizardPage { private void onProjectBrowse() { IJavaProject p = mProjectChooserHelper.chooseJavaProject(mProjectTextField.getText()); if (p != null) { - changeProject(p.getProject()); + mProject = p.getProject(); mProjectTextField.setText(mProject.getName()); + + // update the Type with the new descriptors. + initializeRootValues(); + + // update the combo + updateRootCombo(getSelectedType()); + + validatePage(); } - } - - /** - * Changes mProject to the given new project and update the UI accordingly. - */ - private void changeProject(IProject newProject) { - mProject = newProject; - - // enable types based on new API level - enableTypesBasedOnApi(); - - // update the Type with the new descriptors. - initializeRootValues(); - - // update the combo - updateRootCombo(getSelectedType()); - - validatePage(); } /** @@ -1047,26 +986,6 @@ class NewXmlFileCreationPage extends WizardPage { } /** - * Helper method to enable the type radio buttons depending on the current API level. - * <p/> - * A type radio button is enabled either if: - * - if mProject is null, API level 1 is considered valid - * - if mProject is !null, the project->target->API must be >= to the type's API level. - */ - private void enableTypesBasedOnApi() { - - IAndroidTarget target = mProject != null ? Sdk.getCurrent().getTarget(mProject) : null; - int currentApiLevel = 1; - if (target != null) { - currentApiLevel = target.getApiVersionNumber(); - } - - for (TypeInfo type : sTypes) { - type.getWidget().setEnabled(type.getTargetApiLevel() <= currentApiLevel); - } - } - - /** * Validates the fields, displays errors and warnings. * Enables the finish button if there are no errors. */ @@ -1098,22 +1017,6 @@ class NewXmlFileCreationPage extends WizardPage { } } - // -- validate type API level - if (error == null) { - IAndroidTarget target = Sdk.getCurrent().getTarget(mProject); - int currentApiLevel = 1; - if (target != null) { - currentApiLevel = target.getApiVersionNumber(); - } - - TypeInfo type = getSelectedType(); - - if (type.getTargetApiLevel() > currentApiLevel) { - error = "The API level of the selected type (e.g. gadget, etc.) is not " + - "compatible with the API level of the project."; - } - } - // -- validate folder configuration if (error == null) { ConfigurationState state = mConfigSelector.getState(); diff --git a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java index 7929b5a..fa1370f 100644 --- a/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java +++ b/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java @@ -53,9 +53,6 @@ public final class XmlDescriptors implements IDescriptorProvider { /** The root document descriptor for preferences. */ private DocumentDescriptor mPrefDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ - /** The root document descriptor for gadget provider. */ - private DocumentDescriptor mGadgetDescriptor = new DocumentDescriptor("xml_doc", null /* children */); //$NON-NLS-1$ - /** @return the root descriptor for both searchable and preferences. */ public DocumentDescriptor getDescriptor() { return mDescriptor; @@ -75,11 +72,6 @@ public final class XmlDescriptors implements IDescriptorProvider { return mPrefDescriptor; } - /** @return the root descriptor for gadget providers. */ - public DocumentDescriptor getGadgetDescriptor() { - return mGadgetDescriptor; - } - public IDescriptorProvider getSearchableProvider() { return new IDescriptorProvider() { public ElementDescriptor getDescriptor() { @@ -104,18 +96,6 @@ public final class XmlDescriptors implements IDescriptorProvider { }; } - public IDescriptorProvider getGadgetProvider() { - return new IDescriptorProvider() { - public ElementDescriptor getDescriptor() { - return mGadgetDescriptor; - } - - public ElementDescriptor[] getRootElementDescriptors() { - return mGadgetDescriptor.getChildren(); - } - }; - } - /** * Updates the document descriptor. * <p/> @@ -123,13 +103,11 @@ public final class XmlDescriptors implements IDescriptorProvider { * all at once. * * @param searchableStyleMap The map style=>attributes for <searchable> from the attrs.xml file - * @param gadgetStyleMap The map style=>attributes for <gadget-provider> from the attrs.xml file * @param prefs The list of non-group preference descriptions * @param prefGroups The list of preference group descriptions */ public synchronized void updateDescriptors( Map<String, DeclareStyleableInfo> searchableStyleMap, - Map<String, DeclareStyleableInfo> gadgetStyleMap, ViewClassInfo[] prefs, ViewClassInfo[] prefGroups) { XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor( @@ -137,17 +115,12 @@ public final class XmlDescriptors implements IDescriptorProvider { SdkConstants.NS_RESOURCES); ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns); - ElementDescriptor gadget = createGadgetProviderInfo(gadgetStyleMap, xmlns); ElementDescriptor preferences = createPreference(prefs, prefGroups, xmlns); ArrayList<ElementDescriptor> list = new ArrayList<ElementDescriptor>(); if (searchable != null) { list.add(searchable); mSearchDescriptor.setChildren(new ElementDescriptor[]{ searchable }); } - if (gadget != null) { - list.add(gadget); - mGadgetDescriptor.setChildren(new ElementDescriptor[]{ gadget }); - } if (preferences != null) { list.add(preferences); mPrefDescriptor.setChildren(new ElementDescriptor[]{ preferences }); @@ -188,28 +161,6 @@ public final class XmlDescriptors implements IDescriptorProvider { false /* mandatory */ ); return searchable; } - - /** - * Returns the new ElementDescriptor for <gadget-provider> - */ - private ElementDescriptor createGadgetProviderInfo( - Map<String, DeclareStyleableInfo> gadgetStyleMap, - XmlnsAttributeDescriptor xmlns) { - - if (gadgetStyleMap == null) { - return null; - } - - ElementDescriptor gadget = createElement(gadgetStyleMap, - "GadgetProviderInfo", //$NON-NLS-1$ styleName - "gadget-provider", //$NON-NLS-1$ xmlName - "Gadget Provider", // uiName - null, // sdk url - xmlns, // extraAttribute - null, // childrenElements - false /* mandatory */ ); - return gadget; - } /** * Returns a new ElementDescriptor constructed from the information given here diff --git a/eclipse/scripts/collect_sources_for_sdk.sh b/eclipse/scripts/collect_sources_for_sdk.sh index 4824da7..4637595 100644 --- a/eclipse/scripts/collect_sources_for_sdk.sh +++ b/eclipse/scripts/collect_sources_for_sdk.sh @@ -22,13 +22,6 @@ if [ "-n" == "$1" ]; then shift fi -DIR="frameworks" -if [ "-s" == "$1" ]; then - shift - DIR="$1" - shift -fi - SRC="$1" DST="$2" @@ -43,7 +36,7 @@ function process() { N=0 E=0 -for i in `find -L "${SRC}/${DIR}" -name "*.java"`; do +for i in `find -L "${SRC}/frameworks" -name "*.java"`; do if [ -f "$i" ]; then # look for ^package (android.view.blah);$ PACKAGE=`sed -n '/^package [^ ;]\+; */{s/[^ ]* *\([^ ;]*\).*/\1/p;q}' "$i"` diff --git a/hierarchyviewer/etc/hierarchyviewer.bat b/hierarchyviewer/etc/hierarchyviewer.bat index 2024a79..67e4f80 100755 --- a/hierarchyviewer/etc/hierarchyviewer.bat +++ b/hierarchyviewer/etc/hierarchyviewer.bat @@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks, rem and set up progdir to be the fully-qualified pathname of its directory. set prog=%~f0 -rem Change current directory and drive to where the script is, to avoid -rem issues with directories containing whitespaces. -cd /d %~dp0 +rem Change current directory to where ddms is, to avoid issues with directories +rem containing whitespaces. +cd %~dp0 set jarfile=hierarchyviewer.jar set frameworkdir= diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java index 51e1396..6efb52d6 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyLoader.java @@ -32,7 +32,6 @@ import java.net.Socket; import java.util.Collections; import java.util.Comparator; import java.util.Stack; -import java.util.regex.Pattern; public class ViewHierarchyLoader { @SuppressWarnings("empty-statement") @@ -110,9 +109,7 @@ public class ViewHierarchyLoader { parent.children.add(lastNode); } } - - updateIndices(scene.getRoot()); - + } catch (IOException ex) { Exceptions.printStackTrace(ex); } finally { @@ -130,18 +127,10 @@ public class ViewHierarchyLoader { } System.out.println("==> DONE"); - + return scene; } - - private static void updateIndices(ViewNode root) { - root.computeIndex(); - - for (ViewNode node : root.children) { - updateIndices(node); - } - } - + private static int countFrontWhitespace(String line) { int count = 0; while (line.charAt(count) == ' ') { diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java index 08dc395..d99a80c 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewHierarchyScene.java @@ -60,25 +60,22 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { @Override protected Widget attachNodeWidget(ViewNode node) { - Widget widget = createBox(node, node.name, node.id); + Widget widget = createBox(node.name, node.id); widget.getActions().addAction(createSelectAction()); widget.getActions().addAction(moveAction); widgetLayer.addChild(widget); return widget; } - private Widget createBox(ViewNode node, String nodeName, String id) { - final String shortName = getShortName(nodeName); - node.setShortName(shortName); - - GradientWidget box = new GradientWidget(this, node); + private Widget createBox(String node, String id) { + Widget box = new GradientWidget(this); box.setLayout(LayoutFactory.createVerticalFlowLayout()); box.setBorder(BorderFactory.createLineBorder(2, Color.BLACK)); box.setOpaque(true); LabelWidget label = new LabelWidget(this); label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 12.0f)); - label.setLabel(shortName); + label.setLabel(getShortName(node)); label.setBorder(BorderFactory.createEmptyBorder(6, 6, 0, 6)); label.setAlignment(LabelWidget.Alignment.CENTER); @@ -86,11 +83,9 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { label = new LabelWidget(this); label.setFont(getDefaultFont().deriveFont(Font.PLAIN, 10.0f)); - label.setLabel(getAddress(nodeName)); + label.setLabel(getAddress(node)); label.setBorder(BorderFactory.createEmptyBorder(3, 6, 0, 6)); label.setAlignment(LabelWidget.Alignment.CENTER); - - box.addressWidget = label; box.addChild(label); @@ -141,7 +136,7 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { connection.setTargetAnchor(AnchorFactory.createRectangularAnchor(target)); } - private static class GradientWidget extends Widget implements ViewNode.StateListener { + private static class GradientWidget extends Widget { public static final GradientPaint BLUE_EXPERIENCE = new GradientPaint( new Point2D.Double(0, 0), new Color(168, 204, 241), @@ -182,28 +177,15 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { new Color(129, 138, 155), new Point2D.Double(0, 1), new Color(58, 66, 82)); - public static final GradientPaint NIGHT_GRAY_VERY_LIGHT = new GradientPaint( - new Point2D.Double(0, 0), - new Color(129, 138, 155, 60), - new Point2D.Double(0, 1), - new Color(58, 66, 82, 60)); private static Color UNSELECTED = Color.BLACK; private static Color SELECTED = Color.WHITE; - private final ViewNode node; - - private LabelWidget addressWidget; - private boolean isSelected = false; - private final GradientPaint selectedGradient = MAC_OSX_SELECTED; - private final GradientPaint filteredGradient = RED_XP; - private final GradientPaint focusGradient = NIGHT_GRAY_VERY_LIGHT; + private GradientPaint gradient = MAC_OSX_SELECTED; - public GradientWidget(ViewHierarchyScene scene, ViewNode node) { + public GradientWidget(ViewHierarchyScene scene) { super(scene); - this.node = node; - node.setStateListener(this); } @Override @@ -211,12 +193,8 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { super.notifyStateChanged(previous, state); isSelected = state.isSelected() || state.isFocused() || state.isWidgetFocused(); - pickChildrenColor(); - } - - private void pickChildrenColor() { for (Widget child : getChildren()) { - child.setForeground(isSelected || node.filtered ? SELECTED : UNSELECTED); + child.setForeground(isSelected ? SELECTED : UNSELECTED); } repaint(); @@ -228,35 +206,14 @@ public class ViewHierarchyScene extends GraphScene<ViewNode, String> { Graphics2D g2 = getGraphics(); Rectangle bounds = getBounds(); - + if (!isSelected) { - if (!node.filtered) { - if (!node.hasFocus) { - g2.setColor(Color.WHITE); - } else { - g2.setPaint(new GradientPaint(bounds.x, bounds.y, - focusGradient.getColor1(), bounds.x, bounds.x + bounds.height, - focusGradient.getColor2())); - } - } else { - g2.setPaint(new GradientPaint(bounds.x, bounds.y, filteredGradient.getColor1(), - bounds.x, bounds.x + bounds.height, filteredGradient.getColor2())); - } + g2.setColor(Color.WHITE); } else { - g2.setPaint(new GradientPaint(bounds.x, bounds.y, selectedGradient.getColor1(), - bounds.x, bounds.x + bounds.height, selectedGradient.getColor2())); + g2.setPaint(new GradientPaint(bounds.x, bounds.y, gradient.getColor1(), + bounds.x, bounds.x + bounds.height, gradient.getColor2())); } g2.fillRect(bounds.x, bounds.y, bounds.width, bounds.height); } - - public void nodeStateChanged(ViewNode node) { - pickChildrenColor(); - } - - public void nodeIndexChanged(ViewNode node) { - if (addressWidget != null) { - addressWidget.setLabel("#" + node.index + addressWidget.getLabel()); - } - } } } diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java index 2b7efd6..6b212c0 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewManager.java @@ -17,6 +17,7 @@ package com.android.hierarchyviewer.scene; import com.android.ddmlib.Device; +import com.android.hierarchyviewer.device.Configuration; import com.android.hierarchyviewer.device.Window; import com.android.hierarchyviewer.device.DeviceBridge; diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java index 64c0703..8284df1 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/scene/ViewNode.java @@ -21,7 +21,6 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.regex.Pattern; public class ViewNode { public String id; @@ -53,15 +52,8 @@ public class ViewNode { public boolean willNotDraw; public boolean hasMargins; - boolean hasFocus; - int index; - public boolean decoded; - public boolean filtered; - - private String shortName; - private StateListener listener; - + void decode() { id = namedProperties.get("mID").value; @@ -81,7 +73,6 @@ public class ViewNode { marginBottom = getInt("layout_bottomMargin", Integer.MIN_VALUE); baseline = getInt("getBaseline()", 0); willNotDraw = getBoolean("willNotDraw()", false); - hasFocus = getBoolean("hasFocus()", false); hasMargins = marginLeft != Integer.MIN_VALUE && marginRight != Integer.MIN_VALUE && @@ -110,33 +101,11 @@ public class ViewNode { return Integer.parseInt(p.value); } catch (NumberFormatException e) { return defaultValue; - } + } } return defaultValue; } - public void filter(Pattern pattern) { - if (pattern == null || pattern.pattern().length() == 0) { - filtered = false; - } else { - filtered = pattern.matcher(shortName).find() || pattern.matcher(id).find(); - } - listener.nodeStateChanged(this); - } - - void computeIndex() { - index = parent == null ? 0 : parent.children.indexOf(this); - listener.nodeIndexChanged(this); - } - - void setShortName(String shortName) { - this.shortName = shortName; - } - - void setStateListener(StateListener listener) { - this.listener = listener; - } - @SuppressWarnings({"StringEquality"}) @Override public boolean equals(Object obj) { @@ -195,9 +164,4 @@ public class ViewNode { return hash; } } - - interface StateListener { - void nodeStateChanged(ViewNode node); - void nodeIndexChanged(ViewNode node); - } } diff --git a/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java b/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java index 20093ae..0add4e9 100644 --- a/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java +++ b/hierarchyviewer/src/com/android/hierarchyviewer/ui/Workspace.java @@ -76,9 +76,6 @@ import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.JTree; import javax.swing.Box; -import javax.swing.JTextField; -import javax.swing.text.Document; -import javax.swing.text.BadLocationException; import javax.swing.tree.TreePath; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.event.ChangeEvent; @@ -87,8 +84,6 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import javax.swing.event.TreeSelectionListener; import javax.swing.event.TreeSelectionEvent; -import javax.swing.event.DocumentListener; -import javax.swing.event.DocumentEvent; import javax.swing.table.DefaultTableModel; import java.awt.image.BufferedImage; import java.awt.BorderLayout; @@ -110,8 +105,6 @@ import java.io.IOException; import java.util.ArrayList; import java.util.HashSet; import java.util.Set; -import java.util.regex.Pattern; -import java.util.regex.PatternSyntaxException; import java.util.concurrent.ExecutionException; public class Workspace extends JFrame { @@ -163,8 +156,6 @@ public class Workspace extends JFrame { private JTable windows; private JLabel minZoomLabel; private JLabel maxZoomLabel; - private JTextField filterText; - private JLabel filterLabel; public Workspace() { super("Hierarchy Viewer"); @@ -322,33 +313,10 @@ public class Workspace extends JFrame { graphViewButton.setSelected(true); - filterText = new JTextField(20); - filterText.putClientProperty("JComponent.sizeVariant", "small"); - filterText.getDocument().addDocumentListener(new DocumentListener() { - public void insertUpdate(DocumentEvent e) { - updateFilter(e); - } - - public void removeUpdate(DocumentEvent e) { - updateFilter(e); - } - - public void changedUpdate(DocumentEvent e) { - updateFilter(e); - } - }); - - filterLabel = new JLabel("Filter by class or id:"); - filterLabel.putClientProperty("JComponent.sizeVariant", "small"); - filterLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 6)); - - leftSide.add(filterLabel); - leftSide.add(filterText); - minZoomLabel = new JLabel(); minZoomLabel.setText("20%"); minZoomLabel.putClientProperty("JComponent.sizeVariant", "small"); - minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0)); + minZoomLabel.setBorder(BorderFactory.createEmptyBorder(0, 6, 0, 0)); leftSide.add(minZoomLabel); zoomSlider = new JSlider(); @@ -389,18 +357,12 @@ public class Workspace extends JFrame { statusPanel.add(rightSide, BorderLayout.LINE_END); - hideStatusBarComponents(); - - return statusPanel; - } - - private void hideStatusBarComponents() { viewCountLabel.setVisible(false); zoomSlider.setVisible(false); minZoomLabel.setVisible(false); - maxZoomLabel.setVisible(false); - filterLabel.setVisible(false); - filterText.setVisible(false); + maxZoomLabel.setVisible(false); + + return statusPanel; } private JToolBar buildToolBar() { @@ -551,7 +513,10 @@ public class Workspace extends JFrame { } private void toggleGraphView() { - showStatusBarComponents(); + viewCountLabel.setVisible(true); + zoomSlider.setVisible(true); + minZoomLabel.setVisible(true); + maxZoomLabel.setVisible(true); screenViewer.stop(); mainPanel.remove(pixelPerfectPanel); @@ -561,15 +526,6 @@ public class Workspace extends JFrame { repaint(); } - private void showStatusBarComponents() { - viewCountLabel.setVisible(true); - zoomSlider.setVisible(true); - minZoomLabel.setVisible(true); - maxZoomLabel.setVisible(true); - filterLabel.setVisible(true); - filterText.setVisible(true); - } - private void togglePixelPerfectView() { if (pixelPerfectPanel == null) { pixelPerfectPanel = buildPixelPerfectPanel(); @@ -578,7 +534,10 @@ public class Workspace extends JFrame { screenViewer.start(); } - hideStatusBarComponents(); + viewCountLabel.setVisible(false); + zoomSlider.setVisible(false); + minZoomLabel.setVisible(false); + maxZoomLabel.setVisible(false); mainPanel.remove(mainSplitter); mainPanel.add(pixelPerfectPanel, BorderLayout.CENTER); @@ -643,7 +602,10 @@ public class Workspace extends JFrame { graphViewButton.setEnabled(true); pixelPerfectViewButton.setEnabled(true); - showStatusBarComponents(); + viewCountLabel.setVisible(true); + zoomSlider.setVisible(true); + minZoomLabel.setVisible(true); + maxZoomLabel.setVisible(true); } sceneView = scene.createView(); @@ -814,7 +776,10 @@ public class Workspace extends JFrame { pixelPerfectPanel = mainSplitter = null; graphViewButton.setSelected(true); - hideStatusBarComponents(); + viewCountLabel.setVisible(false); + zoomSlider.setVisible(false); + minZoomLabel.setVisible(false); + maxZoomLabel.setVisible(false); saveMenuItem.setEnabled(false); showDevicesMenuItem.setEnabled(false); @@ -900,34 +865,6 @@ public class Workspace extends JFrame { }); } - private void updateFilter(DocumentEvent e) { - final Document document = e.getDocument(); - try { - updateFilteredNodes(document.getText(0, document.getLength())); - } catch (BadLocationException e1) { - e1.printStackTrace(); - } - } - - private void updateFilteredNodes(String filterText) { - final ViewNode root = scene.getRoot(); - try { - final Pattern pattern = Pattern.compile(filterText, Pattern.CASE_INSENSITIVE); - filterNodes(pattern, root); - } catch (PatternSyntaxException e) { - filterNodes(null, root); - } - repaint(); - } - - private void filterNodes(Pattern pattern, ViewNode root) { - root.filter(pattern); - - for (ViewNode node : root.children) { - filterNodes(pattern, node); - } - } - public void beginTask() { progress.setVisible(true); } diff --git a/sdkmanager/app/etc/android.bat b/sdkmanager/app/etc/android.bat index de950ed..1af1e47 100755 --- a/sdkmanager/app/etc/android.bat +++ b/sdkmanager/app/etc/android.bat @@ -23,9 +23,9 @@ set prog=%~f0 rem Grab current directory before we change it set workdir=%cd% -rem Change current directory and drive to where the script is, to avoid -rem issues with directories containing whitespaces. -cd /d %~dp0 +rem Change current directory to where ddms is, to avoid issues with directories +rem containing whitespaces. +cd %~dp0 set jarfile=sdkmanager.jar set frameworkdir= diff --git a/sdkmanager/app/src/com/android/sdkmanager/Main.java b/sdkmanager/app/src/com/android/sdkmanager/Main.java index 154788e..1a15fce 100644 --- a/sdkmanager/app/src/com/android/sdkmanager/Main.java +++ b/sdkmanager/app/src/com/android/sdkmanager/Main.java @@ -383,28 +383,24 @@ class Main { */ private void displayAvdList() { try { - AvdManager avdManager = new AvdManager(mSdkManager, mSdkLog); + AvdManager avdManager = new AvdManager(mSdkManager, null /* sdklog */); mSdkLog.printf("Available Android Virtual Devices:\n"); - AvdInfo[] avds = avdManager.getAvds(); - for (int index = 0 ; index < avds.length ; index++) { - AvdInfo info = avds[index]; - if (index > 0) { - mSdkLog.printf("---------\n"); - } - mSdkLog.printf(" Name: %s\n", info.getName()); - mSdkLog.printf(" Path: %s\n", info.getPath()); + int index = 1; + for (AvdInfo info : avdManager.getAvds()) { + mSdkLog.printf("[%d] %s\n", index, info.getName()); + mSdkLog.printf(" Path: %s\n", info.getPath()); // get the target of the AVD IAndroidTarget target = info.getTarget(); if (target.isPlatform()) { - mSdkLog.printf(" Target: %s (API level %d)\n", target.getName(), + mSdkLog.printf(" Target: %s (API level %d)\n", target.getName(), target.getApiVersionNumber()); } else { - mSdkLog.printf(" Target: %s (%s)\n", target.getName(), target + mSdkLog.printf(" Target: %s (%s)\n", target.getName(), target .getVendor()); - mSdkLog.printf(" Based on Android %s (API level %d)\n", target + mSdkLog.printf(" Based on Android %s (API level %d)\n", target .getApiVersionName(), target.getApiVersionNumber()); } @@ -412,15 +408,17 @@ class Main { Map<String, String> properties = info.getProperties(); String skin = properties.get(AvdManager.AVD_INI_SKIN_NAME); if (skin != null) { - mSdkLog.printf(" Skin: %s\n", skin); + mSdkLog.printf(" Skin: %s\n", skin); } String sdcard = properties.get(AvdManager.AVD_INI_SDCARD_SIZE); if (sdcard == null) { sdcard = properties.get(AvdManager.AVD_INI_SDCARD_PATH); } if (sdcard != null) { - mSdkLog.printf(" Sdcard: %s\n", sdcard); + mSdkLog.printf(" Sdcard: %s\n", sdcard); } + + index++; } } catch (AndroidLocationException e) { errorAndExit(e.getMessage()); @@ -501,7 +499,7 @@ class Main { // Is it NNNxMMM? if (!valid) { - valid = AvdManager.NUMERIC_SKIN_SIZE.matcher(skin).matches(); + valid = skin.matches("[0-9]{2,}x[0-9]{2,}"); } if (!valid) { diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java index 00594d1..87f9b56 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java @@ -103,8 +103,6 @@ public final class SdkConstants { public final static String FD_ASSETS = "assets"; //$NON-NLS-1$ /** Default source folder name, i.e. "src" */ public final static String FD_SOURCES = "src"; //$NON-NLS-1$ - /** Default generated source folder name, i.e. "gen" */ - public final static String FD_GEN_SOURCES = "gen"; //$NON-NLS-1$ /** Default native library folder name inside the project, i.e. "libs" * While the folder inside the .apk is "lib", we call that one libs because * that's what we use in ant for both .jar and .so and we need to make the 2 development ways diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java index 2c0f164..b44cf01 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/avd/AvdManager.java @@ -55,12 +55,6 @@ public final class AvdManager { public final static String AVD_INI_IMAGES_1 = "image.sysdir.1"; public final static String AVD_INI_IMAGES_2 = "image.sysdir.2"; - /** - * Pattern to match pixel-sized skin "names", e.g. "320x480". - */ - public final static Pattern NUMERIC_SKIN_SIZE = Pattern.compile("[0-9]{2,}x[0-9]{2,}"); - - private final static String USERDATA_IMG = "userdata.img"; private final static String CONFIG_INI = "config.ini"; private final static String SDCARD_IMG = "sdcard.img"; @@ -261,22 +255,17 @@ public final class AvdManager { skinName = target.getDefaultSkin(); } - if (NUMERIC_SKIN_SIZE.matcher(skinName).matches()) { - // Skin name is an actual screen resolution, no skin.path - values.put(AVD_INI_SKIN_NAME, skinName); - } else { - // get the path of the skin (relative to the SDK) - // assume skin name is valid - String skinPath = getSkinRelativePath(skinName, target, log); - if (skinPath == null) { - needCleanup = true; - return null; - } - - values.put(AVD_INI_SKIN_PATH, skinPath); - values.put(AVD_INI_SKIN_NAME, skinName); + // get the path of the skin (relative to the SDK) + // assume skin name is valid + String skinPath = getSkinRelativePath(skinName, target, log); + if (skinPath == null) { + needCleanup = true; + return null; } + values.put(AVD_INI_SKIN_PATH, skinPath); + values.put(AVD_INI_SKIN_NAME, skinName); + if (sdcard != null) { File sdcardFile = new File(sdcard); if (sdcardFile.isFile()) { diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ApkConfigurationHelper.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ApkConfigurationHelper.java index b89d3bd..ab43f46 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ApkConfigurationHelper.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ApkConfigurationHelper.java @@ -25,30 +25,24 @@ import java.util.Map.Entry; * Helper class to read and write Apk Configuration into a {@link ProjectProperties} file. */ public class ApkConfigurationHelper { - /** Prefix for property names for config definition. This prevents having config named - * after other valid properties such as "target". */ - final static String CONFIG_PREFIX = "apk-config-"; /** * Reads the Apk Configurations from a {@link ProjectProperties} file and returns them as a map. * <p/>If there are no defined configurations, the returned map will be empty. - * @return a map of apk configurations. The map contains (name, filter) where name is - * the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of - * resource configuration to include in the apk (see aapt -c) */ public static Map<String, String> getConfigs(ProjectProperties properties) { HashMap<String, String> configMap = new HashMap<String, String>(); // get the list of configs. - String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS); + String configList = properties.getProperty(ProjectProperties.PROPERTY_CONFIGS); if (configList != null) { // this is a comma separated list String[] configs = configList.split(","); //$NON-NLS-1$ // read the value of each config and store it in a map + for (String config : configs) { - config = config.trim(); - String configValue = properties.getProperty(CONFIG_PREFIX + config); + String configValue = properties.getProperty(config); if (configValue != null) { configMap.put(config, configValue); } @@ -60,10 +54,6 @@ public class ApkConfigurationHelper { /** * Writes the Apk Configurations from a given map into a {@link ProjectProperties}. - * @param properties the {@link ProjectProperties} in which to store the apk configurations. - * @param configMap a map of apk configurations. The map contains (name, filter) where name is - * the name of the configuration (a-zA-Z0-9 only), and filter is the comma separated list of - * resource configuration to include in the apk (see aapt -c) * @return true if the {@link ProjectProperties} contained Apk Configuration that were not * present in the map. */ @@ -72,20 +62,17 @@ public class ApkConfigurationHelper { // in case a config was removed. // get the list of configs. - String configList = properties.getProperty(ProjectProperties.PROPERTY_APK_CONFIGS); - + String configList = properties.getProperty(ProjectProperties.PROPERTY_CONFIGS); + + // this is a comma separated list + String[] configs = configList.split(","); //$NON-NLS-1$ + boolean hasRemovedConfig = false; - - if (configList != null) { - // this is a comma separated list - String[] configs = configList.split(","); //$NON-NLS-1$ - - for (String config : configs) { - config = config.trim(); - if (configMap.containsKey(config) == false) { - hasRemovedConfig = true; - properties.removeProperty(CONFIG_PREFIX + config); - } + + for (String config : configs) { + if (configMap.containsKey(config) == false) { + hasRemovedConfig = true; + properties.removeProperty(config); } } @@ -97,9 +84,9 @@ public class ApkConfigurationHelper { sb.append(","); } sb.append(entry.getKey()); - properties.setProperty(CONFIG_PREFIX + entry.getKey(), entry.getValue()); + properties.setProperty(entry.getKey(), entry.getValue()); } - properties.setProperty(ProjectProperties.PROPERTY_APK_CONFIGS, sb.toString()); + properties.setProperty(ProjectProperties.PROPERTY_CONFIGS, sb.toString()); return hasRemovedConfig; } diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java index 7489b65..18e2ac9 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java @@ -209,7 +209,7 @@ public class ProjectCreator { } // create the source folder and the java package folders. - String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath; + final String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath; File sourceFolder = createDirs(projectFolder, srcFolderPath); String javaTemplate = "java_file.template"; String activityFileName = activityName + ".java"; @@ -220,10 +220,6 @@ public class ProjectCreator { installTemplate(javaTemplate, new File(sourceFolder, activityFileName), keywords, target); - // create the generate source folder - srcFolderPath = SdkConstants.FD_GEN_SOURCES + File.separator + packagePath; - sourceFolder = createDirs(projectFolder, srcFolderPath); - // create other useful folders File resourceFodler = createDirs(projectFolder, SdkConstants.FD_RESOURCES); createDirs(projectFolder, SdkConstants.FD_OUTPUT); diff --git a/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java b/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java index 69a16be..1f6a047 100644 --- a/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java +++ b/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java @@ -33,7 +33,7 @@ import java.util.Map.Entry; public final class ProjectProperties { /** The property name for the project target */ public final static String PROPERTY_TARGET = "target"; - public final static String PROPERTY_APK_CONFIGS = "apk-configurations"; + public final static String PROPERTY_CONFIGS = "configs"; public final static String PROPERTY_SDK = "sdk-location"; public static enum PropertyType { @@ -98,19 +98,7 @@ public final class ProjectProperties { // 1-------10--------20--------30--------40--------50--------60--------70--------80 COMMENT_MAP.put(PROPERTY_TARGET, "# Project target.\n"); - COMMENT_MAP.put(PROPERTY_APK_CONFIGS, - "# apk configurations. This property allows creation of APK files with limited\n" + - "# resources. For example, if your application contains many locales and\n" + - "# you wish to release multiple smaller apks instead of a large one, you can\n" + - "# define configuration to create apks with limited language sets.\n" + - "# Format is a comma separated list of configuration names. For each\n" + - "# configuration, a property will declare the resource configurations to\n" + - "# include. Example:\n" + - "# " + PROPERTY_APK_CONFIGS +"=european,northamerica\n" + - "# " + ApkConfigurationHelper.CONFIG_PREFIX + "european=en,fr,it,de,es\n" + - "# " + ApkConfigurationHelper.CONFIG_PREFIX + "northamerica=en,es\n"); - COMMENT_MAP.put(PROPERTY_SDK, - "# location of the SDK. This is only used by Ant\n" + + COMMENT_MAP.put(PROPERTY_SDK, "# location of the SDK. This is only used by Ant\n" + "# For customization when using a Version Control System, please read the\n" + "# header note.\n"); } diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigEditDialog.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigEditDialog.java deleted file mode 100644 index 1460fd7..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigEditDialog.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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.sdkuilib; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.IDialogConstants; -import org.eclipse.jface.window.Window; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ModifyEvent; -import org.eclipse.swt.events.ModifyListener; -import org.eclipse.swt.events.VerifyEvent; -import org.eclipse.swt.events.VerifyListener; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Control; -import org.eclipse.swt.widgets.Label; -import org.eclipse.swt.widgets.Shell; -import org.eclipse.swt.widgets.Text; - -/** - * Edit dialog to create/edit APK configuration. The dialog displays 2 text fields for the config - * name and its filter. - */ -class ApkConfigEditDialog extends Dialog implements ModifyListener, VerifyListener { - - private String mName; - private String mFilter; - private Text mNameField; - private Text mFilterField; - private Button mOkButton; - - /** - * Creates an edit dialog with optional initial values for the name and filter. - * @param name optional value for the name. Can be null. - * @param filter optional value for the filter. Can be null. - * @param parentShell the parent shell. - */ - protected ApkConfigEditDialog(String name, String filter, Shell parentShell) { - super(parentShell); - mName = name; - mFilter = filter; - } - - /** - * Returns the name of the config. This is only valid if the user clicked OK and {@link #open()} - * returned {@link Window#OK} - */ - public String getName() { - return mName; - } - - /** - * Returns the filter for the config. This is only valid if the user clicked OK and - * {@link #open()} returned {@link Window#OK} - */ - public String getFilter() { - return mFilter; - } - - @Override - protected Control createContents(Composite parent) { - Control control = super.createContents(parent); - - mOkButton = getButton(IDialogConstants.OK_ID); - validateButtons(); - - return control; - } - - @Override - protected Control createDialogArea(Composite parent) { - Composite composite = new Composite(parent, SWT.NONE); - GridLayout layout; - composite.setLayout(layout = new GridLayout(2, false)); - layout.marginHeight = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_MARGIN); - layout.marginWidth = convertHorizontalDLUsToPixels(IDialogConstants.HORIZONTAL_MARGIN); - layout.verticalSpacing = convertVerticalDLUsToPixels(IDialogConstants.VERTICAL_SPACING); - layout.horizontalSpacing = convertHorizontalDLUsToPixels( - IDialogConstants.HORIZONTAL_SPACING); - - composite.setLayoutData(new GridData(GridData.FILL_BOTH)); - - Label l = new Label(composite, SWT.NONE); - l.setText("Name"); - - mNameField = new Text(composite, SWT.BORDER); - mNameField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - mNameField.addVerifyListener(this); - if (mName != null) { - mNameField.setText(mName); - } - mNameField.addModifyListener(this); - - l = new Label(composite, SWT.NONE); - l.setText("Filter"); - - mFilterField = new Text(composite, SWT.BORDER); - mFilterField.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - if (mFilter != null) { - mFilterField.setText(mFilter); - } - mFilterField.addVerifyListener(this); - mFilterField.addModifyListener(this); - - applyDialogFont(composite); - return composite; - } - - /** - * Validates the OK button based on the content of the 2 text fields. - */ - private void validateButtons() { - mOkButton.setEnabled(mNameField.getText().trim().length() > 0 && - mFilterField.getText().trim().length() > 0); - } - - @Override - protected void okPressed() { - mName = mNameField.getText(); - mFilter = mFilterField.getText().trim(); - super.okPressed(); - } - - /** - * Callback for text modification in the 2 text fields. - */ - public void modifyText(ModifyEvent e) { - validateButtons(); - } - - /** - * Callback to ensure the content of the text field are proper. - */ - public void verifyText(VerifyEvent e) { - Text source = ((Text)e.getSource()); - if (source == mNameField) { - // check for a-zA-Z0-9. - final String text = e.text; - final int len = text.length(); - for (int i = 0 ; i < len; i++) { - char letter = text.charAt(i); - if (letter > 255 || Character.isLetterOrDigit(letter) == false) { - e.doit = false; - return; - } - } - } else if (source == mFilterField) { - // we can't validate the content as its typed, but we can at least ensure the characters - // are valid. Same as mNameFiled + the comma. - final String text = e.text; - final int len = text.length(); - for (int i = 0 ; i < len; i++) { - char letter = text.charAt(i); - if (letter > 255 || (Character.isLetterOrDigit(letter) == false && letter != ',')) { - e.doit = false; - return; - } - } - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigWidget.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigWidget.java deleted file mode 100644 index 6bf1df3..0000000 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/ApkConfigWidget.java +++ /dev/null @@ -1,211 +0,0 @@ -/* - * 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.sdkuilib; - -import org.eclipse.jface.dialogs.Dialog; -import org.eclipse.jface.dialogs.MessageDialog; -import org.eclipse.swt.SWT; -import org.eclipse.swt.events.ControlAdapter; -import org.eclipse.swt.events.ControlEvent; -import org.eclipse.swt.events.SelectionAdapter; -import org.eclipse.swt.events.SelectionEvent; -import org.eclipse.swt.graphics.Rectangle; -import org.eclipse.swt.layout.GridData; -import org.eclipse.swt.layout.GridLayout; -import org.eclipse.swt.widgets.Button; -import org.eclipse.swt.widgets.Composite; -import org.eclipse.swt.widgets.Table; -import org.eclipse.swt.widgets.TableColumn; -import org.eclipse.swt.widgets.TableItem; - -import java.util.Arrays; -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -/** - * The APK Configuration widget is a table that is added to the given parent composite. - * <p/> - * To use, create it using {@link #ApkConfigWidget(Composite)} then - * call {@link #fillTable(Map) to set the initial list of configurations. - */ -public class ApkConfigWidget { - private final static int INDEX_NAME = 0; - private final static int INDEX_FILTER = 1; - - private Table mApkConfigTable; - private Button mEditButton; - private Button mDelButton; - - public ApkConfigWidget(final Composite parent) { - final Composite apkConfigComp = new Composite(parent, SWT.NONE); - apkConfigComp.setLayoutData(new GridData(GridData.FILL_BOTH)); - apkConfigComp.setLayout(new GridLayout(2, false)); - - mApkConfigTable = new Table(apkConfigComp, SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER); - mApkConfigTable.setHeaderVisible(true); - mApkConfigTable.setLinesVisible(true); - - GridData data = new GridData(); - data.grabExcessVerticalSpace = true; - data.grabExcessHorizontalSpace = true; - data.horizontalAlignment = GridData.FILL; - data.verticalAlignment = GridData.FILL; - mApkConfigTable.setLayoutData(data); - - // create the table columns - final TableColumn column0 = new TableColumn(mApkConfigTable, SWT.NONE); - column0.setText("Name"); - column0.setWidth(100); - final TableColumn column1 = new TableColumn(mApkConfigTable, SWT.NONE); - column1.setText("Configuration"); - column1.setWidth(100); - - Composite buttonComp = new Composite(apkConfigComp, SWT.NONE); - buttonComp.setLayoutData(new GridData(GridData.FILL_VERTICAL)); - GridLayout gl; - buttonComp.setLayout(gl = new GridLayout(1, false)); - gl.marginHeight = gl.marginWidth = 0; - - Button newButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT); - newButton.setText("New..."); - newButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - mEditButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT); - mEditButton.setText("Edit..."); - mEditButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - mDelButton = new Button(buttonComp, SWT.PUSH | SWT.FLAT); - mDelButton.setText("Delete"); - mDelButton.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); - - newButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - ApkConfigEditDialog dlg = new ApkConfigEditDialog(null /*name*/, null /*filter*/, - apkConfigComp.getShell()); - if (dlg.open() == Dialog.OK) { - TableItem item = new TableItem(mApkConfigTable, SWT.NONE); - item.setText(INDEX_NAME, dlg.getName()); - item.setText(INDEX_FILTER, dlg.getFilter()); - - onSelectionChanged(); - } - } - }); - - mEditButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - // get the current selection (single mode so we don't care about any item beyond - // index 0). - TableItem[] items = mApkConfigTable.getSelection(); - if (items.length != 0) { - ApkConfigEditDialog dlg = new ApkConfigEditDialog( - items[0].getText(INDEX_NAME), items[0].getText(INDEX_FILTER), - apkConfigComp.getShell()); - if (dlg.open() == Dialog.OK) { - items[0].setText(INDEX_NAME, dlg.getName()); - items[0].setText(INDEX_FILTER, dlg.getFilter()); - } - } - } - }); - - mDelButton.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - // get the current selection (single mode so we don't care about any item beyond - // index 0). - int[] indices = mApkConfigTable.getSelectionIndices(); - if (indices.length != 0) { - TableItem item = mApkConfigTable.getItem(indices[0]); - if (MessageDialog.openQuestion(parent.getShell(), - "Apk Configuration deletion", - String.format( - "Are you sure you want to delete configuration '%1$s'?", - item.getText(INDEX_NAME)))) { - // delete the item. - mApkConfigTable.remove(indices[0]); - - onSelectionChanged(); - } - } - } - }); - - // Add a listener to resize the column to the full width of the table - mApkConfigTable.addControlListener(new ControlAdapter() { - @Override - public void controlResized(ControlEvent e) { - Rectangle r = mApkConfigTable.getClientArea(); - column0.setWidth(r.width * 30 / 100); // 30% - column1.setWidth(r.width * 70 / 100); // 70% - } - }); - - // add a selection listener on the table, to enable/disable buttons. - mApkConfigTable.addSelectionListener(new SelectionAdapter() { - @Override - public void widgetSelected(SelectionEvent e) { - onSelectionChanged(); - } - }); - } - - public void fillTable(Map<String, String> apkConfigMap) { - // get the names in a list so that we can sort them. - if (apkConfigMap != null) { - Set<String> keys = apkConfigMap.keySet(); - String[] keyArray = keys.toArray(new String[keys.size()]); - Arrays.sort(keyArray); - - for (String key : keyArray) { - TableItem item = new TableItem(mApkConfigTable, SWT.NONE); - item.setText(INDEX_NAME, key); - item.setText(INDEX_FILTER, apkConfigMap.get(key)); - } - } - - onSelectionChanged(); - } - - public Map<String, String> getApkConfigs() { - // go through all the items from the table and fill a new map - HashMap<String, String> map = new HashMap<String, String>(); - - TableItem[] items = mApkConfigTable.getItems(); - for (TableItem item : items) { - map.put(item.getText(INDEX_NAME), item.getText(INDEX_FILTER)); - } - - return map; - } - - /** - * Handles table selection changes. - */ - private void onSelectionChanged() { - if (mApkConfigTable.getSelectionCount() > 0) { - mEditButton.setEnabled(true); - mDelButton.setEnabled(true); - } else { - mEditButton.setEnabled(false); - mDelButton.setEnabled(false); - } - } -} diff --git a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java index 5f9e9c2..fc951f2 100644 --- a/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java +++ b/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java @@ -48,57 +48,32 @@ import java.util.ArrayList; */ public class SdkTargetSelector { - private IAndroidTarget[] mTargets; - private final boolean mAllowSelection; + private final IAndroidTarget[] mTargets; private final boolean mAllowMultipleSelection; private SelectionListener mSelectionListener; private Table mTable; private Label mDescription; - private Composite mInnerGroup; - + /** * Creates a new SDK Target Selector. * * @param parent The parent composite where the selector will be added. * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. - * Targets can be null or an empty array, in which case the table is disabled. * @param allowMultipleSelection True if more than one SDK target can be selected at the same * time. */ public SdkTargetSelector(Composite parent, IAndroidTarget[] targets, boolean allowMultipleSelection) { - this(parent, targets, true /*allowSelection*/, allowMultipleSelection); - } + mTargets = targets; - /** - * Creates a new SDK Target Selector. - * - * @param parent The parent composite where the selector will be added. - * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. - * Targets can be null or an empty array, in which case the table is disabled. - * @param allowSelection True if selection is enabled. - * @param allowMultipleSelection True if more than one SDK target can be selected at the same - * time. Used only if allowSelection is true. - */ - public SdkTargetSelector(Composite parent, IAndroidTarget[] targets, - boolean allowSelection, - boolean allowMultipleSelection) { // Layout has 1 column - mInnerGroup = new Composite(parent, SWT.NONE); - mInnerGroup.setLayout(new GridLayout()); - mInnerGroup.setLayoutData(new GridData(GridData.FILL_BOTH)); - mInnerGroup.setFont(parent.getFont()); + Composite group = new Composite(parent, SWT.NONE); + group.setLayout(new GridLayout()); + group.setLayoutData(new GridData(GridData.FILL_BOTH)); + group.setFont(parent.getFont()); - mAllowSelection = allowSelection; mAllowMultipleSelection = allowMultipleSelection; - int style = SWT.BORDER; - if (allowSelection) { - style |= SWT.CHECK | SWT.FULL_SELECTION; - } - if (!mAllowMultipleSelection) { - style |= SWT.SINGLE; - } - mTable = new Table(mInnerGroup, style); + mTable = new Table(group, SWT.CHECK | SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER); mTable.setHeaderVisible(true); mTable.setLinesVisible(false); @@ -109,7 +84,7 @@ public class SdkTargetSelector { data.verticalAlignment = GridData.FILL; mTable.setLayoutData(data); - mDescription = new Label(mInnerGroup, SWT.WRAP); + mDescription = new Label(group, SWT.WRAP); mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); // create the table columns @@ -118,26 +93,15 @@ public class SdkTargetSelector { final TableColumn column1 = new TableColumn(mTable, SWT.NONE); column1.setText("Vendor"); final TableColumn column2 = new TableColumn(mTable, SWT.NONE); - column2.setText("Version"); + column2.setText("API Level"); final TableColumn column3 = new TableColumn(mTable, SWT.NONE); - column3.setText("API Level"); + column3.setText("SDK"); adjustColumnsWidth(mTable, column0, column1, column2, column3); setupSelectionListener(mTable); - setTargets(targets); + fillTable(mTable); setupTooltip(mTable); } - - /** - * Returns the layout data of the inner composite widget that contains the target selector. - * By default the layout data is set to a {@link GridData} with a {@link GridData#FILL_BOTH} - * mode. - * <p/> - * This can be useful if you want to change the {@link GridData#horizontalSpan} for example. - */ - public Object getLayoutData() { - return mInnerGroup.getLayoutData(); - } /** * Returns the list of known targets. @@ -149,16 +113,6 @@ public class SdkTargetSelector { } /** - * Changes the targets of the SDK Target Selector. - * - * @param targets The list of targets. This is <em>not</em> copied, the caller must not modify. - */ - public void setTargets(IAndroidTarget[] targets) { - mTargets = targets; - fillTable(mTable); - } - - /** * Sets a selection listener. Set it to null to remove it. * The listener will be called <em>after</em> this table processed its selection * events so that the caller can see the updated state. @@ -185,10 +139,6 @@ public class SdkTargetSelector { * @return true if the target could be selected, false otherwise. */ public boolean setSelection(IAndroidTarget target) { - if (!mAllowSelection) { - return false; - } - boolean found = false; boolean modified = false; for (TableItem i : mTable.getItems()) { @@ -274,10 +224,6 @@ public class SdkTargetSelector { * double-clicked (aka "the default selection"). */ private void setupSelectionListener(final Table table) { - if (!mAllowSelection) { - return; - } - // Add a selection listener that will check/uncheck items when they are double-clicked table.addSelectionListener(new SelectionListener() { /** Default selection means double-click on "most" platforms */ @@ -335,9 +281,6 @@ public class SdkTargetSelector { * </ul> */ private void fillTable(final Table table) { - - table.removeAll(); - if (mTargets != null && mTargets.length > 0) { table.setEnabled(true); for (IAndroidTarget target : mTargets) { diff --git a/traceview/etc/traceview.bat b/traceview/etc/traceview.bat index a9b573d..d074f42 100755 --- a/traceview/etc/traceview.bat +++ b/traceview/etc/traceview.bat @@ -20,9 +20,9 @@ rem Set up prog to be the path of this script, including following symlinks, rem and set up progdir to be the fully-qualified pathname of its directory. set prog=%~f0 -rem Change current directory and drive to where traceview.bat is, to avoid -rem issues with directories containing whitespaces. -cd /d %~dp0 +rem Change current directory to where traceview is, to avoid issues with directories +rem containing whitespaces. +cd %~dp0 set jarfile=traceview.jar set frameworkdir= |