summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2009-01-20 14:05:23 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2009-01-20 14:05:23 -0800
commit2d6668aaf09b01a045954c824183d53482fadafe (patch)
treee045a54a6979ee399dd7931576d6a0b13d9b9c98
parentdb1b7a2e17ba200c36b7ab73920a76b28a43974c (diff)
parent7b53e3937797ee1eea71c6291bdcd58cb9dedf7a (diff)
downloadandroid_development-2d6668aaf09b01a045954c824183d53482fadafe.tar.gz
android_development-2d6668aaf09b01a045954c824183d53482fadafe.tar.bz2
android_development-2d6668aaf09b01a045954c824183d53482fadafe.zip
Merge branch 'cupcake'
-rw-r--r--build/sdk.atree4
-rwxr-xr-xbuild/tools/make_windows_sdk.sh3
-rw-r--r--host/windows/prebuilt/usb/driver_amd_64/androidusb.sysbin31744 -> 37360 bytes
-rw-r--r--host/windows/prebuilt/usb/driver_amd_64/androidusba64.catbin1811 -> 7282 bytes
-rw-r--r--pdk/Pdk.mk9
-rw-r--r--pdk/README4
-rw-r--r--pdk/doxygen_config/footer.html2
-rw-r--r--pdk/doxygen_config/header.html15
-rw-r--r--samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java248
-rw-r--r--tools/activitycreator/.classpath6
-rw-r--r--tools/activitycreator/.project17
-rw-r--r--tools/activitycreator/Android.mk17
-rw-r--r--tools/activitycreator/MODULE_LICENSE_APACHE20
-rw-r--r--tools/activitycreator/etc/Android.mk20
-rwxr-xr-xtools/activitycreator/etc/activitycreator20
-rwxr-xr-xtools/activitycreator/etc/activitycreator.bat22
-rw-r--r--tools/activitycreator/src/Android.mk23
-rw-r--r--tools/activitycreator/src/com/android/activitycreator/ActivityCreator.java881
-rw-r--r--tools/androidprefs/src/com/android/prefs/AndroidLocation.java44
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/.project2
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java2
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java3
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java5
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java4
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java10
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java4
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java7
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java4
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ReferenceAttributeDescriptor.java6
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java4
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/WidgetPullParser.java5
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java9
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementEditPart.java4
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/uimodel/UiViewElementNode.java3
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java5
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java4
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiManifestElementNode.java6
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/descriptors/MenuDescriptors.java6
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiElementNode.java18
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiListAttributeNode.java4
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java10
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlEditor.java3
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java11
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath1
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.tests/.project1
-rw-r--r--tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/layout/UiElementPullParserTest.java39
-rwxr-xr-xtools/runtest2
-rw-r--r--tools/scripts/build.alias.template2
-rw-r--r--tools/scripts/build.template2
-rw-r--r--tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java59
-rw-r--r--tools/sdkmanager/app/src/com/android/sdkmanager/Main.java44
-rw-r--r--tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java34
-rw-r--r--tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java48
-rw-r--r--tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java22
-rw-r--r--tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java366
-rw-r--r--tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java4
-rw-r--r--tools/sdkmanager/libs/sdklib/src/com/android/sdklib/vm/VmManager.java184
57 files changed, 1011 insertions, 1271 deletions
diff --git a/build/sdk.atree b/build/sdk.atree
index f12a30c0b..b9126d4a2 100644
--- a/build/sdk.atree
+++ b/build/sdk.atree
@@ -112,9 +112,7 @@ framework/swing-worker-1.1.jar tools/lib/swing-worker-1.1.jar
bin/traceview tools/traceview
framework/traceview.jar tools/lib/traceview.jar
-# activitycreator
-bin/activitycreator tools/activitycreator
-framework/activitycreator.jar tools/lib/activitycreator.jar
+# custom ant tasks
framework/anttasks.jar tools/lib/anttasks.jar
# sdkmanager
diff --git a/build/tools/make_windows_sdk.sh b/build/tools/make_windows_sdk.sh
index 4f3cee815..bf52679ac 100755
--- a/build/tools/make_windows_sdk.sh
+++ b/build/tools/make_windows_sdk.sh
@@ -87,7 +87,7 @@ function package() {
# Remove obsolete stuff from tools
TOOLS="$DEST/tools"
LIB="$DEST/tools/lib"
- rm -v "$TOOLS"/{aapt,aidl,adb,emulator,traceview,draw9patch,hierarchyviewer,dx,dexdump,apkbuilder,ddms,dmtracedump,mksdcard,sqlite3,activitycreator,android}
+ rm -v "$TOOLS"/{aapt,aidl,adb,emulator,traceview,draw9patch,hierarchyviewer,dx,dexdump,apkbuilder,ddms,dmtracedump,mksdcard,sqlite3,android}
rm -v --force "$LIB"/*.so "$LIB"/*.jnilib
# Copy all the new stuff in tools
@@ -108,7 +108,6 @@ function package() {
cp -v development/tools/traceview/etc/traceview.bat "$TOOLS"
cp -v development/tools/hierarchyviewer/etc/hierarchyviewer.bat "$TOOLS"
cp -v development/tools/draw9patch/etc/draw9patch.bat "$TOOLS"
- cp -v development/tools/activitycreator/etc/activitycreator.bat "$TOOLS"
cp -v development/tools/sdkmanager/app/etc/android.bat "$TOOLS"
# Fix EOL chars to make window users happy - fix all files at the top level only
diff --git a/host/windows/prebuilt/usb/driver_amd_64/androidusb.sys b/host/windows/prebuilt/usb/driver_amd_64/androidusb.sys
index 70ce24fd1..e610ebea0 100644
--- a/host/windows/prebuilt/usb/driver_amd_64/androidusb.sys
+++ b/host/windows/prebuilt/usb/driver_amd_64/androidusb.sys
Binary files differ
diff --git a/host/windows/prebuilt/usb/driver_amd_64/androidusba64.cat b/host/windows/prebuilt/usb/driver_amd_64/androidusba64.cat
index 9d5db5d1f..cabb288b4 100644
--- a/host/windows/prebuilt/usb/driver_amd_64/androidusba64.cat
+++ b/host/windows/prebuilt/usb/driver_amd_64/androidusba64.cat
Binary files differ
diff --git a/pdk/Pdk.mk b/pdk/Pdk.mk
index 88fedf572..319c5ae3d 100644
--- a/pdk/Pdk.mk
+++ b/pdk/Pdk.mk
@@ -48,7 +48,7 @@ pdk_docs_intermediates := $(call intermediates-dir-for,PACKAGING,pdkdocs)
pdk_templates_dir := development/pdk/docs
pdk_config_dir := development/pdk/doxygen_config
pdk_docsfile_dir := $(pdk_config_dir)/docsfiles
-pdk_hardware_dir := hardware/libhardware/include/hardware
+pdk_legacy_hardware_dir := hardware/libhardware_legacy/include/hardware_legacy
pdk_camera_dir := frameworks/base/include/ui
# Destination directory for docs (templates + doxygenated headers)
@@ -74,9 +74,10 @@ doxygen_version = doxygen
# Header files to doxygenize.
# Add new header files to document here, also adjust the templates to have
# descriptions for the new headers and point to the new doxygen created html.
-pdk_headers := $(pdk_hardware_dir)/AudioHardwareInterface.h \
- $(pdk_hardware_dir)/gps.h \
- $(pdk_hardware_dir)/wifi.h \
+pdk_headers := \
+ $(pdk_legacy_hardware_dir)/AudioHardwareInterface.h \
+ $(pdk_legacy_hardware_dir)/gps.h \
+ $(pdk_legacy_hardware_dir)/wifi.h \
$(pdk_camera_dir)/CameraHardwareInterface.h
# Create a rule to copy the list of PDK headers to be doxyginated.
diff --git a/pdk/README b/pdk/README
index ab923becf..29f46d41a 100644
--- a/pdk/README
+++ b/pdk/README
@@ -66,3 +66,7 @@ The build target 'pdk' brings in the pdk/ndk make files into the build system.
pdk_docs - which builds the pdk documentation
ndk - which builds the native development kit (native compiler, linker, etc.)
pdk_all - which builds the above two targets
+
+for doxygen version changing you can pass in the variable:
+doxygen_version='<path/name_of_doxygen_executable>'
+on the make line.
diff --git a/pdk/doxygen_config/footer.html b/pdk/doxygen_config/footer.html
new file mode 100644
index 000000000..691287b6e
--- /dev/null
+++ b/pdk/doxygen_config/footer.html
@@ -0,0 +1,2 @@
+</body>
+</html> \ No newline at end of file
diff --git a/pdk/doxygen_config/header.html b/pdk/doxygen_config/header.html
new file mode 100644
index 000000000..b26c3030a
--- /dev/null
+++ b/pdk/doxygen_config/header.html
@@ -0,0 +1,15 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
+<title>Doxygen-Generated Content</title>
+<link href="doxygen.css" rel="stylesheet" type="text/css" />
+<style type="text/css">
+<!--
+.navigation {
+ display: none;
+}
+-->
+</style>
+</head>
+<body> \ No newline at end of file
diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java
index c6e572923..36d4233ff 100644
--- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java
+++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java
@@ -16,7 +16,6 @@
package com.example.android.softkeyboard;
-import android.content.Context;
import android.inputmethodservice.InputMethodService;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
@@ -25,7 +24,6 @@ import android.util.Log;
import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.View;
-import android.view.WindowManager;
import android.view.inputmethod.CompletionInfo;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
@@ -44,6 +42,16 @@ public class SoftKeyboard extends InputMethodService
implements KeyboardView.OnKeyboardActionListener {
static final boolean DEBUG = false;
+ /**
+ * This boolean indicates the optional example code for performing
+ * processing of hard keys in addition to regular text generation
+ * from on-screen interaction. It would be used for input methods that
+ * perform language translations (such as converting text entered on
+ * a QWERTY keyboard to Chinese), but may not be used for input methods
+ * that are primarily intended to be used for on-screen text entry.
+ */
+ static final boolean PROCESS_HARD_KEYS = true;
+
private KeyboardView mInputView;
private CandidateView mCandidateView;
private CompletionInfo[] mCompletions;
@@ -62,13 +70,17 @@ public class SoftKeyboard extends InputMethodService
private String mWordSeparators;
+ /**
+ * Helper function to generate the various keyboard layouts used by the
+ * input method. Takes care of regenerating the layouts if the width
+ * of the input method changes.
+ */
private void makeKeyboards() {
- // Configuration change is coming after the keyboard gets recreated. So don't rely on that.
- // If keyboards have already been made, check if we have a screen width change and
- // create the keyboard layouts again at the correct orientation
if (mQwertyKeyboard != null) {
- WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
- int displayWidth = wm.getDefaultDisplay().getWidth();
+ // Configuration changes can happen after the keyboard gets recreated,
+ // so we need to be able to re-build the keyboards if the available
+ // space has changed.
+ int displayWidth = getMaxWidth();
if (displayWidth == mLastDisplayWidth) return;
mLastDisplayWidth = displayWidth;
}
@@ -77,14 +89,25 @@ public class SoftKeyboard extends InputMethodService
mSymbolsShiftedKeyboard = new LatinKeyboard(this, R.xml.symbols_shift);
}
+ /**
+ * Main initialization of the input method component. Be sure to call
+ * to super class.
+ */
@Override public void onCreate() {
super.onCreate();
makeKeyboards();
mWordSeparators = getResources().getString(R.string.word_separators);
}
- @Override
- public View onCreateInputView() {
+ /**
+ * Called by the framework when your view for creating input needs to
+ * be generated. This will be called the first time your input method
+ * is displayed, and every time it needs to be re-created such as due to
+ * a configuration change.
+ */
+ @Override public View onCreateInputView() {
+ // We call makeKeyboards() here to regenerate them if needed due to
+ // a configuration change.
makeKeyboards();
mInputView = (KeyboardView) getLayoutInflater().inflate(
R.layout.input, null);
@@ -93,15 +116,27 @@ public class SoftKeyboard extends InputMethodService
return mInputView;
}
- @Override
- public View onCreateCandidatesView() {
+ /**
+ * Called by the framework when your view for showing candidates needs to
+ * be generated, like {@link #onCreateInputView}.
+ */
+ @Override public View onCreateCandidatesView() {
mCandidateView = new CandidateView(this);
mCandidateView.setService(this);
return mCandidateView;
}
- @Override
- public void onStartInputView(EditorInfo attribute, boolean restarting) {
+ /**
+ * This is the main point where we do our initialization of the input method
+ * to begin operating on an application. At this point we have been
+ * bound to the client, and are now receiving all of the detailed information
+ * about the target of our edits.
+ */
+ @Override public void onStartInputView(EditorInfo attribute, boolean restarting) {
+ super.onStartInputView(attribute, restarting);
+
+ // Reset our state. We want to do this even if restarting, because
+ // the underlying state of the text editor could have changed in any way.
mComposing.setLength(0);
updateCandidates();
@@ -114,57 +149,105 @@ public class SoftKeyboard extends InputMethodService
mCompletionOn = false;
mCompletions = null;
Keyboard keyboard;
+
+ // We are now going to initialize our state based on the type of
+ // text being edited.
switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) {
case EditorInfo.TYPE_CLASS_NUMBER:
case EditorInfo.TYPE_CLASS_DATETIME:
+ // Numbers and dates default to the symbols keyboard, with
+ // no extra features.
keyboard = mSymbolsKeyboard;
break;
+
case EditorInfo.TYPE_CLASS_PHONE:
+ // Phones will also default to the symbols keyboard, though
+ // often you will want to have a dedicated phone keyboard.
keyboard = mSymbolsKeyboard;
break;
- default:
+
+ case EditorInfo.TYPE_CLASS_TEXT:
+ // This is general text editing. We will default to the
+ // normal alphabetic keyboard, and assume that we should
+ // be doing predictive text (showing candidates as the
+ // user types).
keyboard = mQwertyKeyboard;
mPredictionOn = true;
- // Make sure that passwords are not displayed in candidate view
+
+ // We now look for a few special variations of text that will
+ // modify our behavior.
int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION;
if (variation == EditorInfo.TYPE_TEXT_VARIATION_PASSWORD) {
+ // Do not display predictions / what the user is typing
+ // when they are entering a password.
mPredictionOn = false;
}
+
if (variation == EditorInfo.TYPE_TEXT_VARIATION_EMAIL_ADDRESS
|| variation == EditorInfo.TYPE_TEXT_VARIATION_URI) {
+ // Our predictions are not useful for e-mail addresses
+ // or URIs.
mPredictionOn = false;
}
+
if ((attribute.inputType&EditorInfo.TYPE_TEXT_FLAG_AUTO_COMPLETE) != 0) {
+ // If this is an auto-complete text view, then our predictions
+ // will not be shown and instead we will allow the editor
+ // to supply their own. We only show the editor's
+ // candidates when in fullscreen mode, otherwise relying
+ // own it displaying its own UI.
mPredictionOn = false;
mCompletionOn = isFullscreenMode();
}
+
+ // We also want to look at the current state of the editor
+ // to decide whether our alphabetic keyboard should start out
+ // shifted.
updateShiftKeyState(attribute);
break;
+
+ default:
+ // For all unknown input types, default to the alphabetic
+ // keyboard with no special features.
+ keyboard = mQwertyKeyboard;
}
+ // Apply the selected keyboard to the input view.
if (mInputView != null) {
mInputView.setKeyboard(keyboard);
mInputView.closing();
}
-
- mComposing.setLength(0);
- setSuggestions(null, false, false);
}
- @Override
- public void onFinishInput() {
+ /**
+ * This is called when the user is done editing a field. We can use
+ * this to reset our state.
+ */
+ @Override public void onFinishInput() {
super.onFinishInput();
+
+ // Clear current composing text and candidates.
mComposing.setLength(0);
updateCandidates();
+
+ // We only hide the candidates window when finishing input on
+ // a particular editor, to avoid popping the underlying application
+ // up and down if the user is entering text into the bottom of
+ // its window.
+ setCandidatesViewShown(false);
+
if (mInputView != null) {
mInputView.closing();
}
}
- @Override
- public void onUpdateSelection(int oldSelStart, int oldSelEnd,
+ /**
+ * Deal with the editor reporting movement of its cursor.
+ */
+ @Override public void onUpdateSelection(int oldSelStart, int oldSelEnd,
int newSelStart, int newSelEnd,
int candidatesStart, int candidatesEnd) {
+
// If the current selection in the text view changes, we should
// clear whatever candidate text we have.
if (mComposing.length() > 0 && (newSelStart != candidatesEnd
@@ -178,8 +261,13 @@ public class SoftKeyboard extends InputMethodService
}
}
- @Override
- public void onDisplayCompletions(CompletionInfo[] completions) {
+ /**
+ * This tells us about completions that the editor has determined based
+ * on the current text in it. We want to use this in fullscreen mode
+ * to show the completions ourself, since the editor can not be seen
+ * in that situation.
+ */
+ @Override public void onDisplayCompletions(CompletionInfo[] completions) {
if (mCompletionOn) {
mCompletions = completions;
if (completions == null) {
@@ -196,6 +284,11 @@ public class SoftKeyboard extends InputMethodService
}
}
+ /**
+ * This translates incoming hard key events in to edit operations on an
+ * InputConnection. It is only needed when using the
+ * PROCESS_HARD_KEYS option.
+ */
private boolean translateKeyDown(int keyCode, KeyEvent event) {
mMetaState = MetaKeyKeyListener.handleKeyDown(mMetaState,
keyCode, event);
@@ -228,55 +321,71 @@ public class SoftKeyboard extends InputMethodService
return true;
}
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
+ /**
+ * Use this to monitor key events being delivered to the application.
+ * We get first crack at them, and can either resume them or let them
+ * continue to the app.
+ */
+ @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_BACK:
+ // The InputMethodService already takes care of the back
+ // key for us, to dismiss the input method if it is shown.
+ // However, our keyboard could be showing a pop-up window
+ // that back should dismiss, so we first allow it to do that.
if (event.getRepeatCount() == 0 && mInputView != null) {
if (mInputView.handleBack()) {
return true;
}
}
break;
+
case KeyEvent.KEYCODE_DEL:
+ // Special handling of the delete key: if we currently are
+ // composing text for the user, we want to modify that instead
+ // of let the application to the delete itself.
if (mComposing.length() > 0) {
onKey(Keyboard.KEYCODE_DELETE, null);
return true;
}
break;
+
default:
- if (mPredictionOn && translateKeyDown(keyCode, event)) {
- return true;
+ // For all other keys, if we want to do transformations on
+ // text being entered with a hard keyboard, we need to process
+ // it and do the appropriate action.
+ if (PROCESS_HARD_KEYS) {
+ if (mPredictionOn && translateKeyDown(keyCode, event)) {
+ return true;
+ }
}
}
+
return super.onKeyDown(keyCode, event);
}
- @Override
- public boolean onKeyUp(int keyCode, KeyEvent event) {
- switch (keyCode) {
- case KeyEvent.KEYCODE_DPAD_DOWN:
- case KeyEvent.KEYCODE_DPAD_UP:
- case KeyEvent.KEYCODE_DPAD_LEFT:
- case KeyEvent.KEYCODE_DPAD_RIGHT:
- // Enable shift key and DPAD to do selections
- if (mInputView != null && mInputView.isShown() && mInputView.isShifted()) {
- event = new KeyEvent(event.getDownTime(), event.getEventTime(),
- event.getAction(), event.getKeyCode(), event.getRepeatCount(),
- KeyEvent.META_SHIFT_LEFT_ON | KeyEvent.META_SHIFT_ON);
- getCurrentInputConnection().sendKeyEvent(event);
- return true;
- }
- break;
- default:
- if (mPredictionOn) {
- mMetaState = MetaKeyKeyListener.handleKeyUp(mMetaState,
- keyCode, event);
- }
+ /**
+ * Use this to monitor key events being delivered to the application.
+ * We get first crack at them, and can either resume them or let them
+ * continue to the app.
+ */
+ @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
+ // If we want to do transformations on text being entered with a hard
+ // keyboard, we need to process the up events to update the meta key
+ // state we are tracking.
+ if (PROCESS_HARD_KEYS) {
+ if (mPredictionOn) {
+ mMetaState = MetaKeyKeyListener.handleKeyUp(mMetaState,
+ keyCode, event);
+ }
}
+
return super.onKeyUp(keyCode, event);
}
+ /**
+ * Helper function to commit any text being composed in to the editor.
+ */
private void commitTyped(InputConnection inputConnection) {
if (mComposing.length() > 0) {
inputConnection.commitText(mComposing, mComposing.length());
@@ -285,7 +394,11 @@ public class SoftKeyboard extends InputMethodService
}
}
- public void updateShiftKeyState(EditorInfo attr) {
+ /**
+ * Helper to update the shift state of our keyboard based on the initial
+ * editor state.
+ */
+ private void updateShiftKeyState(EditorInfo attr) {
if (attr != null
&& mInputView != null && mQwertyKeyboard == mInputView.getKeyboard()) {
int caps = getCurrentInputConnection().getCursorCapsMode(attr.inputType);
@@ -293,6 +406,9 @@ public class SoftKeyboard extends InputMethodService
}
}
+ /**
+ * Helper to determine if a given character code is alphabetic.
+ */
private boolean isAlphabet(int code) {
if (Character.isLetter(code)) {
return true;
@@ -301,6 +417,9 @@ public class SoftKeyboard extends InputMethodService
}
}
+ /**
+ * Helper to send a key down / key up pair to the current editor.
+ */
private void keyDownUp(int keyEventCode) {
getCurrentInputConnection().sendKeyEvent(
new KeyEvent(KeyEvent.ACTION_DOWN, keyEventCode));
@@ -308,6 +427,9 @@ public class SoftKeyboard extends InputMethodService
new KeyEvent(KeyEvent.ACTION_UP, keyEventCode));
}
+ /**
+ * Helper to send a character to the editor as raw key events.
+ */
private void sendKey(int keyCode) {
switch (keyCode) {
case '\n':
@@ -378,13 +500,13 @@ public class SoftKeyboard extends InputMethodService
public void setSuggestions(List<String> suggestions, boolean completions,
boolean typedWordValid) {
- mCandidateView.setSuggestions(suggestions, completions, typedWordValid);
- if (suggestions != null && suggestions.size() > 0) {
- setCandidatesViewShown(true);
- } else if (isFullscreenMode()) {
- setCandidatesViewShown(true);
- } else {
- setCandidatesViewShown(false);
+ if (mCandidateView != null) {
+ mCandidateView.setSuggestions(suggestions, completions, typedWordValid);
+ if (suggestions != null && suggestions.size() > 0) {
+ setCandidatesViewShown(true);
+ } else if (isFullscreenMode()) {
+ setCandidatesViewShown(true);
+ }
}
}
@@ -399,7 +521,6 @@ public class SoftKeyboard extends InputMethodService
getCurrentInputConnection().commitText("", 0);
updateCandidates();
} else {
- //getCurrentInputConnection().deleteSurroundingText(1, 0);
keyDownUp(KeyEvent.KEYCODE_DEL);
}
updateShiftKeyState(getCurrentInputEditorInfo());
@@ -439,7 +560,7 @@ public class SoftKeyboard extends InputMethodService
updateCandidates();
} else {
getCurrentInputConnection().commitText(
- String.valueOf((char) primaryCode), 0);
+ String.valueOf((char) primaryCode), 1);
}
}
@@ -459,7 +580,7 @@ public class SoftKeyboard extends InputMethodService
}
}
- protected String getWordSeparators() {
+ private String getWordSeparators() {
return mWordSeparators;
}
@@ -504,10 +625,11 @@ public class SoftKeyboard extends InputMethodService
}
public void swipeUp() {
- // ?
}
- public void onPress(int primaryCode) { }
+ public void onPress(int primaryCode) {
+ }
- public void onRelease(int primaryCode) { }
+ public void onRelease(int primaryCode) {
+ }
}
diff --git a/tools/activitycreator/.classpath b/tools/activitycreator/.classpath
deleted file mode 100644
index fb5011632..000000000
--- a/tools/activitycreator/.classpath
+++ /dev/null
@@ -1,6 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<classpath>
- <classpathentry kind="src" path="src"/>
- <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
- <classpathentry kind="output" path="bin"/>
-</classpath>
diff --git a/tools/activitycreator/.project b/tools/activitycreator/.project
deleted file mode 100644
index b81a8871d..000000000
--- a/tools/activitycreator/.project
+++ /dev/null
@@ -1,17 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<projectDescription>
- <name>ActivityCreator</name>
- <comment></comment>
- <projects>
- </projects>
- <buildSpec>
- <buildCommand>
- <name>org.eclipse.jdt.core.javabuilder</name>
- <arguments>
- </arguments>
- </buildCommand>
- </buildSpec>
- <natures>
- <nature>org.eclipse.jdt.core.javanature</nature>
- </natures>
-</projectDescription>
diff --git a/tools/activitycreator/Android.mk b/tools/activitycreator/Android.mk
deleted file mode 100644
index 924c9b6c4..000000000
--- a/tools/activitycreator/Android.mk
+++ /dev/null
@@ -1,17 +0,0 @@
-# Copyright (C) 2007 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.
-
-ACTIVITY_CREATOR_LOCAL_DIR := $(call my-dir)
-include $(ACTIVITY_CREATOR_LOCAL_DIR)/etc/Android.mk
-include $(ACTIVITY_CREATOR_LOCAL_DIR)/src/Android.mk
diff --git a/tools/activitycreator/MODULE_LICENSE_APACHE2 b/tools/activitycreator/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29bb..000000000
--- a/tools/activitycreator/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/tools/activitycreator/etc/Android.mk b/tools/activitycreator/etc/Android.mk
deleted file mode 100644
index 9128d8838..000000000
--- a/tools/activitycreator/etc/Android.mk
+++ /dev/null
@@ -1,20 +0,0 @@
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_PREBUILT_EXECUTABLES := activitycreator
-include $(BUILD_HOST_PREBUILT)
-
diff --git a/tools/activitycreator/etc/activitycreator b/tools/activitycreator/etc/activitycreator
deleted file mode 100755
index f387d171c..000000000
--- a/tools/activitycreator/etc/activitycreator
+++ /dev/null
@@ -1,20 +0,0 @@
-#!/bin/sh
-
-# Copyright (C) 2007 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.
-
-TOOLS_DIR=`dirname $0`
-AC_JARFILE=$TOOLS_DIR/lib/activitycreator.jar
-
-java -Dcom.android.activitycreator.toolsdir=$TOOLS_DIR -cp $AC_JARFILE com.android.activitycreator.ActivityCreator "$@"
diff --git a/tools/activitycreator/etc/activitycreator.bat b/tools/activitycreator/etc/activitycreator.bat
deleted file mode 100755
index 1cf1847fc..000000000
--- a/tools/activitycreator/etc/activitycreator.bat
+++ /dev/null
@@ -1,22 +0,0 @@
-@echo off
-rem Copyright (C) 2007 The Android Open Source Project
-rem
-rem Licensed under the Apache License, Version 2.0 (the "License");
-rem you may not use this file except in compliance with the License.
-rem You may obtain a copy of the License at
-rem
-rem http://www.apache.org/licenses/LICENSE-2.0
-rem
-rem Unless required by applicable law or agreed to in writing, software
-rem distributed under the License is distributed on an "AS IS" BASIS,
-rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-rem See the License for the specific language governing permissions and
-rem limitations under the License.
-
-rem don't modify the caller's environmeny
-setlocal
-
-set toolsdir=%~dp0\
-set acjarfile=%toolsdir%/lib/activitycreator.jar
-
-call java -Dcom.android.activitycreator.toolsdir="%toolsdir%" -cp "%acjarfile%" com.android.activitycreator.ActivityCreator %*
diff --git a/tools/activitycreator/src/Android.mk b/tools/activitycreator/src/Android.mk
deleted file mode 100644
index eea427a0d..000000000
--- a/tools/activitycreator/src/Android.mk
+++ /dev/null
@@ -1,23 +0,0 @@
-# Copyright (C) 2007 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_MODULE := activitycreator
-
-include $(BUILD_HOST_JAVA_LIBRARY)
-
diff --git a/tools/activitycreator/src/com/android/activitycreator/ActivityCreator.java b/tools/activitycreator/src/com/android/activitycreator/ActivityCreator.java
deleted file mode 100644
index f7db7df6d..000000000
--- a/tools/activitycreator/src/com/android/activitycreator/ActivityCreator.java
+++ /dev/null
@@ -1,881 +0,0 @@
-/*
- * Copyright (C) 2007 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.activitycreator;
-
-import org.w3c.dom.NodeList;
-import org.xml.sax.InputSource;
-
-import java.io.BufferedReader;
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileReader;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
-import javax.xml.xpath.XPath;
-import javax.xml.xpath.XPathConstants;
-import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
-
-/**
- * Creates the basic files needed to get an Android project up and running. Also
- * allows creation of IntelliJ project files.
- *
- * @hide
- */
-public class ActivityCreator {
- // FIXME: target platform must be provided by the user
- private final String mTargetPlatform = "android-1.1";
-
- /** Whether we are in silent mode (i.e.: don't print any non-error messages) */
- private boolean mSilent;
-
- /** Path to tools */
- private String mToolsDir;
-
- /** Path to SDK */
- private String mSdkDir;
-
- /** Path to target platform's template folder */
- private String mTemplateDir;
-
- /** Path to tools/lib for the build templates */
- private String mLibDir;
-
- /** Path to output */
- private String mOutDir;
-
- /** IDE to generate for */
- private String mIde;
-
- /** Data used for the "alias" mode */
- private String mAliasData;
-
- /** Application label used in the "alias" mode */
- private String mApplicationLabel;
-
- /** Package of Activity */
- private String mPackageFull;
-
- /**
- * Constructs object.
- * @param args arguments passed to the program
- */
- public ActivityCreator(String[] args) {
- mSilent = false;
-
- mIde = "";
-
- initPathVars();
- parseArgs(args);
-
- if (isAliasProject()) {
- setupAliasProject();
- } else {
- setupProject();
- }
- }
-
- /**
- * Initializes the path variables based on location of this class.
- */
- private void initPathVars() {
- /* We get passed a property for the tools dir */
- String toolsDirProp = System.getProperty("com.android.activitycreator.toolsdir");
- if (toolsDirProp == null) {
- // for debugging, it's easier to override using the process environment
- toolsDirProp = System.getenv("com.android.activitycreator.toolsdir");
- }
- if (toolsDirProp == null) {
- printHelpAndExit("ERROR: The tools directory property is not set, please make sure you are executing activitycreator or activitycreator.bat");
- }
-
- /* Absolute path */
- File toolsDir = new File(toolsDirProp);
- try {
- mToolsDir = toolsDir.getCanonicalPath();
- } catch (IOException e) {
- printHelpAndExit("ERROR: Could not determine the tools directory.");
- }
- toolsDir = new File(mToolsDir);
-
- mSdkDir = toolsDir.getParent();
- mLibDir = mToolsDir + File.separator + "lib";
- mTemplateDir = mSdkDir + File.separator + "platforms" + File.separator +
- mTargetPlatform + File.separator + "templates";
- try {
- mOutDir = new File("").getCanonicalPath();
- } catch (IOException e) {
- printHelpAndExit("ERROR: Could not determine the current directory.");
- }
-
- if (!toolsDir.exists()) {
- printHelpAndExit("ERROR: Tools directory does not exist.");
- }
-
- if (!(new File(mSdkDir).exists())) {
- printHelpAndExit("ERROR: SDK directory does not exist.");
- }
-
- if (!(new File(mTemplateDir).exists())) {
- printHelpAndExit("ERROR: Target platform templates directory does not exist.");
- }
-
- if (!(new File(mLibDir).exists())) {
- printHelpAndExit("ERROR: Library directory does not exist.");
- }
- }
-
- /**
- * Parses command-line arguments, or prints help/usage and exits if error.
- * @param args arguments passed to the program
- */
- private void parseArgs(String[] args) {
- final int numArgs = args.length;
-
- try {
- int argPos = 0;
- for (; argPos < numArgs; argPos++) {
- final String arg = args[argPos];
- if (arg.equals("-o") || arg.equals("-out") || arg.equals("--out")) {
- argPos++;
- mOutDir = args[argPos];
- } else if (arg.equals("-d") || arg.equals("-data") || arg.equals("--data")) {
- argPos++;
- mAliasData = args[argPos];
- } else if (arg.equals("-l") || arg.equals("-label") || arg.equals("--label")) {
- argPos++;
- mApplicationLabel = args[argPos];
- } else if (arg.equals("-i") || arg.equals("-ide") || arg.equals("--ide")) {
- argPos++;
- mIde = args[argPos].toLowerCase();
- } else if (arg.equals("-h") || arg.equals("-help") || arg.equals("--help")) {
- printHelpAndExit(null);
- } else if (arg.equals("-s") || arg.equals("-silent") || arg.equals("--silent")) {
- mSilent = true;
- } else {
- if (mPackageFull == null) {
- mPackageFull = extractPackageFromManifest(args[argPos]);
- if (mPackageFull == null) {
- mPackageFull = args[argPos];
- }
- } else {
- /* Package has already been set, so this is an extra argument */
- printHelpAndExit("ERROR: Too many arguments: %1$s", args[argPos]);
- }
- }
- }
- } catch (ArrayIndexOutOfBoundsException e) {
- /* Any OOB triggers help */
- printHelpAndExit("ERROR: Not enough arguments.");
- }
-
- if (isStringEmpty(mPackageFull)) {
- printHelpAndExit("ERROR: Please enter a package.");
- }
-
- if (isStringEmpty(mOutDir)) {
- printHelpAndExit("ERROR: Please enter an output directory.");
- }
-
- // we need both application label and url for the "alias" mode
- if (isStringEmpty(mAliasData) ^ isStringEmpty(mApplicationLabel)) {
- printHelpAndExit("ERROR: Alias projects require both --data and --label.");
- }
-
- if (mIde.equals("eclipse")) {
- printHelpAndExit("ERROR: For Eclipse support, please install the Eclipse ADT plugin and use its New Project Wizard.");
- }
- }
-
- /**
- * Prints the help/usage and exits.
- * @param errorFormat Optional error message to print prior to usage using String.format
- * @param args Arguments for String.format
- */
- private void printHelpAndExit(String errorFormat, Object... args) {
- if (errorFormat != null) {
- System.err.println(String.format(errorFormat, args));
- }
-
- /*
- * usage should fit in 80 columns
- * 12345678901234567890123456789012345678901234567890123456789012345678901234567890
- */
- final String usage = "\n" +
- "Activity Creator Script.\n" +
- "\n" +
- "Usage:\n" +
- " activitycreator --out outdir [--ide intellij] your.package.name.ActivityName\n" +
- " activitycreator --out outdir [--ide intellij] path/to/AndroidManifest.xml\n" +
- " activitycreator --out outdir --data data --label app_label your.package.name\n" +
- "\n" +
- "With both the --data and --label options, ActivityCreator creates the structure\n" +
- "of an 'alias' Android application.\n" +
- " An Alias project is an application with no code that simply launches an\n" +
- " android.intent.action.VIEW intent with the provided data.\n" +
- " The following will be created (existing files will not be modified):\n" +
- " - AndroidManifest.xml: The application manifest file.\n" +
- " - build.xml: An Ant script to build/package the application.\n" +
- " - res/values/strings.xml: an XML file defining the application label\n" +
- " string resource.\n" +
- " - res/xml/alias.xml: an XML file defining the VIEW intent and its data.\n " +
- "\n" +
- "Without --data and --label, ActivityCreator creates the structure of a minimal\n" +
- "Android application.\n" +
- " The following will be created (existing files will not be modified):\n" +
- " - AndroidManifest.xml: The application manifest file.\n" +
- " - build.xml: An Ant script to build/package the application.\n" +
- " - res : The resource directory.\n" +
- " - src : The source directory.\n" +
- " - src/your/package/name/ActivityName.java the Activity java class.\n" +
- " packageName is a fully qualified java Package in the format\n" +
- " <package1>.<package2>... (with at least two components).\n" +
- " - bin : The output folder for the build script.\n" +
- "\n" +
- "Options:\n" +
- " -o <folder>, --out <folder>\n" +
- " Specifies where to create the files/folders.\n" +
- " -i intellij, --ide intellij\n" +
- " Creates project files for IntelliJ (non alias application only)\n" +
- " -d <data-string>, --data <data-string>\n" +
- " The data passed to the VIEW intent. For instance, this can be a url,\n" +
- " such as http://www.android.com\n" +
- " -l <app-label>, --label <app-label>\n" +
- " The name the alias application will have in the HOME screen.\n" +
- " -h, --help\n" +
- " Display this help.\n" +
- " -s, --silent\n" +
- " Silent mode.\n" +
- "\n" +
- "For Eclipse support, please use the ADT plugin.\n";
-
- println(usage);
- System.exit(1);
- }
-
- /**
- * Installs a destination file that is based on a code template file at the source.
- * For each match of each key in keywords will be replaced with its
- * corresponding value in the destination file.
- *
- * Invokes {@link #installProjectTemplate(String, String, Map, boolean, String)} with
- * the main project output directory (#mOutDir) as the last argument.
- *
- * @param source the name of to the source template file
- * @param dest the path to the destination file
- * @param keywords in the destination file, the keys will be replaced by their values
- * @param force True to force writing the file even if it already exists
- *
- * @see #installProjectTemplate(String, String, Map, boolean, String)
- */
- private void installProjectTemplate(String source, String dest,
- Map<String, String> keywords, boolean force) {
- installProjectTemplate(source, dest, keywords, force, mOutDir);
- }
-
- /**
- * Installs a destination file that is based on a code template file at the source.
- * For each match of each key in keywords will be replaced with its
- * corresponding value in the destination file.
- *
- * @param source the name of to the source template file
- * @param dest the path to the destination file
- * @param keywords in the destination file, the keys will be replaced by their values
- * @param force True to force writing the file even if it already exists
- * @param outDir the output directory to copy the template file to
- */
- private void installProjectTemplate(String source, String dest,
- Map<String, String> keywords, boolean force, String outDir) {
- final String sourcePath = mTemplateDir + File.separator + source;
- final String destPath = outDir + File.separator + dest;
-
- installFullPathTemplate(sourcePath, destPath, keywords, force);
- }
-
- /**
- * Installs a destination file that is based on a build template file at the source.
- * For each match of each key in keywords will be replaced with its
- * corresponding value in the destination file.
- *
- * Invokes {@link #installBuildTemplate(String, String, Map, boolean, String)} with
- * the main project output directory (#mOutDir) as the last argument.
- *
- * @param source the name of to the source template file
- * @param dest the path to the destination file
- * @param keywords in the destination file, the keys will be replaced by their values
- * @param force True to force writing the file even if it already exists
- *
- * @see #installBuildTemplate(String, String, Map, boolean, String)
- */
- private void installBuildTemplate(String source, String dest,
- Map<String, String> keywords, boolean force) {
- installBuildTemplate(source, dest, keywords, force, mOutDir);
- }
-
- /**
- * Installs a destination file that is based on a build template file at the source.
- * For each match of each key in keywords will be replaced with its
- * corresponding value in the destination file.
- *
- * @param source the name of to the source template file
- * @param dest the path to the destination file
- * @param keywords in the destination file, the keys will be replaced by their values
- * @param force True to force writing the file even if it already exists
- * @param outDir the output directory to copy the template file to
- */
- private void installBuildTemplate(String source, String dest,
- Map<String, String> keywords, boolean force, String outDir) {
- final String sourcePath = mLibDir + File.separator + source;
- final String destPath = outDir + File.separator + dest;
-
- installFullPathTemplate(sourcePath, destPath, keywords, force);
- }
-
- /**
- * Installs a destination file that is based on the template file at source.
- * For each match of each key in keywords will be replaced with its
- * corresponding value in the destination file.
- *
- * @param sourcePath the full path to the source template file
- * @param destPath the full path to the destination file
- * @param keywords in the destination file, the keys will be replaced by their values
- * @param force True to force writing the file even if it already exists
- */
- private void installFullPathTemplate(String sourcePath, String destPath,
- Map<String, String> keywords, boolean force) {
- final File destPathFile = new File(destPath);
- if (!force && destPathFile.exists()) {
- println("WARNING! The file %1$s already exists and will not be overwritten!\n",
- destPathFile.getName());
- return;
- }
-
- try {
- BufferedWriter out = new BufferedWriter(new FileWriter(destPathFile));
- BufferedReader in = new BufferedReader(new FileReader(sourcePath));
- String line;
-
- while ((line = in.readLine()) != null) {
- for (String key : keywords.keySet()) {
- line = line.replace(key, keywords.get(key));
- }
-
- out.write(line);
- out.newLine();
- }
-
- out.close();
- in.close();
- } catch (Exception e) {
- printHelpAndExit("ERROR: Could not access %1$s: %2$s", destPath, e.getMessage());
- }
-
- println("Added file %1$s", destPath);
- }
-
- /**
- * Set up the Android-related files
- */
- private void setupProject() {
- String packageName = null;
- String activityName = null;
- String activityTestName = null;
- try {
- /* Grab package and Activity names */
- int lastPeriod = mPackageFull.lastIndexOf('.');
- packageName = mPackageFull.substring(0, lastPeriod);
- if (lastPeriod < mPackageFull.length() - 1) {
- activityName = mPackageFull.substring(lastPeriod+1);
- activityTestName = activityName + "Test";
- }
-
- if (packageName.indexOf('.') == -1) {
- printHelpAndExit("ERROR: Package name must be composed of at least two java identifiers.");
- }
- } catch (RuntimeException e) {
- printHelpAndExit("ERROR: Invalid package or activity name.");
- }
-
- println("Package: %1$s", packageName);
- println("Output directory: %1$s", mOutDir);
- String testsOutDir = mOutDir + File.separator + "tests";
- println("Tests directory: %1$s", testsOutDir);
-
- if (activityName != null) {
- println("Activity name: %1$s", activityName);
- }
- if (activityTestName != null) {
- println("ActivityTest name: %1$s", activityTestName);
- }
-
- final HashMap<String, String> keywords = createBaseKeywordMap();
-
- addTargetKeywords(keywords);
-
- keywords.put("PACKAGE", packageName);
- if (activityName != null) {
- keywords.put("ACTIVITY_NAME", activityName);
- }
-
- final String packagePath =
- stripString(packageName.replace(".", File.separator),
- File.separatorChar);
- keywords.put("PACKAGE_PATH", packagePath);
-
- /* Other files that are always created */
-
- /* Make Activity java file */
- final String srcDir = "src" + File.separator + packagePath;
- createDirs(srcDir);
- if (isDirEmpty(srcDir, "Java") && activityName != null) {
- installProjectTemplate("java_file.template", srcDir + File.separator
- + activityName + ".java", keywords, false /*force*/);
- }
- createDirs("bin");
- createDirs("libs");
- createDirs("res");
-
- /* Make ActivityTest java file */
- createDirs(srcDir, testsOutDir);
- if (isDirEmpty(srcDir, "Java", testsOutDir) && activityTestName != null) {
- installProjectTemplate("java_tests_file.template", srcDir + File.separator
- + activityTestName + ".java", keywords, false, testsOutDir);
- }
- createDirs("bin", testsOutDir);
- createDirs("libs", testsOutDir);
- createDirs("res", testsOutDir);
-
- /* Make res files */
- final String valuesDir = "res" + File.separator + "values";
- createDirs(valuesDir);
- if (isDirEmpty(valuesDir, "Resource Values")) {
- installProjectTemplate("strings.template", valuesDir + File.separator
- + "strings.xml", keywords, false /*force*/);
- }
-
- final String layoutDir = "res" + File.separator + "layout";
- createDirs(layoutDir);
- if (isDirEmpty(layoutDir, "Resource Layout")) {
- installProjectTemplate("layout.template", layoutDir + File.separator
- + "main.xml", keywords, false /*force*/);
- }
-
- /* Make AndroidManifest.xml and build.xml files */
- installProjectTemplate("AndroidManifest.template", "AndroidManifest.xml",
- keywords, false /*force*/);
-
- installBuildTemplate("build.template", "build.xml", keywords, false /*force*/);
- installBuildTemplate("default.properties.template", "default.properties", keywords,
- true /*force*/);
-
- /* Make AndroidManifest.xml and build.xml files for tests */
- installProjectTemplate("AndroidManifest.tests.template", "AndroidManifest.xml",
- keywords, false /*force*/, testsOutDir);
-
- installBuildTemplate("build.template", "build.xml", keywords, false /*force*/, testsOutDir);
- installBuildTemplate("default.properties.template", "default.properties", keywords,
- true /*force*/, testsOutDir);
-
- if (mIde.equals("intellij")) {
- /* IntelliJ files */
- if (activityName != null) {
- installProjectTemplate("iml.template", activityName + ".iml", keywords,
- false /*force*/);
- installProjectTemplate("ipr.template", activityName + ".ipr", keywords,
- false /*force*/);
- installProjectTemplate("iws.template", activityName + ".iws", keywords,
- false /*force*/);
- }
- } else if (!isStringEmpty(mIde)) {
- println("WARNING: Unknown IDE option \"%1$s\". No IDE files generated.",
- mIde);
- }
- }
-
-
- /**
- * Sets up the files for an alias project.
- */
- private void setupAliasProject() {
- println("Package: %1$s", mPackageFull);
- println("Output directory: %1$s", mOutDir);
- println("URL: %1$s", mAliasData);
- println("Application label: %1$s", mApplicationLabel);
-
- if (mIde != null) {
- println("Alias project: ignoring --ide option.");
- }
-
- final HashMap<String, String> keywords = createBaseKeywordMap();
- keywords.put("PACKAGE", mPackageFull);
- keywords.put("ALIASDATA", mAliasData);
-
- // since strings.xml uses ACTIVITY_NAME for the application label we use it as well.
- // since we'll use a different AndroidManifest template this is not a problem.
- keywords.put("ACTIVITY_NAME", mApplicationLabel);
-
- /* Make res files */
- final String xmlDir = "res" + File.separator + "xml";
- createDirs(xmlDir);
- if (isDirEmpty(xmlDir, "Resource Xml")) {
- installProjectTemplate("alias.template", xmlDir + File.separator + "alias.xml",
- keywords, false /*force*/);
- }
-
- final String valuesDir = "res" + File.separator + "values";
- createDirs(valuesDir);
- if (isDirEmpty(valuesDir, "Resource Values")) {
- installProjectTemplate("strings.template", valuesDir + File.separator
- + "strings.xml", keywords, false /*force*/);
- }
-
-
- /* Make AndroidManifest.xml and build.xml files */
- installProjectTemplate("AndroidManifest.alias.template", "AndroidManifest.xml", keywords,
- false /*force*/);
-
- installBuildTemplate("build.alias.template", "build.xml", keywords, false /*force*/);
- installBuildTemplate("default.properties.template", "default.properties", keywords, true /*force*/);
- }
-
-
- private HashMap<String, String> createBaseKeywordMap() {
- final HashMap<String, String> keywords = new HashMap<String, String>();
-
- // When the tools & sdk folder on Windows get written to a properties file,
- // we need to transform \ in /, otherwise it gets interpreted as an escape character.
- // This is OK since ant can understand / as a separator even under Windows.
- // References:
- // - http://ant.apache.org/manual/CoreTasks/property.html
- // - http://java.sun.com/j2se/1.4.2/docs/api/java/util/Properties.html#load(java.io.InputStream)
- keywords.put("ANDROID_SDK_TOOLS", mToolsDir.replace('\\', '/'));
- keywords.put("ANDROID_SDK_FOLDER", mSdkDir.replace('\\', '/'));
-
- return keywords;
- }
-
- private void addTargetKeywords(HashMap<String, String> keywords) {
- // FIXME: get this from the target selection
- keywords.put("TARGET_MODE", "platform");
- keywords.put("TARGET_API", "1"); // this is potentially wrong but since it's only used
- // when editing a project config, this is ok for now.
- keywords.put("TARGET_NAME", "android"); // this is only used in add-on mode.
- keywords.put("TARGET_FOLDER", mTargetPlatform);
- keywords.put("TARGET_MODE", "platform");
- }
-
-
- /**
- * Called first.
- * @param args arguments passed to the program
- */
- public static void main(String[] args) {
- new ActivityCreator(args);
- }
-
- /**
- * Prints a message unless silence is enabled.
- * @param format Format for String.format
- * @param args Arguments for String.format
- */
- public void println(String format, Object... args) {
- if (!mSilent) {
- System.out.println(String.format(format, args));
- }
- }
-
- /**
- * Checks whether a string is "empty" (null or trimmed length == 0)
- * @param s the string to check
- * @return true if empty
- */
- public static boolean isStringEmpty(String s) {
- return (s == null) || (s.trim().length() == 0);
- }
-
- /**
- * Creates the path in the output directory along with any parent paths
- * that don't exist.
- *
- * Invokes ActivityCreator#createDirs(String, String) with
- * the main project output directory (#mOutDir) as the last argument.
- *
- * @param path the directory out/path that is created.
- *
- * @see com.android.activitycreator.ActivityCreator#createDirs(String, String)
- */
- public void createDirs(String path) {
- createDirs(path, mOutDir);
- }
-
- /**
- * Creates the path in the output directory along with any parent paths
- * that don't exist.
- *
- * @param path the directory out/path that is created.
- * @param dir the directory in which the path to be created
- */
- public void createDirs(String path, String dir) {
- final File pathFile = new File(dir + File.separator + path);
- boolean existedBefore = true;
-
- if (!pathFile.exists()) {
- if (!pathFile.mkdirs()) {
- printHelpAndExit("ERROR: Could not create directory: %1$s", pathFile);
- }
- existedBefore = false;
- }
-
- if (pathFile.isDirectory()) {
- if (!pathFile.canWrite()) {
- printHelpAndExit("ERROR: Path is not writable: %1$s", pathFile);
- }
- } else {
- printHelpAndExit("ERROR: Path is not a directory: %1$s", pathFile);
- }
-
- if (!existedBefore) {
- try {
- println("Created directory %1$s", pathFile.getCanonicalPath());
- } catch (IOException e) {
- printHelpAndExit("ERROR: Could not determine canonical path of created directory");
- }
- }
- }
-
- /**
- * Checks whether the path in the output directory is empty
- *
- * Invokes ActivityCreator#isDirEmpty(String, String, String) with
- * the main project output directory (#mOutDir) as the last argument.
- *
- * @param path the out/path directory that is checked
- * @param message the logical name for what this path points to (used in
- * warning message)
- * @return whether the directory is empty
- * @see com.android.activitycreator.ActivityCreator#isDirEmpty(String, String, String)
- */
- public boolean isDirEmpty(String path, String message) {
- return isDirEmpty(path, message, mOutDir);
- }
-
- /**
- * Checks whether the path in the output directory is empty
- *
- * @param path the out/path directory that is checked
- * @param message the logical name for what this path points to (used in
- * warning message)
- * @param outDir the output director to check
- * @return whether the directory is empty
- */
- public boolean isDirEmpty(String path, String message, String outDir) {
- File pathFile = new File(outDir + File.separator + path);
-
- String[] pathListing = pathFile.list();
- if ((pathListing != null) && (pathListing.length > 0)) {
- println("WARNING: There are already some %1$s files present. None will be created!",
- message);
- return false;
- }
-
- return true;
- }
-
- /**
- * Strips the string of beginning and trailing characters (multiple
- * characters will be stripped, example stripString("..test...", '.')
- * results in "test";
- *
- * @param s the string to strip
- * @param strip the character to strip from beginning and end
- * @return the stripped string or the empty string if everything is stripped.
- */
- public static String stripString(String s, char strip) {
- final int sLen = s.length();
- int newStart = 0, newEnd = sLen - 1;
-
- while (newStart < sLen && s.charAt(newStart) == strip) {
- newStart++;
- }
- while (newEnd >= 0 && s.charAt(newEnd) == strip) {
- newEnd--;
- }
-
- /*
- * newEnd contains a char we want, and substring takes end as being
- * exclusive
- */
- newEnd++;
-
- if (newStart >= sLen || newEnd < 0) {
- return "";
- }
-
- return s.substring(newStart, newEnd);
- }
-
- /**
- * Returns true if the project is an alias project.
- * <p/>
- * Alias projects require both the --url and the --label options.
- * @return boolean true if the project requested is an alias project
- */
- private boolean isAliasProject() {
- return (!isStringEmpty(mAliasData) && !isStringEmpty(mApplicationLabel));
- }
-
- /**
- * Extracts a "full" package & activity name from an AndroidManifest.xml.
- * @param osManifestPath The OS path to the AndroidManifest.xml
- * @return A full "package.ActivtyName" if this is a valid manifest,
- * or "package." (with a dot at the end) if there's no activity,
- * or null if there's no valid package namespace.
- */
- private String extractPackageFromManifest(String osManifestPath) {
- File f = new File(osManifestPath);
- if (!f.isFile()) {
- return null;
- }
-
- try {
- final String nsPrefix = "android";
- final String nsURI = "http://schemas.android.com/apk/res/android";
-
- XPath xpath = XPathFactory.newInstance().newXPath();
-
- xpath.setNamespaceContext(new NamespaceContext() {
- public String getNamespaceURI(String prefix) {
- if (nsPrefix.equals(prefix)) {
- return nsURI;
- }
- return XMLConstants.NULL_NS_URI;
- }
-
- public String getPrefix(String namespaceURI) {
- if (nsURI.equals(namespaceURI)) {
- return nsPrefix;
- }
- return null;
- }
-
- @SuppressWarnings("unchecked")
- public Iterator getPrefixes(String namespaceURI) {
- if (nsURI.equals(namespaceURI)) {
- ArrayList<String> list = new ArrayList<String>();
- list.add(nsPrefix);
- return list.iterator();
- }
- return null;
- }
-
- });
-
- InputSource source = new InputSource(new FileReader(osManifestPath));
- String packageName = xpath.evaluate("/manifest/@package", source);
-
- source = new InputSource(new FileReader(osManifestPath));
-
- // Select the "android:name" attribute of all <activity> nodes but only if they
- // contain a sub-node <intent-filter><action> with an "android:name" attribute which
- // is 'android.intent.action.MAIN' and an <intent-filter><category> with an
- // "android:name" attribute which is 'android.intent.category.LAUNCHER'
- String expression = String.format("/manifest/application/activity" +
- "[intent-filter/action/@%1$s:name='android.intent.action.MAIN' and " +
- "intent-filter/category/@%1$s:name='android.intent.category.LAUNCHER']" +
- "/@%1$s:name", nsPrefix);
-
- NodeList activityNames = (NodeList) xpath.evaluate(expression, source,
- XPathConstants.NODESET);
-
- // If we get here, both XPath expressions were valid so we're most likely dealing
- // with an actual AndroidManifest.xml file. The nodes may not have the requested
- // attributes though, if which case we should warn.
-
- if (packageName == null || packageName.length() == 0) {
- printHelpAndExit("ERROR: missing <manifest package=\"...\"> in '%1$s'",
- osManifestPath);
- }
-
- // Get the first activity that matched earlier. If there is no activity,
- // activityName is set to an empty string and the generated "combined" name
- // will be in the form "package." (with a dot at the end).
- String activityName = "";
- if (activityNames.getLength() > 0) {
- activityName = activityNames.item(0).getNodeValue();
- }
-
- if (!mSilent && activityNames.getLength() > 1) {
- println("WARNING: There is more than one activity defined in '%1$s'.\n" +
- "Only the first one will be used. If this is not appropriate, you need\n" +
- "to specify one of these values manually instead:",
- osManifestPath);
-
- for (int i = 0; i < activityNames.getLength(); i++) {
- String name = activityNames.item(i).getNodeValue();
- name = combinePackageActivityNames(packageName, name);
- println("- %1$s", name);
- }
- }
-
- if (!mSilent && activityName.length() == 0) {
- println("WARNING: missing <activity %1$s:name=\"...\"> in '%2$s'.\n" +
- "No activity will be generated.",
- nsPrefix, osManifestPath);
- }
-
- return combinePackageActivityNames(packageName, activityName);
-
- } catch (IOException e) {
- printHelpAndExit("ERROR: failed to read '%1$s', %2$s", osManifestPath, e.getMessage());
- } catch (XPathExpressionException e) {
- Throwable t = e.getCause();
- printHelpAndExit("ERROR: failed to parse '%1$s', %2$s", osManifestPath,
- t == null ? e.getMessage() : t.getMessage());
- }
-
- return null;
- }
-
- private String combinePackageActivityNames(String packageName,
- String activityName) {
- // Activity Name can have 3 forms:
- // - ".Name" means this is a class name in the given package name.
- // The full FQCN is thus packageName + ".Name"
- // - "Name" is an older variant of the former. Full FQCN is packageName + "." + "Name"
- // - "com.blah.Name" is a full FQCN. Ignore packageName and use activityName as-is.
- // To be valid, the package name should have at least two components. This is checked
- // later during the creation of the build.xml file, so we just need to detect there's
- // a dot but not at pos==0.
-
- int pos = activityName.indexOf('.');
- if (pos == 0) {
- return packageName + activityName;
- } else if (pos > 0) {
- return activityName;
- } else {
- return packageName + "." + activityName;
- }
- }
-
-}
diff --git a/tools/androidprefs/src/com/android/prefs/AndroidLocation.java b/tools/androidprefs/src/com/android/prefs/AndroidLocation.java
index 3530f2dd1..a7ceb76a4 100644
--- a/tools/androidprefs/src/com/android/prefs/AndroidLocation.java
+++ b/tools/androidprefs/src/com/android/prefs/AndroidLocation.java
@@ -56,47 +56,15 @@ public final class AndroidLocation {
*/
public final static String getFolder() throws AndroidLocationException {
if (sPrefsLocation == null) {
- String osName = System.getProperty("os.name");
-
- // First we check for unknown or non windows OS.
- if (osName == null || osName.startsWith("Windows") == false) {
- String home = findValidPath("user.home", "HOME");
-
- if (home != null) {
- sPrefsLocation = home + File.separator + ".android" + File.separator;
- }
- } else {
- String localAppData = findValidPath("LOCALAPPDATA");
- if (localAppData == null) {
- localAppData = findValidPath("USERPROFILE");
- if (localAppData != null) {
- localAppData = localAppData + "\\Local Settings\\Application Data";
-
- // check that this directory exists.
- File f = new File(localAppData);
- if (f.isDirectory() == false) {
- localAppData = null;
- }
- }
-
- // ok if nothing worked, revert to HOME
- if (localAppData == null) {
- localAppData = findValidPath("HOME", "user.home");
- }
- }
-
- if (localAppData != null) {
- sPrefsLocation = localAppData + "\\Android\\";
- }
- }
+ String home = findValidPath("user.home", "HOME");
- // if all the above failed, try to create a temporary file to get its parent and
- // use that as the folder
- if (sPrefsLocation == null) {
- // no home dir?
+ // if the above failed, we throw an exception.
+ if (home == null) {
throw new AndroidLocationException(
"Unable to get the home directory. Make sure the user.home property is set up");
} else {
+ sPrefsLocation = home + File.separator + ".android" + File.separator;
+
// make sure the folder exists!
File f = new File(sPrefsLocation);
if (f.exists() == false) {
@@ -107,7 +75,7 @@ public final class AndroidLocation {
}
}
}
-
+
return sPrefsLocation;
}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project
index 6689a1f9b..c7b1ad476 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/.project
@@ -3,6 +3,8 @@
<name>adt</name>
<comment></comment>
<projects>
+ <project>SdkLib</project>
+ <project>SdkUiLib</project>
</projects>
<buildSpec>
<buildCommand>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java
index a0a3603fb..172b4ae34 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/Sdk.java
@@ -82,9 +82,11 @@ public class Sdk {
logMessages.add(throwable.getMessage());
}
}
+
public void warning(String warningFormat, Object... arg) {
logMessages.add(String.format(warningFormat, arg));
}
+
public void printf(String msgFormat, Object... arg) {
logMessages.add(String.format(msgFormat, arg));
}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
index 0e780a982..65817c306 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/AndroidConstants.java
@@ -158,9 +158,6 @@ public class AndroidConstants {
/** Regexp for aidl extension, i.e. "\.aidl$" */
public final static String RE_AIDL_EXT = "\\.aidl$"; //$NON-NLS-1$
- /** Namespace for the resource XML, i.e. "http://schemas.android.com/apk/res/android" */
- public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android"; //$NON-NLS-1$
-
/** Namespace pattern for the custom resource XML, i.e. "http://schemas.android.com/apk/res/%s" */
public final static String NS_CUSTOM_RESOURCES = "http://schemas.android.com/apk/res/%1$s"; //$NON-NLS-1$
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
index 2866ce21f..850c59d71 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestParser.java
@@ -18,6 +18,7 @@ package com.android.ide.eclipse.common.project;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.project.XmlErrorHandler.XmlErrorListener;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IMarker;
@@ -442,7 +443,7 @@ public class AndroidManifestParser {
* @param attributeName the name of the attribute to look for.
* @param hasNamespace Indicates whether the attribute has an android namespace.
* @return a String with the value or null if the attribute was not found.
- * @see AndroidConstants#NS_RESOURCES
+ * @see SdkConstants#NS_RESOURCES
*/
private String getAttributeValue(Attributes attributes, String attributeName,
boolean hasNamespace) {
@@ -450,7 +451,7 @@ public class AndroidManifestParser {
for (int i = 0 ; i < count ; i++) {
if (attributeName.equals(attributes.getLocalName(i)) &&
((hasNamespace &&
- AndroidConstants.NS_RESOURCES.equals(attributes.getURI(i))) ||
+ SdkConstants.NS_RESOURCES.equals(attributes.getURI(i))) ||
(hasNamespace == false && attributes.getURI(i).length() == 0))) {
return attributes.getValue(i);
}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java
index 8544b25ff..0f1e25574 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidXPathFactory.java
@@ -16,7 +16,7 @@
package com.android.ide.eclipse.common.project;
-import com.android.ide.eclipse.common.AndroidConstants;
+import com.android.sdklib.SdkConstants;
import java.util.Iterator;
@@ -48,7 +48,7 @@ public class AndroidXPathFactory {
public String getNamespaceURI(String prefix) {
if (prefix != null) {
if (prefix.equals(mAndroidPrefix)) {
- return AndroidConstants.NS_RESOURCES;
+ return SdkConstants.NS_RESOURCES;
}
}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
index 50d3d2856..a325ccbf6 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidContentAssist.java
@@ -17,7 +17,6 @@
package com.android.ide.eclipse.editors;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
@@ -29,6 +28,7 @@ import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiFlagAttributeNode;
+import com.android.sdklib.SdkConstants;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
@@ -199,13 +199,13 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
*
* @param node The current node. Must not be null.
* @param nsUri The namespace URI of which the prefix is to be found,
- * e.g. AndroidConstants.NS_RESOURCES
+ * e.g. {@link SdkConstants#NS_RESOURCES}
* @return The first prefix declared or the default "android" prefix.
*/
private String lookupNamespacePrefix(Node node, String nsUri) {
// Note: Node.lookupPrefix is not implemented in wst/xml/core NodeImpl.java
// The following emulates this:
- // String prefix = node.lookupPrefix(AndroidConstants.NS_RESOURCES);
+ // String prefix = node.lookupPrefix(SdkConstants.NS_RESOURCES);
if (XmlnsAttributeDescriptor.XMLNS_URI.equals(nsUri)) {
return "xmlns"; //$NON-NLS-1$
@@ -223,7 +223,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
Node attr = attrs.item(n);
if ("xmlns".equals(attr.getPrefix())) { //$NON-NLS-1$
String uri = attr.getNodeValue();
- if (AndroidConstants.NS_RESOURCES.equals(uri)) {
+ if (SdkConstants.NS_RESOURCES.equals(uri)) {
return attr.getLocalName();
}
visited.add(uri);
@@ -234,7 +234,7 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor {
// Use a sensible default prefix if we can't find one.
// We need to make sure the prefix is not one that was declared in the scope
// visited above.
- prefix = AndroidConstants.NS_RESOURCES.equals(nsUri) ? "android" : "ns"; //$NON-NLS-1$ //$NON-NLS-2$
+ prefix = SdkConstants.NS_RESOURCES.equals(nsUri) ? "android" : "ns"; //$NON-NLS-1$ //$NON-NLS-2$
String base = prefix;
for (int i = 1; visited.contains(prefix); i++) {
prefix = base + Integer.toString(i);
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java
index 70d03a19b..e0ec86bfb 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptor.java
@@ -17,10 +17,10 @@
package com.android.ide.eclipse.editors.descriptors;
import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
+import com.android.sdklib.SdkConstants;
import org.eclipse.swt.graphics.Image;
@@ -45,7 +45,7 @@ public abstract class AttributeDescriptor {
*
* @param xmlLocalName The XML name of the attribute (case sensitive)
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
*/
public AttributeDescriptor(String xmlLocalName, String nsUri) {
mXmlLocalName = xmlLocalName;
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java
index 09f147833..cc923bf54 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/DescriptorsUtils.java
@@ -23,6 +23,7 @@ import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeIn
import com.android.ide.eclipse.editors.layout.LayoutConstants;
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
+import com.android.sdklib.SdkConstants;
import org.eclipse.swt.graphics.Image;
@@ -75,7 +76,7 @@ public final class DescriptorsUtils {
* @param xmlName The XML attribute name.
* @param uiName The UI attribute name.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param tooltip An optional tooltip.
* @return A new {@link TextAttributeDescriptor} (or derived) instance.
*/
@@ -90,7 +91,7 @@ public final class DescriptorsUtils {
* @param elementXmlName Optional XML local name of the element to which attributes are
* being added. When not null, this is used to filter overrides.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param infos The array of {@link AttributeInfo} to read and append to attributes
* @param requiredAttributes An optional set of attributes to mark as "required" (i.e. append
* a "*" to their UI name as a hint for the user.) If not null, must contains
@@ -125,7 +126,7 @@ public final class DescriptorsUtils {
* being added. When not null, this is used to filter overrides.
* @param info The {@link AttributeInfo} to append to attributes
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param required True if the attribute is to be marked as "required" (i.e. append
* a "*" to its UI name as a hint for the user.)
* @param overrides A map [attribute name => TextAttributeDescriptor creator]. A creator
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java
index 7d7b1c9be..555015537 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ElementDescriptor.java
@@ -17,9 +17,9 @@
package com.android.ide.eclipse.editors.descriptors;
import com.android.ide.eclipse.adt.AdtPlugin;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.IconFactory;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
+import com.android.sdklib.SdkConstants;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.graphics.Image;
@@ -147,7 +147,7 @@ public class ElementDescriptor {
public final String getNamespace() {
// For now we hard-code the prefix as being "android"
if (mXmlName.startsWith("android:")) { //$NON-NLs-1$
- return AndroidConstants.NS_RESOURCES;
+ return SdkConstants.NS_RESOURCES;
}
return ""; //$NON-NLs-1$
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ReferenceAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ReferenceAttributeDescriptor.java
index 3d3ff2901..336dfe2b3 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ReferenceAttributeDescriptor.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/ReferenceAttributeDescriptor.java
@@ -16,12 +16,12 @@
package com.android.ide.eclipse.editors.descriptors;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.resources.ResourceType;
import com.android.ide.eclipse.editors.ui.ResourceValueCellEditor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiResourceAttributeNode;
+import com.android.sdklib.SdkConstants;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.swt.widgets.Composite;
@@ -39,7 +39,7 @@ public final class ReferenceAttributeDescriptor extends TextAttributeDescriptor
* @param xmlLocalName The XML name of the attribute (case sensitive)
* @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param tooltip A non-empty tooltip string or null
*/
public ReferenceAttributeDescriptor(String xmlLocalName, String uiName, String nsUri,
@@ -55,7 +55,7 @@ public final class ReferenceAttributeDescriptor extends TextAttributeDescriptor
* @param xmlLocalName The XML name of the attribute (case sensitive)
* @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param tooltip A non-empty tooltip string or null
*/
public ReferenceAttributeDescriptor(ResourceType resourceType,
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java
index a9d2b2e65..77fc0678d 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/TextAttributeDescriptor.java
@@ -16,11 +16,11 @@
package com.android.ide.eclipse.editors.descriptors;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.ui.TextValueCellEditor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.ide.eclipse.editors.uimodel.UiTextAttributeNode;
+import com.android.sdklib.SdkConstants;
import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.ILabelProvider;
@@ -47,7 +47,7 @@ public class TextAttributeDescriptor extends AttributeDescriptor implements IPro
* @param xmlLocalName The XML name of the attribute (case sensitive)
* @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param tooltip A non-empty tooltip string or null
*/
public TextAttributeDescriptor(String xmlLocalName, String uiName,
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/WidgetPullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/WidgetPullParser.java
index 75d10eda0..e62ab6951 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/WidgetPullParser.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/WidgetPullParser.java
@@ -19,6 +19,7 @@ package com.android.ide.eclipse.editors.layout;
import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
import com.android.layoutlib.api.IXmlPullParser;
+import com.android.sdklib.SdkConstants;
import org.xmlpull.v1.XmlPullParserException;
@@ -61,7 +62,7 @@ public class WidgetPullParser extends BasePullParser {
}
public String getAttributeNamespace(int index) {
- return AndroidConstants.NS_RESOURCES;
+ return SdkConstants.NS_RESOURCES;
}
public String getAttributePrefix(int index) {
@@ -78,7 +79,7 @@ public class WidgetPullParser extends BasePullParser {
}
public String getAttributeValue(String ns, String name) {
- if (AndroidConstants.NS_RESOURCES.equals(ns)) {
+ if (SdkConstants.NS_RESOURCES.equals(ns)) {
for (String[] attribute : mAttributes) {
if (name.equals(attribute[0])) {
return attribute[1];
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java
index cad9ccf60..7caa50f12 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/descriptors/LayoutDescriptors.java
@@ -26,6 +26,7 @@ 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.descriptors.SeparatorAttributeDescriptor;
+import com.android.sdklib.SdkConstants;
import java.util.ArrayList;
import java.util.Collections;
@@ -134,7 +135,7 @@ public final class LayoutDescriptors implements IDescriptorProvider {
ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
DescriptorsUtils.appendAttributes(attributes,
null, // elementName
- AndroidConstants.NS_RESOURCES,
+ SdkConstants.NS_RESOURCES,
info.getAttributes(),
null, // requiredAttributes
null /* overrides */);
@@ -148,7 +149,7 @@ public final class LayoutDescriptors implements IDescriptorProvider {
String.format("Attributes from %1$s", link.getShortClassName())));
DescriptorsUtils.appendAttributes(attributes,
null, // elementName
- AndroidConstants.NS_RESOURCES,
+ SdkConstants.NS_RESOURCES,
attrList,
null, // requiredAttributes
null /* overrides */);
@@ -163,7 +164,7 @@ public final class LayoutDescriptors implements IDescriptorProvider {
boolean need_separator = true;
for (AttributeInfo attr_info : layoutParams.getAttributes()) {
if (DescriptorsUtils.containsAttribute(layoutAttributes,
- AndroidConstants.NS_RESOURCES, attr_info)) {
+ SdkConstants.NS_RESOURCES, attr_info)) {
continue;
}
if (need_separator) {
@@ -182,7 +183,7 @@ public final class LayoutDescriptors implements IDescriptorProvider {
}
DescriptorsUtils.appendAttribute(layoutAttributes,
null, // elementName
- AndroidConstants.NS_RESOURCES,
+ SdkConstants.NS_RESOURCES,
attr_info,
false, // required
null /* overrides */);
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementEditPart.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementEditPart.java
index d873005ce..a2e05c7fa 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementEditPart.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/parts/UiElementEditPart.java
@@ -16,10 +16,10 @@
package com.android.ide.eclipse.editors.layout.parts;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
+import com.android.sdklib.SdkConstants;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.geometry.Point;
@@ -177,7 +177,7 @@ public abstract class UiElementEditPart extends AbstractGraphicalEditPart
NamedNodeMap nodeAttributes = xmlNode.getAttributes();
if (nodeAttributes != null) {
Node attr = nodeAttributes.getNamedItemNS(
- AndroidConstants.NS_RESOURCES, attrName);
+ SdkConstants.NS_RESOURCES, attrName);
if (attr != null) {
return attr.getNodeValue();
}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/uimodel/UiViewElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/uimodel/UiViewElementNode.java
index 45cbc7760..1bf5d5abf 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/uimodel/UiViewElementNode.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/uimodel/UiViewElementNode.java
@@ -26,6 +26,7 @@ import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IProject;
@@ -109,7 +110,7 @@ public class UiViewElementNode extends UiElementNode {
if (need_xmlns) {
AttributeDescriptor desc = new XmlnsAttributeDescriptor(
"android", //$NON-NLS-1$
- AndroidConstants.NS_RESOURCES);
+ SdkConstants.NS_RESOURCES);
mCachedAttributeDescriptors[direct_attrs.length + layout_attrs.length] = desc;
}
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java
index a0b30ecab..61b73a279 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/AndroidManifestDescriptors.java
@@ -28,6 +28,7 @@ import com.android.ide.eclipse.editors.descriptors.ListAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.ReferenceAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.runtime.IStatus;
@@ -166,7 +167,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
"android", //$NON-NLS-1$
- AndroidConstants.NS_RESOURCES);
+ SdkConstants.NS_RESOURCES);
// -- setup the required attributes overrides --
@@ -355,7 +356,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider {
ArrayList<AttributeDescriptor> attrDescs = new ArrayList<AttributeDescriptor>();
DescriptorsUtils.appendAttributes(attrDescs,
elemDesc.getXmlLocalName(),
- AndroidConstants.NS_RESOURCES,
+ SdkConstants.NS_RESOURCES,
style.getAttributes(),
requiredAttributes,
overrides);
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java
index 1144006d2..abaf438d6 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/descriptors/ClassAttributeDescriptor.java
@@ -44,7 +44,7 @@ public class ClassAttributeDescriptor extends TextAttributeDescriptor {
* @param xmlLocalName The XML name of the attribute (case sensitive, with android: prefix).
* @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param tooltip A non-empty tooltip string or null.
* @param mandatory indicates if the class attribute is mandatory.
*/
@@ -64,7 +64,7 @@ public class ClassAttributeDescriptor extends TextAttributeDescriptor {
* @param xmlLocalName The XML local name of the attribute (case sensitive).
* @param uiName The UI name of the attribute. Cannot be an empty string and cannot be null.
* @param nsUri The URI of the attribute. Can be null if attribute has no namespace.
- * See {@link AndroidConstants#NS_RESOURCES} for a common value.
+ * See {@link SdkConstants#NS_RESOURCES} for a common value.
* @param tooltip A non-empty tooltip string or null.
* @param mandatory indicates if the class attribute is mandatory.
*/
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiManifestElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiManifestElementNode.java
index 79295a817..fb8f2115d 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiManifestElementNode.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/manifest/model/UiManifestElementNode.java
@@ -16,12 +16,12 @@
package com.android.ide.eclipse.editors.manifest.model;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescriptors;
import com.android.ide.eclipse.editors.manifest.descriptors.ManifestElementDescriptor;
import com.android.ide.eclipse.editors.uimodel.UiAttributeNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
+import com.android.sdklib.SdkConstants;
import org.w3c.dom.Element;
@@ -74,10 +74,10 @@ public final class UiManifestElementNode extends UiElementNode {
if (desc != manifestDescriptors.getManifestElement() &&
desc != manifestDescriptors.getApplicationElement()) {
Element elem = (Element) getXmlNode();
- String attr = elem.getAttributeNS(AndroidConstants.NS_RESOURCES,
+ String attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
AndroidManifestDescriptors.ANDROID_NAME_ATTR);
if (attr == null || attr.length() == 0) {
- attr = elem.getAttributeNS(AndroidConstants.NS_RESOURCES,
+ attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
AndroidManifestDescriptors.ANDROID_LABEL_ATTR);
}
if (attr != null && attr.length() > 0) {
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/descriptors/MenuDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/descriptors/MenuDescriptors.java
index 34c7bb275..40a8f16db 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/descriptors/MenuDescriptors.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/menu/descriptors/MenuDescriptors.java
@@ -16,13 +16,13 @@
package com.android.ide.eclipse.editors.menu.descriptors;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.common.resources.DeclareStyleableInfo;
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.descriptors.IDescriptorProvider;
import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
+import com.android.sdklib.SdkConstants;
import java.util.ArrayList;
import java.util.Map;
@@ -121,7 +121,7 @@ public final class MenuDescriptors implements IDescriptorProvider {
false /* mandatory */);
XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor("android", //$NON-NLS-1$
- AndroidConstants.NS_RESOURCES);
+ SdkConstants.NS_RESOURCES);
updateElement(mDescriptor, styleMap, "Menu", xmlns); //$NON-NLS-1$
mDescriptor.setChildren(new ElementDescriptor[] { top_item, top_group });
@@ -159,7 +159,7 @@ public final class MenuDescriptors implements IDescriptorProvider {
if (style != null) {
DescriptorsUtils.appendAttributes(descs,
null, // elementName
- AndroidConstants.NS_RESOURCES,
+ SdkConstants.NS_RESOURCES,
style.getAttributes(),
null, // requiredAttributes
null); // overrides
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiElementNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiElementNode.java
index e0e9a4051..3728886b5 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiElementNode.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiElementNode.java
@@ -18,7 +18,6 @@ package com.android.ide.eclipse.editors.uimodel;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.AndroidEditor;
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
@@ -31,6 +30,7 @@ import com.android.ide.eclipse.editors.manifest.descriptors.AndroidManifestDescr
import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptors;
import com.android.ide.eclipse.editors.uimodel.IUiUpdateListener.UiUpdateState;
import com.android.ide.eclipse.editors.xml.descriptors.XmlDescriptors;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.ui.IEditorInput;
@@ -201,21 +201,21 @@ public class UiElementNode implements IPropertySource {
// just using the UI name below.
Element elem = (Element) mXmlNode;
- String attr = elem.getAttributeNS(AndroidConstants.NS_RESOURCES,
+ String attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
AndroidManifestDescriptors.ANDROID_NAME_ATTR);
if (attr == null || attr.length() == 0) {
- attr = elem.getAttributeNS(AndroidConstants.NS_RESOURCES,
+ attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
AndroidManifestDescriptors.ANDROID_LABEL_ATTR);
}
if (attr == null || attr.length() == 0) {
- attr = elem.getAttributeNS(AndroidConstants.NS_RESOURCES,
+ attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
XmlDescriptors.PREF_KEY_ATTR);
}
if (attr == null || attr.length() == 0) {
attr = elem.getAttribute(ResourcesDescriptors.NAME_ATTR);
}
if (attr == null || attr.length() == 0) {
- attr = elem.getAttributeNS(AndroidConstants.NS_RESOURCES,
+ attr = elem.getAttributeNS(SdkConstants.NS_RESOURCES,
LayoutDescriptors.ID_ATTR);
if (attr != null && attr.length() > 0) {
@@ -1205,13 +1205,13 @@ public class UiElementNode implements IPropertySource {
*
* @param node The current node. Must not be null.
* @param nsUri The namespace URI of which the prefix is to be found,
- * e.g. AndroidConstants.NS_RESOURCES
+ * e.g. SdkConstants.NS_RESOURCES
* @return The first prefix declared or the default "android" prefix.
*/
private String lookupNamespacePrefix(Node node, String nsUri) {
// Note: Node.lookupPrefix is not implemented in wst/xml/core NodeImpl.java
// The following code emulates this simple call:
- // String prefix = node.lookupPrefix(AndroidConstants.NS_RESOURCES);
+ // String prefix = node.lookupPrefix(SdkConstants.NS_RESOURCES);
// if the requested URI is null, it denotes an attribute with no namespace.
if (nsUri == null) {
@@ -1234,7 +1234,7 @@ public class UiElementNode implements IPropertySource {
if ("xmlns".equals(attr.getPrefix())) { //$NON-NLS-1$
String uri = attr.getNodeValue();
String nsPrefix = attr.getLocalName();
- if (AndroidConstants.NS_RESOURCES.equals(uri)) {
+ if (SdkConstants.NS_RESOURCES.equals(uri)) {
return nsPrefix;
}
visited.add(nsPrefix);
@@ -1245,7 +1245,7 @@ public class UiElementNode implements IPropertySource {
// Use a sensible default prefix if we can't find one.
// We need to make sure the prefix is not one that was declared in the scope
// visited above.
- String prefix = AndroidConstants.NS_RESOURCES.equals(nsUri) ? "android" : "ns"; //$NON-NLS-1$ //$NON-NLS-2$
+ String prefix = SdkConstants.NS_RESOURCES.equals(nsUri) ? "android" : "ns"; //$NON-NLS-1$ //$NON-NLS-2$
String base = prefix;
for (int i = 1; visited.contains(prefix); i++) {
prefix = base + Integer.toString(i);
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiListAttributeNode.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiListAttributeNode.java
index aaad0ce72..c5c10aa11 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiListAttributeNode.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/uimodel/UiListAttributeNode.java
@@ -18,7 +18,6 @@ package com.android.ide.eclipse.editors.uimodel;
import com.android.ide.eclipse.adt.AdtPlugin;
import com.android.ide.eclipse.adt.sdk.AndroidTargetData;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.AndroidEditor;
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
@@ -26,6 +25,7 @@ import com.android.ide.eclipse.editors.descriptors.ListAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
import com.android.ide.eclipse.editors.ui.SectionHelper;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.swt.SWT;
@@ -135,7 +135,7 @@ public class UiListAttributeNode extends UiAbstractTextAttributeNode {
// FrameworkResourceManager expects a specific prefix for the attribute.
String prefix = "";
- if (AndroidConstants.NS_RESOURCES.equals(descriptor.getNamespaceUri())) {
+ if (SdkConstants.NS_RESOURCES.equals(descriptor.getNamespaceUri())) {
prefix = "android:"; //$NON-NLS-1$
} else if (XmlnsAttributeDescriptor.XMLNS_URI.equals(descriptor.getNamespaceUri())) {
prefix = "xmlns:"; //$NON-NLS-1$
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java
index cc643be49..4d171762c 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/NewXmlFileCreationPage.java
@@ -163,7 +163,7 @@ class NewXmlFileCreationPage extends WizardPage {
/**
* If the generated resource XML file requires an "android" XMLNS, this should be set
- * to {@link AndroidConstants#NS_RESOURCES}. When it is null, no XMLNS is generated.
+ * to {@link SdkConstants#NS_RESOURCES}. When it is null, no XMLNS is generated.
*/
String getXmlns() {
return mXmlns;
@@ -188,7 +188,7 @@ class NewXmlFileCreationPage extends WizardPage {
ResourceFolderType.LAYOUT, // folder type
AndroidTargetData.DESCRIPTOR_LAYOUT, // root seed
"LinearLayout", // default root
- AndroidConstants.NS_RESOURCES, // xmlns
+ SdkConstants.NS_RESOURCES, // xmlns
"android:layout_width=\"wrap_content\"\n" + // default attributes
"android:layout_height=\"wrap_content\""
),
@@ -205,7 +205,7 @@ class NewXmlFileCreationPage extends WizardPage {
ResourceFolderType.MENU, // folder type
MenuDescriptors.MENU_ROOT_ELEMENT, // root seed
null, // default root
- AndroidConstants.NS_RESOURCES, // xmlns
+ SdkConstants.NS_RESOURCES, // xmlns
null // default attributes
),
new TypeInfo("Preference", // UI name
@@ -213,7 +213,7 @@ class NewXmlFileCreationPage extends WizardPage {
ResourceFolderType.XML, // folder type
AndroidTargetData.DESCRIPTOR_PREFERENCES, // root seed
AndroidConstants.CLASS_PREFERENCE_SCREEN, // default root
- AndroidConstants.NS_RESOURCES, // xmlns
+ SdkConstants.NS_RESOURCES, // xmlns
null // default attributes
),
new TypeInfo("Searchable", // UI name
@@ -221,7 +221,7 @@ class NewXmlFileCreationPage extends WizardPage {
ResourceFolderType.XML, // folder type
AndroidTargetData.DESCRIPTOR_SEARCHABLE, // root seed
null, // default root
- AndroidConstants.NS_RESOURCES, // xmlns
+ SdkConstants.NS_RESOURCES, // xmlns
null // default attributes
),
new TypeInfo("Animation", // UI name
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlEditor.java
index b1900ae41..d7f611949 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlEditor.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/XmlEditor.java
@@ -26,6 +26,7 @@ import com.android.ide.eclipse.editors.descriptors.DocumentDescriptor;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.uimodel.UiDocumentNode;
import com.android.sdklib.IAndroidTarget;
+import com.android.sdklib.SdkConstants;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
@@ -80,7 +81,7 @@ public class XmlEditor extends AndroidEditor {
FirstElementParser.Result result = FirstElementParser.parse(
file.getLocation().toOSString(),
- AndroidConstants.NS_RESOURCES);
+ SdkConstants.NS_RESOURCES);
if (result != null) {
String name = result.getElement();
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java
index 31b4c617a..fa1370f31 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/xml/descriptors/XmlDescriptors.java
@@ -25,9 +25,10 @@ import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils;
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.descriptors.XmlnsAttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.SeparatorAttributeDescriptor;
+import com.android.ide.eclipse.editors.descriptors.XmlnsAttributeDescriptor;
import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor;
+import com.android.sdklib.SdkConstants;
import java.util.ArrayList;
import java.util.Map;
@@ -111,7 +112,7 @@ public final class XmlDescriptors implements IDescriptorProvider {
XmlnsAttributeDescriptor xmlns = new XmlnsAttributeDescriptor(
"android", //$NON-NLS-1$
- AndroidConstants.NS_RESOURCES);
+ SdkConstants.NS_RESOURCES);
ElementDescriptor searchable = createSearchable(searchableStyleMap, xmlns);
ElementDescriptor preferences = createPreference(prefs, prefGroups, xmlns);
@@ -191,7 +192,7 @@ public final class XmlDescriptors implements IDescriptorProvider {
if (style != null) {
DescriptorsUtils.appendAttributes(descs,
null, // elementName
- AndroidConstants.NS_RESOURCES,
+ SdkConstants.NS_RESOURCES,
style.getAttributes(),
null, // requiredAttributes
null); // overrides
@@ -280,7 +281,7 @@ public final class XmlDescriptors implements IDescriptorProvider {
ArrayList<AttributeDescriptor> attributes = new ArrayList<AttributeDescriptor>();
DescriptorsUtils.appendAttributes(attributes,
null, // elementName
- AndroidConstants.NS_RESOURCES,
+ SdkConstants.NS_RESOURCES,
info.getAttributes(),
null, // requiredAttributes
null); // overrides
@@ -294,7 +295,7 @@ public final class XmlDescriptors implements IDescriptorProvider {
String.format("Attributes from %1$s", link.getShortClassName())));
DescriptorsUtils.appendAttributes(attributes,
null, // elementName
- AndroidConstants.NS_RESOURCES,
+ SdkConstants.NS_RESOURCES,
attrList,
null, // requiredAttributes
null); // overrides
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
index 1cc51e994..40886832d 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.classpath
@@ -5,5 +5,6 @@
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="lib" path="kxml2-2.3.0.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/SdkLib"/>
<classpathentry kind="output" path="bin"/>
</classpath>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project
index 094260254..99e496486 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/.project
@@ -3,6 +3,7 @@
<name>adt-tests</name>
<comment></comment>
<projects>
+ <project>SdkLib</project>
</projects>
<buildSpec>
<buildCommand>
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/layout/UiElementPullParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/layout/UiElementPullParserTest.java
index 1427eeea0..b0deda0ad 100644
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/layout/UiElementPullParserTest.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/layout/UiElementPullParserTest.java
@@ -16,18 +16,17 @@
package com.android.ide.eclipse.editors.layout;
-import com.android.ide.eclipse.common.AndroidConstants;
import com.android.ide.eclipse.editors.descriptors.AttributeDescriptor;
import com.android.ide.eclipse.editors.descriptors.ElementDescriptor;
import com.android.ide.eclipse.editors.descriptors.TextAttributeDescriptor;
import com.android.ide.eclipse.editors.mock.MockXmlNode;
import com.android.ide.eclipse.editors.uimodel.UiElementNode;
+import com.android.sdklib.SdkConstants;
import org.w3c.dom.Node;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
-import java.io.IOException;
import java.util.HashMap;
import junit.framework.TestCase;
@@ -47,22 +46,22 @@ public class UiElementPullParserTest extends TestCase {
// Also add some dummy attributes.
ElementDescriptor buttonDescriptor = new ElementDescriptor("Button", "Button", "", "",
new AttributeDescriptor[] {
- new TextAttributeDescriptor("name", "name", AndroidConstants.NS_RESOURCES, ""),
- new TextAttributeDescriptor("text", "text", AndroidConstants.NS_RESOURCES, ""),
+ new TextAttributeDescriptor("name", "name", SdkConstants.NS_RESOURCES, ""),
+ new TextAttributeDescriptor("text", "text", SdkConstants.NS_RESOURCES, ""),
},
new ElementDescriptor[] {}, false);
ElementDescriptor textDescriptor = new ElementDescriptor("TextView", "TextView", "", "",
new AttributeDescriptor[] {
- new TextAttributeDescriptor("name", "name", AndroidConstants.NS_RESOURCES, ""),
- new TextAttributeDescriptor("text", "text", AndroidConstants.NS_RESOURCES, ""), },
+ new TextAttributeDescriptor("name", "name", SdkConstants.NS_RESOURCES, ""),
+ new TextAttributeDescriptor("text", "text", SdkConstants.NS_RESOURCES, ""), },
new ElementDescriptor[] {}, false);
ElementDescriptor linearDescriptor = new ElementDescriptor("LinearLayout", "Linear Layout",
"", "",
new AttributeDescriptor[] {
new TextAttributeDescriptor("orientation", "orientation",
- AndroidConstants.NS_RESOURCES, ""),
+ SdkConstants.NS_RESOURCES, ""),
},
new ElementDescriptor[] { }, false);
@@ -70,7 +69,7 @@ public class UiElementPullParserTest extends TestCase {
"Relative Layout", "", "",
new AttributeDescriptor[] {
new TextAttributeDescriptor("orientation", "orientation",
- AndroidConstants.NS_RESOURCES, ""),
+ SdkConstants.NS_RESOURCES, ""),
},
new ElementDescriptor[] { }, false);
@@ -99,8 +98,8 @@ public class UiElementPullParserTest extends TestCase {
*/
MockXmlNode button1 = new MockXmlNode(null /* namespace */, "Button", Node.ELEMENT_NODE,
null);
- button1.addAttributes(AndroidConstants.NS_RESOURCES, "name", "button1");
- button1.addAttributes(AndroidConstants.NS_RESOURCES, "text", "button1text");
+ button1.addAttributes(SdkConstants.NS_RESOURCES, "name", "button1");
+ button1.addAttributes(SdkConstants.NS_RESOURCES, "text", "button1text");
// create a map of the attributes we add to the multi-attribute nodes so that
// we can more easily test the values when we parse the XML.
@@ -112,8 +111,8 @@ public class UiElementPullParserTest extends TestCase {
MockXmlNode button2 = new MockXmlNode(null /* namespace */, "Button", Node.ELEMENT_NODE,
null);
- button2.addAttributes(AndroidConstants.NS_RESOURCES, "name", "button2");
- button2.addAttributes(AndroidConstants.NS_RESOURCES, "text", "button2text");
+ button2.addAttributes(SdkConstants.NS_RESOURCES, "name", "button2");
+ button2.addAttributes(SdkConstants.NS_RESOURCES, "text", "button2text");
button2Map = new HashMap<String, String>();
button2Map.put("name", "button2");
@@ -121,8 +120,8 @@ public class UiElementPullParserTest extends TestCase {
MockXmlNode text = new MockXmlNode(null /* namespace */, "TextView", Node.ELEMENT_NODE,
null);
- text.addAttributes(AndroidConstants.NS_RESOURCES, "name", "text1");
- text.addAttributes(AndroidConstants.NS_RESOURCES, "text", "text1text");
+ text.addAttributes(SdkConstants.NS_RESOURCES, "name", "text1");
+ text.addAttributes(SdkConstants.NS_RESOURCES, "text", "text1text");
textMap = new HashMap<String, String>();
textMap.put("name", "text1");
@@ -130,17 +129,17 @@ public class UiElementPullParserTest extends TestCase {
MockXmlNode relative = new MockXmlNode(null /* namespace */, "RelativeLayout",
Node.ELEMENT_NODE, new MockXmlNode[] { button2, text });
- relative.addAttributes(AndroidConstants.NS_RESOURCES, "orientation", "toto");
+ relative.addAttributes(SdkConstants.NS_RESOURCES, "orientation", "toto");
MockXmlNode linear = new MockXmlNode(null /* namespace */, "LinearLayout",
Node.ELEMENT_NODE, new MockXmlNode[] { button1, relative });
- linear.addAttributes(AndroidConstants.NS_RESOURCES, "orientation", "vertical");
+ linear.addAttributes(SdkConstants.NS_RESOURCES, "orientation", "vertical");
MockXmlNode root = new MockXmlNode(null /* namespace */, "root", Node.ELEMENT_NODE,
new MockXmlNode[] { linear });
// put the namespace/prefix in place
- root.setPrefix(AndroidConstants.NS_RESOURCES, "android");
+ root.setPrefix(SdkConstants.NS_RESOURCES, "android");
// load the xml into the UiElementNode
ui.loadFromXmlNode(root);
@@ -165,7 +164,7 @@ public class UiElementPullParserTest extends TestCase {
assertEquals("LinearLayout", parser.getName());
assertEquals(1, parser.getAttributeCount());
assertEquals("orientation", parser.getAttributeName(0));
- assertEquals(AndroidConstants.NS_RESOURCES, parser.getAttributeNamespace(0));
+ assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(0));
assertEquals("android", parser.getAttributePrefix(0));
assertEquals("vertical", parser.getAttributeValue(0));
@@ -183,7 +182,7 @@ public class UiElementPullParserTest extends TestCase {
assertEquals("RelativeLayout", parser.getName());
assertEquals(1, parser.getAttributeCount());
assertEquals("orientation", parser.getAttributeName(0));
- assertEquals(AndroidConstants.NS_RESOURCES, parser.getAttributeNamespace(0));
+ assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(0));
assertEquals("android", parser.getAttributePrefix(0));
assertEquals("toto", parser.getAttributeValue(0));
@@ -234,7 +233,7 @@ public class UiElementPullParserTest extends TestCase {
assertNotNull(referenceValue);
assertEquals(referenceValue, value);
- assertEquals(AndroidConstants.NS_RESOURCES, parser.getAttributeNamespace(i));
+ assertEquals(SdkConstants.NS_RESOURCES, parser.getAttributeNamespace(i));
assertEquals("android", parser.getAttributePrefix(i));
}
diff --git a/tools/runtest b/tools/runtest
index 989f8a493..9978504d9 100755
--- a/tools/runtest
+++ b/tools/runtest
@@ -114,7 +114,7 @@ knownTests=(
# system-wide tests
"framework frameworks/base/tests/FrameworkTest # com.android.frameworktest.AllTests com.android.frameworktest.tests #"
"android frameworks/base/tests/AndroidTests com.android.unit_tests AndroidTests # #"
- "smoke tests/SmokeTest com.android.smoketest # com.android.smoketest.tests #"
+ "smoke frameworks/base/tests/SmokeTest com.android.smoketest # com.android.smoketest.tests #"
"core frameworks/base/tests/CoreTests # android.core.CoreTests android.core #"
"libcore frameworks/base/tests/CoreTests # android.core.JavaTests android.core #"
"apidemos samples/ApiDemos com.example.android.apis # com.example.android.apis.tests #"
diff --git a/tools/scripts/build.alias.template b/tools/scripts/build.alias.template
index b85887e8c..f7de2e889 100644
--- a/tools/scripts/build.alias.template
+++ b/tools/scripts/build.alias.template
@@ -1,5 +1,5 @@
<?xml version="1.0" ?>
-<project name="ACTIVITY_NAME" default="package">
+<project name="PROJECT_NAME" default="package">
<!-- The build.properties file can be created by you and is never touched
by activitycreator. If you want to manually set properties, this is
diff --git a/tools/scripts/build.template b/tools/scripts/build.template
index 8923428a0..350d0f417 100644
--- a/tools/scripts/build.template
+++ b/tools/scripts/build.template
@@ -1,5 +1,5 @@
<?xml version="1.0" ?>
-<project name="ACTIVITY_NAME" default="help">
+<project name="PROJECT_NAME" default="help">
<!-- The local.properties file is created and updated by the 'android' tool.
It contain the path to the SDK. It should *NOT* be checked in in Version
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
index d63272df4..2db668ef5 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java
@@ -45,6 +45,8 @@ public class CommandLineProcessor {
public static final String KEY_HELP = "help";
/** The global verbose flag. */
public static final String KEY_VERBOSE = "verbose";
+ /** The global silent flag. */
+ public static final String KEY_SILENT = "silent";
/** The internal action flag. */
public static final String KEY_ACTION = "action";
@@ -65,10 +67,18 @@ public class CommandLineProcessor {
mLog = logger;
mActions = actions;
- define(MODE.STRING, false, INTERNAL_FLAG, null, KEY_ACTION, "Selected Action", null);
-
- define(MODE.BOOLEAN, false, GLOBAL_FLAG, "v", KEY_VERBOSE, "Verbose mode", false);
- define(MODE.BOOLEAN, false, GLOBAL_FLAG, "h", KEY_HELP, "This help", false);
+ define(MODE.STRING, false, INTERNAL_FLAG, null, KEY_ACTION,
+ "Selected Action", null);
+
+ define(MODE.BOOLEAN, false, GLOBAL_FLAG, "v", KEY_VERBOSE,
+ "Verbose mode: errors, warnings and informational messages are printed.",
+ false);
+ define(MODE.BOOLEAN, false, GLOBAL_FLAG, "s", KEY_SILENT,
+ "Silent mode: only errors are printed out.",
+ false);
+ define(MODE.BOOLEAN, false, GLOBAL_FLAG, "h", KEY_HELP,
+ "This help.",
+ false);
}
//------------------
@@ -79,6 +89,11 @@ public class CommandLineProcessor {
return ((Boolean) getValue(GLOBAL_FLAG, KEY_VERBOSE)).booleanValue();
}
+ /** Helper that returns true if --silent was requested. */
+ public boolean isSilent() {
+ return ((Boolean) getValue(GLOBAL_FLAG, KEY_SILENT)).booleanValue();
+ }
+
/** Helper that returns true if --help was requested. */
public boolean isHelpRequested() {
return ((Boolean) getValue(GLOBAL_FLAG, KEY_HELP)).booleanValue();
@@ -204,18 +219,29 @@ public class CommandLineProcessor {
needsHelp = "Missing action name.";
} else {
// Validate that all mandatory arguments are non-null for this action
+ String missing = null;
+ boolean plural = false;
for (Entry<String, Arg> entry : mArguments.entrySet()) {
Arg arg = entry.getValue();
if (arg.getAction().equals(action)) {
if (arg.isMandatory() && arg.getCurrentValue() == null) {
- needsHelp = String.format("The parameter --%1$s must be defined for action '%2$s'",
- arg.getLongArg(),
- action);
- break;
+ if (missing == null) {
+ missing = "--" + arg.getLongArg();
+ } else {
+ missing += ", --" + arg.getLongArg();
+ plural = true;
+ }
}
}
}
-
+
+ if (missing != null) {
+ needsHelp = String.format("The %1$s %2$s must be defined for action '%3$s'",
+ plural ? "parameters" : "parameter",
+ missing,
+ action);
+ }
+
setValue(INTERNAL_FLAG, KEY_ACTION, action);
}
}
@@ -324,24 +350,29 @@ public class CommandLineProcessor {
Arg arg = entry.getValue();
if (arg.getAction().equals(action)) {
- String value = null;
+ String value = "";
if (arg.getDefaultValue() instanceof String[]) {
- value = "";
for (String v : (String[]) arg.getDefaultValue()) {
if (value.length() > 0) {
- value += "|";
+ value += ", ";
}
value += v;
}
} else if (arg.getDefaultValue() != null) {
value = arg.getDefaultValue().toString();
}
+ if (value.length() > 0) {
+ value = " (" + value + ")";
+ }
+
+ String required = arg.isMandatory() ? " [required]" : "";
- stdout(" -%1$s %2$-10s %3$s%4$s",
+ stdout(" -%1$s %2$-10s %3$s%4$s%5$s",
arg.getShortArg(),
"--" + arg.getLongArg(),
arg.getDescription(),
- value == null ? "" : " (" + value + ")");
+ value,
+ required);
numOptions++;
}
}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
index b50b113dd..1544f5bff 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -144,7 +144,7 @@ class Main {
if (mSdkFolder == null) {
errorAndExit("The tools directory property is not set, please make sure you are executing %1$s",
- SdkConstants.AndroidCmdName());
+ SdkConstants.androidCmdName());
}
// We might get passed a property for the working directory
@@ -203,19 +203,48 @@ class Main {
IAndroidTarget[] targets = mSdkManager.getTargets();
if (targetId < 1 || targetId > targets.length) {
errorAndExit("Target id is not valid. Use '%s list -f target' to get the target Ids.",
- SdkConstants.AndroidCmdName());
+ SdkConstants.androidCmdName());
}
IAndroidTarget target = targets[targetId - 1];
ProjectCreator creator = new ProjectCreator(mSdkFolder,
- mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE : OutputLevel.NORMAL,
+ mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
+ mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
+ OutputLevel.NORMAL,
mSdkLog);
String projectDir = getProjectLocation(mSdkCommandLine.getNewProjectLocation());
creator.createProject(projectDir,
- mSdkCommandLine.getNewProjectName(), mSdkCommandLine.getNewProjectPackage(),
- mSdkCommandLine.getNewProjectActivity(), target, false /* isTestProject*/);
+ mSdkCommandLine.getNewProjectName(),
+ mSdkCommandLine.getNewProjectPackage(),
+ mSdkCommandLine.getNewProjectActivity(),
+ target,
+ false /* isTestProject*/);
+ } else if (SdkCommandLine.ACTION_UPDATE_PROJECT.equals(action)) {
+ // get the target and try to resolve it.
+ IAndroidTarget target = null;
+ int targetId = mSdkCommandLine.getUpdateProjectTargetId();
+ if (targetId >= 0) {
+ IAndroidTarget[] targets = mSdkManager.getTargets();
+ if (targetId < 1 || targetId > targets.length) {
+ errorAndExit("Target id is not valid. Use '%s list -f target' to get the target Ids.",
+ SdkConstants.androidCmdName());
+ }
+ target = targets[targetId - 1];
+ }
+
+ ProjectCreator creator = new ProjectCreator(mSdkFolder,
+ mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
+ mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
+ OutputLevel.NORMAL,
+ mSdkLog);
+
+ String projectDir = getProjectLocation(mSdkCommandLine.getUpdateProjectLocation());
+
+ creator.updateProject(projectDir,
+ target,
+ mSdkCommandLine.getUpdateProjectName());
} else {
mSdkCommandLine.printHelpAndExit(null);
}
@@ -355,7 +384,7 @@ class Main {
target = mSdkManager.getTargets()[targetId-1]; // target it is 1-based
} else {
errorAndExit("Target id is not valid. Use '%s list -f target' to get the target Ids.",
- SdkConstants.AndroidCmdName());
+ SdkConstants.androidCmdName());
}
try {
@@ -384,8 +413,7 @@ class Main {
mSdkCommandLine.getNewVmName(),
target,
mSdkCommandLine.getNewVmSkin(),
- null /*sdcardPath*/,
- 0 /*sdcardSize*/,
+ mSdkCommandLine.getNewVmSdCard(),
hardwareConfig,
mSdkLog);
}
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
index 39c80b195..08626a833 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
@@ -31,7 +31,6 @@ public class SdkCommandLine extends CommandLineProcessor {
public static final String ARG_TARGET = "target";
public static final String ARG_ALL = "all";
- public static final String KEY_IN = "in";
public static final String KEY_ACTIVITY = ARG_ACTIVITY;
public static final String KEY_PACKAGE = "package";
public static final String KEY_MODE = "mode";
@@ -40,7 +39,7 @@ public class SdkCommandLine extends CommandLineProcessor {
public static final String KEY_OUT = "out";
public static final String KEY_FILTER = "filter";
public static final String KEY_SKIN = "skin";
- public static final String KEY_SDCARD_PATH = "sdcard";
+ public static final String KEY_SDCARD = "sdcard";
public final static String ACTION_LIST = "list";
public final static String ACTION_NEW_VM = ARG_VM;
@@ -72,26 +71,28 @@ public class SdkCommandLine extends CommandLineProcessor {
"Target id of the new VM", null);
define(MODE.STRING, true, ACTION_NEW_VM, "s", KEY_SKIN,
"Skin of the new VM", null);
- define(MODE.STRING, true, ACTION_NEW_VM, "p", KEY_SDCARD_PATH,
- "Path to a shared SD card image for the new VM", null);
+ define(MODE.STRING, false, ACTION_NEW_VM, "c", KEY_SDCARD,
+ "Path to a shared SD card image, or size of a new sdcard for the new VM", null);
define(MODE.ENUM, true, ACTION_NEW_PROJECT, "m", KEY_MODE,
"Project mode", new String[] { ARG_ACTIVITY, ARG_ALIAS });
- define(MODE.STRING, false, ACTION_NEW_PROJECT, "o", KEY_OUT,
+ define(MODE.STRING, true, ACTION_NEW_PROJECT, "o", KEY_OUT,
"Location path of new project", null);
- define(MODE.STRING, true, ACTION_NEW_PROJECT, "n", KEY_NAME,
- "Name of the new project", null);
define(MODE.INTEGER, true, ACTION_NEW_PROJECT, "t", KEY_TARGET_ID,
"Target id of the new project", null);
define(MODE.STRING, true, ACTION_NEW_PROJECT, "p", KEY_PACKAGE,
"Package name", null);
define(MODE.STRING, true, ACTION_NEW_PROJECT, "a", KEY_ACTIVITY,
"Activity name", null);
-
- define(MODE.STRING, false, ACTION_UPDATE_PROJECT, "i", KEY_IN,
- "Directory location of the project", null);
- define(MODE.STRING, true, ACTION_UPDATE_PROJECT, "t", KEY_TARGET_ID,
- "Target id to set for the project", null);
+ define(MODE.STRING, false, ACTION_NEW_PROJECT, "n", KEY_NAME,
+ "Project name", null);
+
+ define(MODE.STRING, true, ACTION_UPDATE_PROJECT, "o", KEY_OUT,
+ "Location path of the project", null);
+ define(MODE.INTEGER, true, ACTION_UPDATE_PROJECT, "t", KEY_TARGET_ID,
+ "Target id to set for the project", -1);
+ define(MODE.STRING, false, ACTION_UPDATE_PROJECT, "n", KEY_NAME,
+ "Project name", null);
}
// -- some helpers for list action flags
@@ -123,9 +124,9 @@ public class SdkCommandLine extends CommandLineProcessor {
return ((String) getValue(ACTION_NEW_VM, KEY_SKIN));
}
- /** Helper to retrieve the --sdcard name for the new vm action. */
+ /** Helper to retrieve the --sdcard data for the new vm action. */
public String getNewVmSdCard() {
- return ((String) getValue(ACTION_NEW_VM, KEY_SDCARD_PATH));
+ return ((String) getValue(ACTION_NEW_VM, KEY_SDCARD));
}
@@ -167,4 +168,9 @@ public class SdkCommandLine extends CommandLineProcessor {
public int getUpdateProjectTargetId() {
return ((Integer) getValue(ACTION_UPDATE_PROJECT, KEY_TARGET_ID)).intValue();
}
+
+ /** Helper to retrieve the --name for the update project action. */
+ public String getUpdateProjectName() {
+ return ((String) getValue(ACTION_UPDATE_PROJECT, KEY_NAME));
+ }
}
diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java
new file mode 100644
index 000000000..961e88dae
--- /dev/null
+++ b/tools/sdkmanager/app/tests/com/android/sdkmanager/MockStdLogger.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2008 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.sdkmanager;
+
+import com.android.sdklib.ISdkLog;
+
+/**
+ *
+ */
+public class MockStdLogger implements ISdkLog {
+
+ public void error(Throwable t, String errorFormat, Object... args) {
+ if (errorFormat != null) {
+ System.err.printf("Error: " + errorFormat, args);
+ if (!errorFormat.endsWith("\n")) {
+ System.err.printf("\n");
+ }
+ }
+ if (t != null) {
+ System.err.printf("Error: %s\n", t.getMessage());
+ }
+ }
+
+ public void warning(String warningFormat, Object... args) {
+ System.out.printf("Warning: " + warningFormat, args);
+ if (!warningFormat.endsWith("\n")) {
+ System.out.printf("\n");
+ }
+ }
+
+ public void printf(String msgFormat, Object... args) {
+ System.out.printf(msgFormat, args);
+ }
+}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
index a2de8fc17..b79dedbe3 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java
@@ -31,6 +31,11 @@ import java.io.File;
*/
public final class SdkConstants {
+ /** An SDK Project's AndroidManifest.xml file */
+ public static final String FN_ANDROID_MANIFEST_XML= "AndroidManifest.xml";
+ /** An SDK Project's build.xml file */
+ public final static String FN_BUILD_XML = "build.xml";
+
/** Name of the framework library, i.e. "android.jar" */
public static final String FN_FRAMEWORK_LIBRARY = "android.jar";
/** Name of the layout attributes, i.e. "attrs.xml" */
@@ -129,7 +134,9 @@ public final class SdkConstants {
/** Name of the addon libs folder. */
public final static String FD_ADDON_LIBS = "libs";
-
+ /** Namespace for the resource XML, i.e. "http://schemas.android.com/apk/res/android" */
+ public final static String NS_RESOURCES = "http://schemas.android.com/apk/res/android";
+
/* Folder path relative to the SDK root */
/** Path of the documentation directory relative to the sdk folder.
* This is an OS path, ending with a separator. */
@@ -206,7 +213,7 @@ public final class SdkConstants {
/** Returns the appropriate name for the 'android' command, which is 'android.bat' for
* Windows and 'android' for all other platforms. */
- public static String AndroidCmdName() {
+ public static String androidCmdName() {
String os = System.getProperty("os.name");
String cmd = "android";
if (os.startsWith("Windows")) {
@@ -215,4 +222,15 @@ public final class SdkConstants {
return cmd;
}
+ /** Returns the appropriate name for the 'mksdcard' command, which is 'mksdcard.exe' for
+ * Windows and 'mkdsdcard' for all other platforms. */
+ public static String mkSdCardCmdName() {
+ String os = System.getProperty("os.name");
+ String cmd = "mksdcard";
+ if (os.startsWith("Windows")) {
+ cmd += ".exe";
+ }
+ return cmd;
+ }
+
}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java
index 4cf224d40..1cff43c88 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java
@@ -21,14 +21,27 @@ import com.android.sdklib.ISdkLog;
import com.android.sdklib.SdkConstants;
import com.android.sdklib.project.ProjectProperties.PropertyType;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
+import java.util.ArrayList;
import java.util.HashMap;
+import java.util.Iterator;
import java.util.Map;
+import java.util.regex.Pattern;
+
+import javax.xml.XMLConstants;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
/**
* Creates the basic files needed to get an Android project up and running. Also
@@ -38,16 +51,31 @@ import java.util.Map;
*/
public class ProjectCreator {
+ /** Package path substitution string used in template files, i.e. "PACKAGE_PATH" */
private final static String PH_JAVA_FOLDER = "PACKAGE_PATH";
+ /** Package name substitution string used in template files, i.e. "PACKAGE" */
private final static String PH_PACKAGE = "PACKAGE";
+ /** Activity name substitution string used in template files, i.e. "ACTIVITY_NAME". */
private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME";
+ /** Project name substitution string used in template files, i.e. "PROJECT_NAME". */
+ private final static String PH_PROJECT_NAME = "PROJECT_NAME";
private final static String FOLDER_TESTS = "tests";
public enum OutputLevel {
- SILENT, NORMAL, VERBOSE;
+ /** Silent mode. Project creation will only display errors. */
+ SILENT,
+ /** Normal mode. Project creation will display what's being done, display
+ * error but not warnings. */
+ NORMAL,
+ /** Verbose mode. Project creation will display what's being done, errors and warnings. */
+ VERBOSE;
}
+ /**
+ * Exception thrown when a project creation fails, typically because a template
+ * file cannot be written.
+ */
private static class ProjectCreateException extends Exception {
/** default UID. This will not be serialized anyway. */
private static final long serialVersionUID = 1L;
@@ -78,7 +106,8 @@ public class ProjectCreator {
/**
* Creates a new project.
- * @param folderPath the folder of the project to create. This folder must exist.
+ *
+ * @param folderPath the folder of the project to create.
* @param projectName the name of the project.
* @param packageName the package of the project.
* @param activityName the activity of the project as it will appear in the manifest.
@@ -113,16 +142,16 @@ public class ProjectCreator {
try {
String[] content = projectFolder.list();
if (content == null) {
- error = "Project directory %1$s is not a directory.";
+ error = "Project folder '%1$s' is not a directory.";
} else if (content.length != 0) {
- error = "Project directory %1$s is not empty. Please consider using '%2$s update' instead.";
+ error = "Project folder '%1$s' is not empty. Please consider using '%2$s update' instead.";
}
} catch (Exception e1) {
e = e1;
}
if (e != null || error != null) {
- mLog.error(e, error, projectFolder, SdkConstants.AndroidCmdName());
+ mLog.error(e, error, projectFolder, SdkConstants.androidCmdName());
}
}
@@ -164,6 +193,21 @@ public class ProjectCreator {
keywords.put(PH_ACTIVITY_NAME, activityName);
}
+ // Take the project name from the command line if there's one
+ if (projectName != null) {
+ keywords.put(PH_PROJECT_NAME, projectName);
+ } else {
+ if (activityName != null) {
+ // Use the activity as project name
+ keywords.put(PH_PROJECT_NAME, activityName);
+ } else {
+ // We need a project name. Just pick up the basename of the project
+ // directory.
+ projectName = projectFolder.getName();
+ keywords.put(PH_PROJECT_NAME, projectName);
+ }
+ }
+
// create the source folder and the java package folders.
final String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath;
File sourceFolder = createDirs(projectFolder, srcFolderPath);
@@ -198,10 +242,13 @@ public class ProjectCreator {
manifestTemplate = "AndroidManifest.tests.template";
}
- installTemplate(manifestTemplate, new File(projectFolder, "AndroidManifest.xml"),
+ installTemplate(manifestTemplate,
+ new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML),
keywords, target);
- installTemplate("build.template", new File(projectFolder, "build.xml"), keywords);
+ installTemplate("build.template",
+ new File(projectFolder, SdkConstants.FN_BUILD_XML),
+ keywords);
// if this is not a test project, then we create one.
if (isTestProject == false) {
@@ -220,6 +267,293 @@ public class ProjectCreator {
}
/**
+ * Updates an existing project.
+ * <p/>
+ * Workflow:
+ * <ul>
+ * <li> Check AndroidManifest.xml is present (required)
+ * <li> Check there's a default.properties with a target *or* --target was specified
+ * <li> Update default.prop if --target was specified
+ * <li> Refresh/create "sdk" in local.properties
+ * <li> Build.xml: create if not present or no <androidinit(\w|/>) in it
+ * </ul>
+ *
+ * @param folderPath the folder of the project to update. This folder must exist.
+ * @param target the project target. Can be null.
+ * @param projectName The project name from --name. Can be null.
+ */
+ public void updateProject(String folderPath, IAndroidTarget target, String projectName ) {
+ // project folder must exist and be a directory, since this is an update
+ File projectFolder = new File(folderPath);
+ if (!projectFolder.isDirectory()) {
+ mLog.error(null, "Project folder '%1$s' is not a valid directory, this is not an Android project you can update.",
+ projectFolder);
+ return;
+ }
+
+ // Check AndroidManifest.xml is present
+ File androidManifest = new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML);
+ if (!androidManifest.isFile()) {
+ mLog.error(null,
+ "%1$s not found in '%2$s', this is not an Android project you can update.",
+ SdkConstants.FN_ANDROID_MANIFEST_XML,
+ folderPath);
+ return;
+ }
+
+ // Check there's a default.properties with a target *or* --target was specified
+ ProjectProperties props = ProjectProperties.load(folderPath, PropertyType.DEFAULT);
+ if (props == null || props.getProperty(ProjectProperties.PROPERTY_TARGET) == null) {
+ if (target == null) {
+ mLog.error(null,
+ "There is no %1$s file in '%2$s'. Please provide a --target to the '%3$s update' command.",
+ PropertyType.DEFAULT.getFilename(),
+ folderPath,
+ SdkConstants.androidCmdName());
+ return;
+ }
+ }
+
+ // Update default.prop iif --target was specified
+ if (target != null) {
+ props = ProjectProperties.create(folderPath, PropertyType.DEFAULT);
+ props.setAndroidTarget(target);
+ try {
+ props.save();
+ println("Updated %1$s", PropertyType.DEFAULT.getFilename());
+ } catch (IOException e) {
+ mLog.error(e, "Failed to write %1$s file in '%2$s'",
+ PropertyType.DEFAULT.getFilename(),
+ folderPath);
+ return;
+ }
+ }
+
+ // Refresh/create "sdk" in local.properties
+ props = ProjectProperties.create(folderPath, PropertyType.LOCAL);
+ props.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder);
+ try {
+ props.save();
+ println("Updated %1$s", PropertyType.LOCAL.getFilename());
+ } catch (IOException e) {
+ mLog.error(e, "Failed to write %1$s file in '%2$s'",
+ PropertyType.LOCAL.getFilename(),
+ folderPath);
+ return;
+ }
+
+ // Build.xml: create if not present or no <androidinit/> in it
+ File buildXml = new File(projectFolder, SdkConstants.FN_BUILD_XML);
+ boolean needsBuildXml = projectName != null || !buildXml.exists();
+ if (!needsBuildXml) {
+ // Note that "<androidinit" must be followed by either a whitespace, a "/" (for the
+ // XML /> closing tag) or an end-of-line. This way we know the XML tag is really this
+ // one and later we will be able to use an "androidinit2" tag or such as necessary.
+ needsBuildXml = !checkFileContainsRegexp(buildXml, "<androidinit(?:\\s|/|$)");
+ if (needsBuildXml) {
+ println("File %1$s is too old and needs to be updated.", SdkConstants.FN_BUILD_XML);
+ }
+ }
+
+ if (needsBuildXml) {
+ // create the map for place-holders of values to replace in the templates
+ final HashMap<String, String> keywords = new HashMap<String, String>();
+
+ // Take the project name from the command line if there's one
+ if (projectName != null) {
+ keywords.put(PH_PROJECT_NAME, projectName);
+ } else {
+ extractPackageFromManifest(androidManifest, keywords);
+ if (keywords.containsKey(PH_ACTIVITY_NAME)) {
+ // Use the activity as project name
+ keywords.put(PH_PROJECT_NAME, keywords.get(PH_ACTIVITY_NAME));
+ } else {
+ // We need a project name. Just pick up the basename of the project
+ // directory.
+ projectName = projectFolder.getName();
+ keywords.put(PH_PROJECT_NAME, projectName);
+ }
+ }
+
+ if (mLevel == OutputLevel.VERBOSE) {
+ println("Regenerating %1$s with project name %2$s",
+ SdkConstants.FN_BUILD_XML,
+ keywords.get(PH_PROJECT_NAME));
+ }
+
+ try {
+ installTemplate("build.template",
+ new File(projectFolder, SdkConstants.FN_BUILD_XML),
+ keywords);
+ } catch (ProjectCreateException e) {
+ mLog.error(e, null);
+ }
+ }
+ }
+
+ /**
+ * Returns true if any line of the input file contains the requested regexp.
+ */
+ private boolean checkFileContainsRegexp(File file, String regexp) {
+ Pattern p = Pattern.compile(regexp);
+
+ try {
+ BufferedReader in = new BufferedReader(new FileReader(file));
+ String line;
+
+ while ((line = in.readLine()) != null) {
+ if (p.matcher(line).find()) {
+ return true;
+ }
+ }
+
+ in.close();
+ } catch (Exception e) {
+ // ignore
+ }
+
+ return false;
+ }
+
+ /**
+ * Extracts a "full" package & activity name from an AndroidManifest.xml.
+ * <p/>
+ * The keywords dictionary is always filed the package name under the key {@link #PH_PACKAGE}.
+ * If an activity name can be found, it is filed under the key {@link #PH_ACTIVITY_NAME}.
+ * When no activity is found, this key is not created.
+ *
+ * @param manifestFile The AndroidManifest.xml file
+ * @param outKeywords Place where to put the out parameters: package and activity names.
+ * @return True if the package/activity was parsed and updated in the keyword dictionary.
+ */
+ private boolean extractPackageFromManifest(File manifestFile,
+ Map<String, String> outKeywords) {
+ try {
+ final String nsPrefix = "android";
+ final String nsURI = SdkConstants.NS_RESOURCES;
+
+ XPath xpath = XPathFactory.newInstance().newXPath();
+
+ xpath.setNamespaceContext(new NamespaceContext() {
+ public String getNamespaceURI(String prefix) {
+ if (nsPrefix.equals(prefix)) {
+ return nsURI;
+ }
+ return XMLConstants.NULL_NS_URI;
+ }
+
+ public String getPrefix(String namespaceURI) {
+ if (nsURI.equals(namespaceURI)) {
+ return nsPrefix;
+ }
+ return null;
+ }
+
+ @SuppressWarnings("unchecked")
+ public Iterator getPrefixes(String namespaceURI) {
+ if (nsURI.equals(namespaceURI)) {
+ ArrayList<String> list = new ArrayList<String>();
+ list.add(nsPrefix);
+ return list.iterator();
+ }
+ return null;
+ }
+
+ });
+
+ InputSource source = new InputSource(new FileReader(manifestFile));
+ String packageName = xpath.evaluate("/manifest/@package", source);
+
+ source = new InputSource(new FileReader(manifestFile));
+
+ // Select the "android:name" attribute of all <activity> nodes but only if they
+ // contain a sub-node <intent-filter><action> with an "android:name" attribute which
+ // is 'android.intent.action.MAIN' and an <intent-filter><category> with an
+ // "android:name" attribute which is 'android.intent.category.LAUNCHER'
+ String expression = String.format("/manifest/application/activity" +
+ "[intent-filter/action/@%1$s:name='android.intent.action.MAIN' and " +
+ "intent-filter/category/@%1$s:name='android.intent.category.LAUNCHER']" +
+ "/@%1$s:name", nsPrefix);
+
+ NodeList activityNames = (NodeList) xpath.evaluate(expression, source,
+ XPathConstants.NODESET);
+
+ // If we get here, both XPath expressions were valid so we're most likely dealing
+ // with an actual AndroidManifest.xml file. The nodes may not have the requested
+ // attributes though, if which case we should warn.
+
+ if (packageName == null || packageName.length() == 0) {
+ mLog.error(null,
+ "Missing <manifest package=\"...\"> in '%1$s'",
+ manifestFile.getName());
+ return false;
+ }
+
+ // Get the first activity that matched earlier. If there is no activity,
+ // activityName is set to an empty string and the generated "combined" name
+ // will be in the form "package." (with a dot at the end).
+ String activityName = "";
+ if (activityNames.getLength() > 0) {
+ activityName = activityNames.item(0).getNodeValue();
+ }
+
+ if (mLevel == OutputLevel.VERBOSE && activityNames.getLength() > 1) {
+ println("WARNING: There is more than one activity defined in '%1$s'.\n" +
+ "Only the first one will be used. If this is not appropriate, you need\n" +
+ "to specify one of these values manually instead:",
+ manifestFile.getName());
+
+ for (int i = 0; i < activityNames.getLength(); i++) {
+ String name = activityNames.item(i).getNodeValue();
+ name = combinePackageActivityNames(packageName, name);
+ println("- %1$s", name);
+ }
+ }
+
+ if (activityName.length() == 0) {
+ mLog.warning("Missing <activity %1$s:name=\"...\"> in '%2$s'.\n" +
+ "No activity will be generated.",
+ nsPrefix, manifestFile.getName());
+ } else {
+ outKeywords.put(PH_ACTIVITY_NAME, activityName);
+ }
+
+ outKeywords.put(PH_PACKAGE, packageName);
+ return true;
+
+ } catch (IOException e) {
+ mLog.error(e, "Failed to read %1$s", manifestFile.getName());
+ } catch (XPathExpressionException e) {
+ Throwable t = e.getCause();
+ mLog.error(t == null ? e : t,
+ "Failed to parse %1$s",
+ manifestFile.getName());
+ }
+
+ return false;
+ }
+
+ private String combinePackageActivityNames(String packageName, String activityName) {
+ // Activity Name can have 3 forms:
+ // - ".Name" means this is a class name in the given package name.
+ // The full FQCN is thus packageName + ".Name"
+ // - "Name" is an older variant of the former. Full FQCN is packageName + "." + "Name"
+ // - "com.blah.Name" is a full FQCN. Ignore packageName and use activityName as-is.
+ // To be valid, the package name should have at least two components. This is checked
+ // later during the creation of the build.xml file, so we just need to detect there's
+ // a dot but not at pos==0.
+
+ int pos = activityName.indexOf('.');
+ if (pos == 0) {
+ return packageName + activityName;
+ } else if (pos > 0) {
+ return activityName;
+ } else {
+ return packageName + "." + activityName;
+ }
+ }
+
+ /**
* Installs a new file that is based on a template file provided by a given target.
* Each match of each key from the place-holder map in the template will be replaced with its
* corresponding value in the created file.
@@ -272,6 +606,9 @@ public class ProjectCreator {
*/
private void installFullPathTemplate(String sourcePath, File destFile,
Map<String, String> placeholderMap) throws ProjectCreateException {
+
+ boolean existed = destFile.exists();
+
try {
BufferedWriter out = new BufferedWriter(new FileWriter(destFile));
BufferedReader in = new BufferedReader(new FileReader(sourcePath));
@@ -293,17 +630,26 @@ public class ProjectCreator {
destFile, e.getMessage());
}
- println("Added file %1$s", destFile);
+ println("%1$s file %2$s",
+ existed ? "Updated" : "Added",
+ destFile);
}
/**
* Prints a message unless silence is enabled.
+ * <p/>
+ * This is just a convenience wrapper around {@link ISdkLog#printf(String, Object...)} from
+ * {@link #mLog} after testing if ouput level is {@link OutputLevel#VERBOSE}.
+ *
* @param format Format for String.format
* @param args Arguments for String.format
*/
private void println(String format, Object... args) {
- if (mLevel == OutputLevel.VERBOSE) {
- System.out.println(String.format(format, args));
+ if (mLevel != OutputLevel.SILENT) {
+ if (!format.endsWith("\n")) {
+ format += "\n";
+ }
+ mLog.printf(format, args);
}
}
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java
index 938f89d9a..4e1c27ff0 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectProperties.java
@@ -47,6 +47,10 @@ public final class ProjectProperties {
mFilename = filename;
mHeader = header;
}
+
+ public String getFilename() {
+ return mFilename;
+ }
}
private final static String LOCAL_HEADER =
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/vm/VmManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/vm/VmManager.java
index 1edd8b2f8..39316d2b0 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/vm/VmManager.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/vm/VmManager.java
@@ -20,14 +20,17 @@ import com.android.prefs.AndroidLocation;
import com.android.prefs.AndroidLocation.AndroidLocationException;
import com.android.sdklib.IAndroidTarget;
import com.android.sdklib.ISdkLog;
+import com.android.sdklib.SdkConstants;
import com.android.sdklib.SdkManager;
+import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.FilenameFilter;
import java.io.IOException;
+import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@@ -42,13 +45,15 @@ public final class VmManager {
private final static String VM_INFO_PATH = "path";
private final static String VM_INFO_TARGET = "target";
-
+
private final static String IMAGE_USERDATA = "userdata.img";
private final static String CONFIG_INI = "config.ini";
-
+
private final static Pattern INI_NAME_PATTERN = Pattern.compile("(.+)\\.ini$",
Pattern.CASE_INSENSITIVE);
+ private final static Pattern SDCARD_SIZE_PATTERN = Pattern.compile("\\d+[MK]?");
+
public static final class VmInfo {
String name;
String path;
@@ -69,10 +74,12 @@ public final class VmManager {
private final ArrayList<VmInfo> mVmList = new ArrayList<VmInfo>();
private ISdkLog mSdkLog;
+ private final SdkManager mSdk;
public VmManager(SdkManager sdk, ISdkLog sdkLog) throws AndroidLocationException {
+ mSdk = sdk;
mSdkLog = sdkLog;
- buildVmList(sdk);
+ buildVmList();
}
/**
@@ -104,12 +111,12 @@ public final class VmManager {
* @param name the name of the VM
* @param target the target of the VM
* @param skinName the name of the skin. Can be null.
- * @param sdcardPath the path to the sdCard. Can be null.
- * @param sdcardSize the size of a local sdcard to create. Can be 0 for no local sdcard.
+ * @param sdcard the parameter value for the sdCard. Can be null. This is either a path to
+ * an existing sdcard image or a sdcard size (\d+, \d+K, \dM).
* @param hardwareConfig the hardware setup for the VM
*/
public VmInfo createVm(String parentFolder, String name, IAndroidTarget target,
- String skinName, String sdcardPath, int sdcardSize, Map<String,String> hardwareConfig,
+ String skinName, String sdcard, Map<String,String> hardwareConfig,
ISdkLog log) {
try {
@@ -128,7 +135,7 @@ public final class VmManager {
}
return null;
}
-
+
// create the vm folder.
vmFolder.mkdir();
@@ -177,15 +184,40 @@ public final class VmManager {
}
}
- if (sdcardPath != null) {
- File sdcard = new File(sdcardPath);
- if (sdcard.isFile()) {
- values.put("sdcard", sdcardPath);
- } else if (log != null) {
- log.warning("sdcarad image '%1$s' does not exists.", sdcardPath);
+ if (sdcard != null) {
+ File sdcardFile = new File(sdcard);
+ if (sdcardFile.isFile()) {
+ values.put("sdcard", sdcard);
+ } else {
+ // check that it matches the pattern for sdcard size
+ Matcher m = SDCARD_SIZE_PATTERN.matcher(sdcard);
+ if (m.matches()) {
+ // create the sdcard.
+ sdcardFile = new File(vmFolder, "sdcard.img");
+ String path = sdcardFile.getAbsolutePath();
+
+ // execute mksdcard with the proper parameters.
+ File toolsFolder = new File(mSdk.getLocation(), SdkConstants.FD_TOOLS);
+ File mkSdCard = new File(toolsFolder, SdkConstants.mkSdCardCmdName());
+
+ if (mkSdCard.isFile() == false) {
+ log.error(null, "'%1$s' is missing from the SDK tools folder.",
+ mkSdCard.getName());
+ return null;
+ }
+
+ if (createSdCard(mkSdCard.getAbsolutePath(), sdcard, path, log) == false) {
+ return null; // mksdcard output has already been displayed, no need to
+ // output anything else.
+ }
+
+ // add its path to the values.
+ values.put("sdcard", path);
+ } else {
+ log.error(null, "'%1$s' is not recognized as a valid sdcard value", sdcard);
+ return null;
+ }
}
- } else if (sdcardSize != 0) {
- // TODO: create sdcard image.
}
if (hardwareConfig != null) {
@@ -227,7 +259,7 @@ public final class VmManager {
return null;
}
- private void buildVmList(SdkManager sdk) throws AndroidLocationException {
+ private void buildVmList() throws AndroidLocationException {
// get the Android prefs location.
String vmRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_VMS;
@@ -253,14 +285,14 @@ public final class VmManager {
});
for (File vm : vms) {
- VmInfo info = parseVmInfo(vm, sdk);
+ VmInfo info = parseVmInfo(vm);
if (info != null) {
mVmList.add(info);
}
}
}
- private VmInfo parseVmInfo(File path, SdkManager sdk) {
+ private VmInfo parseVmInfo(File path) {
Map<String, String> map = SdkManager.parsePropertyFile(path, mSdkLog);
String vmPath = map.get(VM_INFO_PATH);
@@ -273,7 +305,7 @@ public final class VmManager {
return null;
}
- IAndroidTarget target = sdk.getTargetFromHashString(targetHash);
+ IAndroidTarget target = mSdk.getTargetFromHashString(targetHash);
if (target == null) {
return null;
}
@@ -301,4 +333,118 @@ public final class VmManager {
writer.close();
}
+
+ private boolean createSdCard(String toolLocation, String size, String location, ISdkLog log) {
+ try {
+ String[] command = new String[3];
+ command[0] = toolLocation;
+ command[1] = size;
+ command[2] = location;
+ Process process = Runtime.getRuntime().exec(command);
+
+ ArrayList<String> errorOutput = new ArrayList<String>();
+ ArrayList<String> stdOutput = new ArrayList<String>();
+ int status = grabProcessOutput(process, errorOutput, stdOutput,
+ true /* waitForReaders */);
+
+ if (status != 0) {
+ log.error(null, "Failed to create the SD card.");
+ for (String error : errorOutput) {
+ log.error(null, error);
+ }
+
+ return false;
+ }
+
+ return true;
+ } catch (InterruptedException e) {
+ log.error(null, "Failed to create the SD card.");
+ } catch (IOException e) {
+ log.error(null, "Failed to create the SD card.");
+ }
+
+ return false;
+ }
+
+ /**
+ * Gets the stderr/stdout outputs of a process and returns when the process is done.
+ * Both <b>must</b> be read or the process will block on windows.
+ * @param process The process to get the ouput from
+ * @param errorOutput The array to store the stderr output. cannot be null.
+ * @param stdOutput The array to store the stdout output. cannot be null.
+ * @param waitforReaders if true, this will wait for the reader threads.
+ * @return the process return code.
+ * @throws InterruptedException
+ */
+ private int grabProcessOutput(final Process process, final ArrayList<String> errorOutput,
+ final ArrayList<String> stdOutput, boolean waitforReaders)
+ throws InterruptedException {
+ assert errorOutput != null;
+ assert stdOutput != null;
+ // read the lines as they come. if null is returned, it's
+ // because the process finished
+ Thread t1 = new Thread("") { //$NON-NLS-1$
+ @Override
+ public void run() {
+ // create a buffer to read the stderr output
+ InputStreamReader is = new InputStreamReader(process.getErrorStream());
+ BufferedReader errReader = new BufferedReader(is);
+
+ try {
+ while (true) {
+ String line = errReader.readLine();
+ if (line != null) {
+ errorOutput.add(line);
+ } else {
+ break;
+ }
+ }
+ } catch (IOException e) {
+ // do nothing.
+ }
+ }
+ };
+
+ Thread t2 = new Thread("") { //$NON-NLS-1$
+ @Override
+ public void run() {
+ InputStreamReader is = new InputStreamReader(process.getInputStream());
+ BufferedReader outReader = new BufferedReader(is);
+
+ try {
+ while (true) {
+ String line = outReader.readLine();
+ if (line != null) {
+ stdOutput.add(line);
+ } else {
+ break;
+ }
+ }
+ } catch (IOException e) {
+ // do nothing.
+ }
+ }
+ };
+
+ t1.start();
+ t2.start();
+
+ // it looks like on windows process#waitFor() can return
+ // before the thread have filled the arrays, so we wait for both threads and the
+ // process itself.
+ if (waitforReaders) {
+ try {
+ t1.join();
+ } catch (InterruptedException e) {
+ }
+ try {
+ t2.join();
+ } catch (InterruptedException e) {
+ }
+ }
+
+ // get the return code from the process
+ return process.waitFor();
+ }
+
}