diff --git a/apps/Fallback/res/values-fr/strings.xml b/apps/Fallback/res/values-fr/strings.xml new file mode 100644 index 000000000..58c84bd8a --- /dev/null +++ b/apps/Fallback/res/values-fr/strings.xml @@ -0,0 +1,7 @@ + + + "Application de secours" + "Action non prise en charge" + "Cette action n\'est actuellement pas prise en charge." + diff --git a/apps/Fallback/res/values-it/strings.xml b/apps/Fallback/res/values-it/strings.xml new file mode 100644 index 000000000..74bef0845 --- /dev/null +++ b/apps/Fallback/res/values-it/strings.xml @@ -0,0 +1,7 @@ + + + "Fallback" + "Azione non supportata" + "L\'azione non è al momento supportata." + diff --git a/apps/Fallback/res/values-zh-rCN/strings.xml b/apps/Fallback/res/values-zh-rCN/strings.xml new file mode 100644 index 000000000..cee12211e --- /dev/null +++ b/apps/Fallback/res/values-zh-rCN/strings.xml @@ -0,0 +1,7 @@ + + + "Fallback" + "不支持的操作" + "当前不支持该操作。" + diff --git a/apps/Term/src/com/android/term/Term.java b/apps/Term/src/com/android/term/Term.java index b3bb7eef1..55cee3c2b 100644 --- a/apps/Term/src/com/android/term/Term.java +++ b/apps/Term/src/com/android/term/Term.java @@ -60,13 +60,22 @@ import java.util.ArrayList; */ public class Term extends Activity { + /** + * Set to true to add debugging code and logging. + */ + public static final boolean DEBUG = false; /** * Set to true to log each character received from the remote process to the * android log, which makes it easier to debug some kinds of problems with * emulating escape sequences and control codes. */ - public static final boolean LOG_CHARACTERS_FLAG = false; + public static final boolean LOG_CHARACTERS_FLAG = DEBUG && false; + + /** + * Set to true to log unknown escape sequences. + */ + public static final boolean LOG_UNKNOWN_ESCAPE_SEQUENCES = DEBUG && false; /** * The tag we use when logging, so that our messages can be distinguished @@ -619,7 +628,7 @@ interface Screen { * @param columns * @param rows */ - void resize(int columns, int rows); + void resize(int columns, int rows, int foreColor, int backColor); } @@ -673,7 +682,7 @@ class TranscriptScreen implements Screen { private char[] mData; /** - * The data's stored as bytes, but the drawing routines require chars, so we + * The data's stored as color-encoded chars, but the drawing routines require chars, so we * need a temporary buffer to hold a row's worth of characters. */ private char[] mRowBuffer; @@ -695,23 +704,25 @@ class TranscriptScreen implements Screen { * transcript that holds lines that have scrolled off the top of the * screen. */ - public TranscriptScreen(int columns, int totalRows, int screenRows) { - init(columns, totalRows, screenRows); + public TranscriptScreen(int columns, int totalRows, int screenRows, + int foreColor, int backColor) { + init(columns, totalRows, screenRows, foreColor, backColor); } - private void init(int columns, int totalRows, int screenRows) { + private void init(int columns, int totalRows, int screenRows, int foreColor, int backColor) { mColumns = columns; mTotalRows = totalRows; mActiveTranscriptRows = 0; mHead = 0; - mActiveRows = mScreenRows; + mActiveRows = screenRows; mScreenRows = screenRows; int totalSize = columns * totalRows; mData = new char[totalSize]; - blockSet(0, 0, mColumns, mScreenRows, ' ', 0, 7); + blockSet(0, 0, mColumns, mScreenRows, ' ', foreColor, backColor); mRowBuffer = new char[columns]; mLineWrap = new boolean[totalRows]; - } + consistencyCheck(); + } /** * Convert a row value from the public external coordinate system to our @@ -781,7 +792,7 @@ class TranscriptScreen implements Screen { // Adjust the transcript so that the last line of the transcript // is ready to receive the newly scrolled data - + consistencyCheck(); int expansionRows = Math.min(1, mTotalRows - mActiveRows); int rollRows = 1 - expansionRows; mActiveRows += expansionRows; @@ -789,6 +800,7 @@ class TranscriptScreen implements Screen { if (mActiveTranscriptRows > 0) { mHead = (mHead + rollRows) % mActiveTranscriptRows; } + consistencyCheck(); // Block move the scroll line to the transcript int topOffset = getOffset(topMargin); @@ -799,7 +811,6 @@ class TranscriptScreen implements Screen { int destLine = externalToInternalRow(-1); System.arraycopy(mLineWrap, topLine, mLineWrap, destLine, 1); - // Block move the scrolled data up int numScrollChars = (bottomMargin - topMargin - 1) * mColumns; System.arraycopy(mData, topOffset + mColumns, mData, topOffset, @@ -813,6 +824,41 @@ class TranscriptScreen implements Screen { mLineWrap[externalToInternalRow(bottomMargin-1)] = false; } + private void consistencyCheck() { + checkPositive(mColumns); + checkPositive(mTotalRows); + checkRange(0, mActiveTranscriptRows, mTotalRows); + if (mActiveTranscriptRows == 0) { + checkEqual(mHead, 0); + } else { + checkRange(0, mHead, mActiveTranscriptRows-1); + } + checkEqual(mScreenRows + mActiveTranscriptRows, mActiveRows); + checkRange(0, mScreenRows, mTotalRows); + + checkEqual(mTotalRows, mLineWrap.length); + checkEqual(mTotalRows*mColumns, mData.length); + checkEqual(mColumns, mRowBuffer.length); + } + + private void checkPositive(int n) { + if (n < 0) { + throw new IllegalArgumentException("checkPositive " + n); + } + } + + private void checkRange(int a, int b, int c) { + if (a > b || b > c) { + throw new IllegalArgumentException("checkRange " + a + " <= " + b + " <= " + c); + } + } + + private void checkEqual(int a, int b) { + if (a != b) { + throw new IllegalArgumentException("checkEqual " + a + " == " + b); + } + } + /** * Block copy characters from one position in the screen to another. The two * positions can overlap. All characters of the source and destination must @@ -872,7 +918,7 @@ class TranscriptScreen implements Screen { for (int y = 0; y < h; y++) { int offset = getOffset(sx, sy + y); for (int x = 0; x < w; x++) { - data[offset + x] = (char) val; + data[offset + x] = encodedVal; } } } @@ -954,7 +1000,7 @@ class TranscriptScreen implements Screen { return internalGetTranscriptText(true); } - public String internalGetTranscriptText(boolean stripColors) { + private String internalGetTranscriptText(boolean stripColors) { StringBuilder builder = new StringBuilder(); char[] rowBuffer = mRowBuffer; char[] data = mData; @@ -982,55 +1028,11 @@ class TranscriptScreen implements Screen { return builder.toString(); } - public void resize(int columns, int rows) { - if (columns == mColumns) { - if (rows == mScreenRows) { - return; - } - if (rows < mTotalRows) { - mScreenRows = rows; - mActiveTranscriptRows = mActiveRows - mScreenRows; - return; - } - } - // Tough case: columns size changes or need to expand rows - String transcriptText = internalGetTranscriptText(false); - int totalRows = Math.max(rows + 1, mTotalRows); - init(columns, totalRows, rows); - int length = transcriptText.length(); - - // Copy transcript into buffer - int row = 0; - char[] data = mData; - int col = 0; - for(int i = 0; i < length && row < totalRows; i++) { - char c = transcriptText.charAt(i); - if (c == '\n') { - row++; - col = 0; - } else { - if (col < columns) { - data[row * columns + col] = c; - col += 1; - } else { - if (row < totalRows-1) { - mLineWrap[row] = true; - row++; - col = 0; - data[row * columns + col] = c; - col += 1; - } else { - break; // ran out of room - } - } - } - } - mActiveRows = rows; - mActiveTranscriptRows = mActiveRows - mScreenRows; + public void resize(int columns, int rows, int foreColor, int backColor) { + init(columns, mTotalRows, rows, foreColor, backColor); } } - /** * Renders text into a screen. Contains all the terminal-specific knowlege and * state. Emulates a subset of the X Window System xterm terminal, which in turn @@ -1270,12 +1272,14 @@ class TerminalEmulator { if (mRows == rows && mColumns == columns) { return; } - mScreen.resize(columns, rows); + String transcriptText = mScreen.getTranscriptText(); + + mScreen.resize(columns, rows, mForeColor, mBackColor); + if (mRows != rows) { mRows = rows; mTopMargin = 0; mBottomMargin = mRows; - mCursorRow = Math.min(mCursorRow, mBottomMargin-1); } if (mColumns != columns) { int oldColumns = mColumns; @@ -1288,7 +1292,23 @@ class TerminalEmulator { mCursorCol -= columns; mCursorRow = Math.min(mBottomMargin-1, mCursorRow + 1); } - mAboutToAutoWrap = false; + } + mCursorRow = 0; + mCursorCol = 0; + mAboutToAutoWrap = false; + + int end = transcriptText.length()-1; + while ((end >= 0) && transcriptText.charAt(end) == '\n') { + end--; + } + for(int i = 0; i <= end; i++) { + byte c = (byte) transcriptText.charAt(i); + if (c == '\n') { + setCursorCol(0); + doLinefeed(); + } else { + emit(c); + } } } @@ -1877,7 +1897,9 @@ class TerminalEmulator { } else if (code >= 40 && code <= 47) { // background color mBackColor = (mBackColor & 0x8) | (code - 40); } else { - Log.w(Term.LOG_TAG, String.format("SGR unknown code %d", code)); + if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) { + Log.w(Term.LOG_TAG, String.format("SGR unknown code %d", code)); + } } } } @@ -2030,52 +2052,59 @@ class TerminalEmulator { } private void unimplementedSequence(byte b) { - logError("unimplemented", b); + if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) { + logError("unimplemented", b); + } finishSequence(); } private void unknownSequence(byte b) { - logError("unknown", b); - + if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) { + logError("unknown", b); + } finishSequence(); } private void unknownParameter(int parameter) { - // We could log that we didn't recognize parameter. - StringBuilder buf = new StringBuilder(); - buf.append("Unknown parameter"); - buf.append(parameter); - logError(buf.toString()); + if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) { + StringBuilder buf = new StringBuilder(); + buf.append("Unknown parameter"); + buf.append(parameter); + logError(buf.toString()); + } } private void logError(String errorType, byte b) { - // We could log that we didn't recognize character b. - StringBuilder buf = new StringBuilder(); - buf.append(errorType); - buf.append(" sequence "); - buf.append(" EscapeState: "); - buf.append(mEscapeState); - buf.append(" char: '"); - buf.append((char) b); - buf.append("' ("); - buf.append((int) b); - buf.append(")"); - boolean firstArg = true; - for (int i = 0; i <= mArgIndex; i++) { - int value = mArgs[i]; - if (value >= 0) { - if (firstArg) { - firstArg = false; - buf.append("args = "); + if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) { + StringBuilder buf = new StringBuilder(); + buf.append(errorType); + buf.append(" sequence "); + buf.append(" EscapeState: "); + buf.append(mEscapeState); + buf.append(" char: '"); + buf.append((char) b); + buf.append("' ("); + buf.append((int) b); + buf.append(")"); + boolean firstArg = true; + for (int i = 0; i <= mArgIndex; i++) { + int value = mArgs[i]; + if (value >= 0) { + if (firstArg) { + firstArg = false; + buf.append("args = "); + } + buf.append(String.format("%d; ", value)); } - buf.append(String.format("%d; ", value)); } + logError(buf.toString()); } - logError(buf.toString()); } private void logError(String error) { - Log.e(Term.LOG_TAG, error); + if (Term.LOG_UNKNOWN_ESCAPE_SEQUENCES) { + Log.e(Term.LOG_TAG, error); + } finishSequence(); } @@ -2848,7 +2877,7 @@ class EmulatorView extends View implements GestureDetector.OnGestureListener { mEmulator.updateSize(mColumns, mRows); } else { mTranscriptScreen = - new TranscriptScreen(mColumns, TRANSCRIPT_ROWS, mRows); + new TranscriptScreen(mColumns, TRANSCRIPT_ROWS, mRows, 0, 7); mEmulator = new TerminalEmulator(mTranscriptScreen, mColumns, mRows, mTermOut); diff --git a/build/sdk.atree b/build/sdk.atree index 2df42bc8d..f12a30c0b 100644 --- a/build/sdk.atree +++ b/build/sdk.atree @@ -50,11 +50,10 @@ development/tools/scripts/java_tests_file.template platforms/${PLATFORM_NAME}/te development/tools/scripts/layout.template platforms/${PLATFORM_NAME}/templates/layout.template development/tools/scripts/strings.template platforms/${PLATFORM_NAME}/templates/strings.template development/tools/scripts/alias.template platforms/${PLATFORM_NAME}/templates/alias.template +development/tools/scripts/android_rules.xml platforms/${PLATFORM_NAME}/templates/android_rules.xml +development/tools/scripts/alias_rules.xml platforms/${PLATFORM_NAME}/templates/alias_rules.xml development/tools/scripts/build.template tools/lib/build.template development/tools/scripts/build.alias.template tools/lib/build.alias.template -development/tools/scripts/default.properties.template tools/lib/default.properties.template -development/tools/scripts/android_rules.xml tools/lib/android_rules.xml -development/tools/scripts/alias_rules.xml tools/lib/alias_rules.xml # emacs support development/tools/scripts/android.el tools/lib/android.el @@ -116,6 +115,7 @@ framework/traceview.jar tools/lib/traceview.jar # activitycreator bin/activitycreator tools/activitycreator framework/activitycreator.jar tools/lib/activitycreator.jar +framework/anttasks.jar tools/lib/anttasks.jar # sdkmanager bin/android tools/android diff --git a/emulator/qtools/dmtrace.cpp b/emulator/qtools/dmtrace.cpp index 3efc10a53..66e12a85e 100644 --- a/emulator/qtools/dmtrace.cpp +++ b/emulator/qtools/dmtrace.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include #include diff --git a/pdk/Pdk.mk b/pdk/Pdk.mk index cc458bc4a..88fedf572 100644 --- a/pdk/Pdk.mk +++ b/pdk/Pdk.mk @@ -14,13 +14,181 @@ # limitations under the License. # -# Assemble the Platform Development Kit +# Assemble the Platform Development Kit (PDK) +# (TODO) Figure out why $(ACP) builds with target ndk but not pdk_docs +# (TODO) Copy over index.html from templates instead of from generatedDocs +# (TODO) Build doxygen (depend on latest version) -pdk: ndk - @echo "Package: $@" +pdk: + @echo "Package: $@ has targets ndk, pdk_docs and pdk_all" -LOCAL_PATH := $(my-dir) +pdk_all: ndk pdk_docs + @echo "Package: $^" +LOCAL_PATH := $(call my-dir) + +#------------------------------------------------------------------------------- +# Make the Native Development Kit (Code examples) +# Allows vendors to build shared libraries without entire source tree. +# This include adds /ndk to LOCAL_PATH, so can't use it afterwards... include $(LOCAL_PATH)/ndk/Ndk.mk +#------------------------------------------------------------------------------- +# Make the Plaftorm Development Kit Documentation. +# Doxygenize the header files to create html docs in the generatedDocs dir. +# Copy the template files and the generated html to the docs dir and zip +# everything up to the distribution directory. + + +# Workspace directory +pdk_docs_intermediates := $(call intermediates-dir-for,PACKAGING,pdkdocs) + +# Source directories for templates, config & header files +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_camera_dir := frameworks/base/include/ui + +# Destination directory for docs (templates + doxygenated headers) +pdk_docs_dest_dir := $(pdk_docs_intermediates)/docs + +# Working directory for source to be doxygenated +pdk_doxy_source_dir := $(pdk_docs_intermediates)/sources + +# Working directory for html, et al. after doxygination +pdk_generated_source_dir := $(pdk_docs_intermediates)/generatedDocs/html + +# Working directory for .dox files +pdk_doxy_docsfiles_dir := $(pdk_docs_intermediates)/docsfiles + +# Doxygen version to use, so we can override it on the command line +# doxygen 1.4.6 working, the latest version get-apt installable on goobuntu. +# (TODO) doxygen 1.5.6 generated source files not displayable +# doxygen_version='~pubengdocs/shared/doxy/doxygen.1.5.6.kcc' +# for latest version of doxygen on linux +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_camera_dir)/CameraHardwareInterface.h + +# Create a rule to copy the list of PDK headers to be doxyginated. +# copy-one-header defines the actual rule. +$(foreach header,$(pdk_headers), \ + $(eval _chFrom := $(header)) \ + $(eval _chTo := $(pdk_doxy_source_dir)/$(notdir $(header))) \ + $(eval $(call copy-one-header,$(_chFrom),$(_chTo))) \ + $(eval all_copied_pdk_headers: $(_chTo)) \ + ) +_chFrom := +_chTo := + + +#------------------------------------------------------------------------------- +# Assemble all the necessary doxygen config files and the sources into the +# working directories + +pdk_templates := $(shell find $(pdk_templates_dir) -type f) + +# Create a rule to copy the list of PDK doc templates. +# copy-one-file defines the actual rule. +$(foreach template,$(pdk_templates), \ + $(eval _chFrom := $(template)) \ + $(eval _chTo := $(pdk_docs_dest_dir)/$(notdir $(template))) \ + $(eval $(call copy-one-header,$(_chFrom),$(_chTo))) \ + $(eval all_copied_pdk_templates: $(_chTo)) \ + ) +_chFrom := +_chTo := + +# Copy newer doxygen config file (basic configs, should not change very often.) +pdk_doxygen_config_file := $(pdk_docs_intermediates)/pdk_config.conf +$(pdk_doxygen_config_file): $(pdk_config_dir)/pdk_config.conf + @echo "PDK: $@" + $(copy-file-to-target-with-cp) + +# Copy newer doxygen override config file (may change these more often.) +pdk_doxygen_config_override_file := $(pdk_docs_intermediates)/overrideconfig.conf +$(pdk_doxygen_config_override_file): $(pdk_config_dir)/overrideconfig.conf + @echo "PDK: $@" + $(copy-file-to-target-with-cp) + +# (TODO) Get the latest templates +# Copy newer doxygen html files. +$(pdk_docs_intermediates)/header.html: $(pdk_config_dir)/header.html + @echo "PDK: $@" + $(copy-file-to-target-with-cp) + +$(pdk_docs_intermediates)/footer.html: $(pdk_config_dir)/footer.html + @echo "PDK: $@" + $(copy-file-to-target-with-cp) + +# Copy newer doxygen .dox files +$(pdk_doxy_docsfiles_dir)/groups.dox: $(pdk_docsfile_dir)/groups.dox + @echo "PDK: $@" + $(copy-file-to-target-with-cp) + +$(pdk_doxy_docsfiles_dir)/main.dox: $(pdk_docsfile_dir)/main.dox + @echo "PDK: $@" + $(copy-file-to-target-with-cp) + +# Run doxygen and copy all output and templates to the final destination +# We replace index.html with a template file so don't use the generated one +pdk_doxygen: all_copied_pdk_headers $(pdk_doxygen_config_override_file) \ + $(pdk_doxygen_config_file) $(pdk_docs_intermediates)/header.html \ + $(pdk_docs_intermediates)/footer.html $(pdk_doxy_docsfiles_dir)/groups.dox \ + $(pdk_doxy_docsfiles_dir)/main.dox + @echo "Files for Doxygination: $^" + @mkdir -p $(pdk_generated_source_dir) + @rm -f $(pdk_generated_source_dir)/* + @cd $(pdk_docs_intermediates) && $(doxygen_version) pdk_config.conf + @mkdir -p $(pdk_docs_dest_dir) + @cd $(pdk_generated_source_dir) && chmod ug+rx * + @rm -f $(pdk_generated_source_dir)/index.html + @cp -fp $(pdk_generated_source_dir)/* $(pdk_docs_dest_dir) + +# Name the tar files +name := android_pdk_docs-$(REQUESTED_PRODUCT) +ifeq ($(TARGET_BUILD_TYPE),debug) + name := $(name)_debug +endif +name := $(name)-$(BUILD_NUMBER) +pdk_docs_tarfile := $(pdk_docs_intermediates)/$(name).tar +pdk_docs_tarfile_zipped := $(pdk_docs_tarfile).gz + +.PHONY: pdk pdk_docs pdk_doxygen all_copied_pdk_headers all_copied_pdk_templates + +pdk_docs: $(pdk_docs_tarfile_zipped) + @echo "PDK: Docs tarred and zipped" + +# Put the pdk_docs zip files in the distribution directory +$(call dist-for-goals,pdk_docs,$(pdk_docs_tarfile_zipped)) + +# zip up tar files +%.tar.gz: %.tar + @echo "PDK: zipped $<" + $(hide) gzip -cf $< > $@ + +# tar up all the files to make the pdk docs. +$(pdk_docs_tarfile): pdk_doxygen all_copied_pdk_templates + @echo "PDK: $@" + @mkdir -p $(dir $@) + @rm -f $@ + $(hide) tar rf $@ -C $(pdk_docs_intermediates) docs + +# Debugging reporting can go here, add it as a target to get output. +pdk_debug: + @echo "You are here: $@" + @echo "pdk headers copied: $(all_copied_pdk_headers)" + @echo "pdk headers: $(pdk_headers)" + @echo "pdk docs dest: $(pdk_docs_dest_dir)" + @echo "config dest: $(pdk_doxygen_config_file)" + @echo "config src: $(pdk_config_dir)/pdk_config.conf" + @echo "pdk templates: $(pdk_templates_dir)" diff --git a/pdk/README b/pdk/README index b382a1050..ab923becf 100644 --- a/pdk/README +++ b/pdk/README @@ -1,4 +1,4 @@ -Building the pdk +Building the pdk (platform development kit) 1) get a cupcake source tree @@ -54,9 +54,15 @@ Building the pdk (which contains: DT=`date +%y%m%d-%H%M%S` -#time make -j4 PRODUCT-generic-eng pdk dist DIST_DIR=dist 2>&1 | tee logs/$DT -time make -j4 pdk dist DIST_DIR=dist 2>&1 | tee logs/$DT +time make -j4 pdk pdk_all dist DIST_DIR=dist 2>&1 | tee logs/$DT so you can see the results of the build in the logs directory.) 5) the pdk tar file is put in the dist directory. + + +The build target 'pdk' brings in the pdk/ndk make files into the build system. + Then there are three targets: + 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 diff --git a/pdk/docs/_audio_hardware_interface_8h-source.html b/pdk/docs/_audio_hardware_interface_8h-source.html deleted file mode 100755 index 799b827d3..000000000 --- a/pdk/docs/_audio_hardware_interface_8h-source.html +++ /dev/null @@ -1,268 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -

AudioHardwareInterface.h

Go to the documentation of this file.
00001 /*
-00002  * Copyright (C) 2007 The Android Open Source Project
-00003  *
-00004  * Licensed under the Apache License, Version 2.0 (the "License");
-00005  * you may not use this file except in compliance with the License.
-00006  * You may obtain a copy of the License at
-00007  *
-00008  *      http://www.apache.org/licenses/LICENSE-2.0
-00009  *
-00010  * Unless required by applicable law or agreed to in writing, software
-00011  * distributed under the License is distributed on an "AS IS" BASIS,
-00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-00013  * See the License for the specific language governing permissions and
-00014  * limitations under the License.
-00015  */
-00016 
-00017 #ifndef ANDROID_AUDIO_HARDWARE_INTERFACE_H
-00018 #define ANDROID_AUDIO_HARDWARE_INTERFACE_H
-00019 
-00020 #include <stdint.h>
-00021 #include <sys/types.h>
-00022 
-00023 #include <utils/Errors.h>
-00024 #include <utils/Vector.h>
-00025 #include <utils/String16.h>
-00026 
-00027 #include <media/IAudioFlinger.h>
-00028 #include "media/AudioSystem.h"
-00029 
-00030 
-00031 namespace android {
-00032 
-00033 // ----------------------------------------------------------------------------
-00034 
-00035 /**
-00036  * AudioStreamOut is the abstraction interface for the audio output hardware.
-00037  *
-00038  * It provides information about various properties of the audio output hardware driver.
-00039  */
-00040 class AudioStreamOut {
-00041 public:
-00042     virtual             ~AudioStreamOut() = 0;
-00043 
-00044     /** return audio sampling rate in hz - eg. 44100 */
-00045     virtual uint32_t    sampleRate() const = 0;
-00046 
-00047     /** returns size of output buffer - eg. 4800 */
-00048     virtual size_t      bufferSize() const = 0;
-00049 
-00050     /**
-00051      * return number of output audio channels.
-00052      * Acceptable values are 1 (mono) or 2 (stereo)
-00053      */
-00054     virtual int         channelCount() const = 0;
-00055 
-00056     /**
-00057      * return audio format in 8bit or 16bit PCM format -
-00058      * eg. AudioSystem:PCM_16_BIT
-00059      */
-00060     virtual int         format() const = 0;
-00061 
-00062     /**
-00063      * return the frame size (number of bytes per sample).
-00064      */
-00065     uint32_t    frameSize() const { return channelCount()*((format()==AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(int8_t)); }
-00066 
-00067     /**
-00068      * return the audio hardware driver latency in milli seconds.
-00069      */
-00070     virtual uint32_t    latency() const = 0;
-00071 
-00072     /**
-00073      * Use this method in situations where audio mixing is done in the
-00074      * hardware. This method serves as a direct interface with hardware,
-00075      * allowing you to directly set the volume as apposed to via the framework.
-00076      * This method might produce multiple PCM outputs or hardware accelerated
-00077      * codecs, such as MP3 or AAC.
-00078      */
-00079     virtual status_t    setVolume(float volume) = 0;
-00080 
-00081     /** write audio buffer to driver. Returns number of bytes written */
-00082     virtual ssize_t     write(const void* buffer, size_t bytes) = 0;
-00083 
-00084     /** dump the state of the audio output device */
-00085     virtual status_t dump(int fd, const Vector<String16>& args) = 0;
-00086 };
-00087 
-00088 /**
-00089  * AudioStreamIn is the abstraction interface for the audio input hardware.
-00090  *
-00091  * It defines the various properties of the audio hardware input driver.
-00092  */
-00093 class AudioStreamIn {
-00094 public:
-00095     virtual             ~AudioStreamIn() = 0;
-00096 
-00097     /** return the input buffer size allowed by audio driver */
-00098     virtual size_t      bufferSize() const = 0;
-00099 
-00100     /** return the number of audio input channels */
-00101     virtual int         channelCount() const = 0;
-00102 
-00103     /**
-00104      * return audio format in 8bit or 16bit PCM format -
-00105      * eg. AudioSystem:PCM_16_BIT
-00106      */
-00107     virtual int         format() const = 0;
-00108 
-00109     /**
-00110      * return the frame size (number of bytes per sample).
-00111      */
-00112     uint32_t    frameSize() const { return channelCount()*((format()==AudioSystem::PCM_16_BIT)?sizeof(int16_t):sizeof(int8_t)); }
-00113 
-00114     /** set the input gain for the audio driver. This method is for
-00115      *  for future use */
-00116     virtual status_t    setGain(float gain) = 0;
-00117 
-00118     /** read audio buffer in from audio driver */
-00119     virtual ssize_t     read(void* buffer, ssize_t bytes) = 0;
-00120 
-00121     /** dump the state of the audio input device */
-00122     virtual status_t dump(int fd, const Vector<String16>& args) = 0;
-00123 
-00124     /**
-00125      * Put the audio hardware input into standby mode. Returns
-00126      * status based on include/utils/Errors.h
-00127      */
-00128     virtual status_t    standby() = 0;
-00129 
-00130 };
-00131 
-00132 /**
-00133  * AudioHardwareInterface.h defines the interface to the audio hardware abstraction layer.
-00134  *
-00135  * The interface supports setting and getting parameters, selecting audio routing
-00136  * paths, and defining input and output streams.
-00137  *
-00138  * AudioFlinger initializes the audio hardware and immediately opens an output stream.
-00139  * You can set Audio routing to output to handset, speaker, Bluetooth, or a headset.
-00140  *
-00141  * The audio input stream is initialized when AudioFlinger is called to carry out
-00142  * a record operation.
-00143  */
-00144 class AudioHardwareInterface
-00145 {
-00146 public:
-00147     /**
-00148      * check to see if the audio hardware interface has been initialized.
-00149      * return status based on values defined in include/utils/Errors.h
-00150      */
-00151     virtual status_t    initCheck() = 0;
-00152 
-00153     /**
-00154      * put the audio hardware into standby mode to conserve power. Returns
-00155      * status based on include/utils/Errors.h
-00156      */
-00157     virtual status_t    standby() = 0;
-00158 
-00159     /** set the audio volume of a voice call. Range is between 0.0 and 1.0 */
-00160     virtual status_t    setVoiceVolume(float volume) = 0;
-00161 
-00162     /**
-00163      * set the audio volume for all audio activities other than voice call.
-00164      * Range between 0.0 and 1.0. If any value other than NO_ERROR is returned,
-00165      * the software mixer will emulate this capability.
-00166      */
-00167     virtual status_t    setMasterVolume(float volume) = 0;
-00168 
-00169     /**
-00170      * Audio routing methods. Routes defined in include/hardware/AudioSystem.h.
-00171      * Audio routes can be (ROUTE_EARPIECE | ROUTE_SPEAKER | ROUTE_BLUETOOTH
-00172      *                    | ROUTE_HEADSET)
-00173      *
-00174      * setRouting sets the routes for a mode. This is called at startup. It is
-00175      * also called when a new device is connected, such as a wired headset is
-00176      * plugged in or a Bluetooth headset is paired.
-00177      */
-00178     virtual status_t    setRouting(int mode, uint32_t routes) = 0;
-00179 
-00180     virtual status_t    getRouting(int mode, uint32_t* routes) = 0;
-00181 
-00182     /**
-00183      * setMode is called when the audio mode changes. NORMAL mode is for
-00184      * standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL
-00185      * when a call is in progress.
-00186      */
-00187     virtual status_t    setMode(int mode) = 0;
-00188     virtual status_t    getMode(int* mode) = 0;
-00189 
-00190     // mic mute
-00191     virtual status_t    setMicMute(bool state) = 0;
-00192     virtual status_t    getMicMute(bool* state) = 0;
-00193 
-00194     // Temporary interface, do not use
-00195     // TODO: Replace with a more generic key:value get/set mechanism
-00196     virtual status_t    setParameter(const char* key, const char* value) = 0;
-00197 
-00198     // Returns audio input buffer size according to parameters passed or 0 if one of the
-00199     // parameters is not supported
-00200     virtual size_t    getInputBufferSize(uint32_t sampleRate, int format, int channelCount) = 0;
-00201     
-00202     /** This method creates and opens the audio hardware output stream */
-00203     virtual AudioStreamOut* openOutputStream(
-00204                                 int format=0,
-00205                                 int channelCount=0,
-00206                                 uint32_t sampleRate=0,
-00207                                 status_t *status=0) = 0;
-00208 
-00209     /** This method creates and opens the audio hardware input stream */
-00210     virtual AudioStreamIn* openInputStream(
-00211                                 int format,
-00212                                 int channelCount,
-00213                                 uint32_t sampleRate,
-00214                                 status_t *status) = 0;
-00215 
-00216     /**This method dumps the state of the audio hardware */
-00217     virtual status_t dumpState(int fd, const Vector<String16>& args) = 0;
-00218 
-00219     static AudioHardwareInterface* create();
-00220 
-00221 protected:
-00222     /**
-00223      * doRouting actually initiates the routing. A call to setRouting
-00224      * or setMode may result in a routing change. The generic logic calls
-00225      * doRouting when required. If the device has any special requirements these
-00226      * methods can be overriden.
-00227      */
-00228     virtual status_t    doRouting() = 0;
-00229 
-00230     virtual status_t dump(int fd, const Vector<String16>& args) = 0;
-00231 };
-00232 
-00233 // ----------------------------------------------------------------------------
-00234 
-00235 extern "C" AudioHardwareInterface* createAudioHardware(void);
-00236 
-00237 }; // namespace android
-00238 
-00239 #endif // ANDROID_AUDIO_HARDWARE_INTERFACE_H
-
- - diff --git a/pdk/docs/_audio_hardware_interface_8h.html b/pdk/docs/_audio_hardware_interface_8h.html deleted file mode 100755 index f45379f83..000000000 --- a/pdk/docs/_audio_hardware_interface_8h.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

AudioHardwareInterface.h File Reference

-

-Go to the source code of this file. - - - - - - - - - - - - - - - - - -

Namespaces

namespace  android

Data Structures

class  android::AudioStreamOut
 AudioStreamOut is the abstraction interface for the audio output hardware. More...
class  android::AudioStreamIn
 AudioStreamIn is the abstraction interface for the audio input hardware. More...
class  android::AudioHardwareInterface
 AudioHardwareInterface.h defines the interface to the audio hardware abstraction layer. More...

Functions

AudioHardwareInterface * android::createAudioHardware (void)
-

- - diff --git a/pdk/docs/_camera_hardware_interface_8h-source.html b/pdk/docs/_camera_hardware_interface_8h-source.html deleted file mode 100755 index 41f0a1df3..000000000 --- a/pdk/docs/_camera_hardware_interface_8h-source.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -

CameraHardwareInterface.h

Go to the documentation of this file.
00001 /*
-00002  * Copyright (C) 2008 The Android Open Source Project
-00003  *
-00004  * Licensed under the Apache License, Version 2.0 (the "License");
-00005  * you may not use this file except in compliance with the License.
-00006  * You may obtain a copy of the License at
-00007  *
-00008  *      http://www.apache.org/licenses/LICENSE-2.0
-00009  *
-00010  * Unless required by applicable law or agreed to in writing, software
-00011  * distributed under the License is distributed on an "AS IS" BASIS,
-00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-00013  * See the License for the specific language governing permissions and
-00014  * limitations under the License.
-00015  */
-00016 
-00017 #ifndef ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
-00018 #define ANDROID_HARDWARE_CAMERA_HARDWARE_INTERFACE_H
-00019 
-00020 #include <utils/IMemory.h>
-00021 #include <utils/RefBase.h>
-00022 #include <ui/CameraParameters.h>
-00023 
-00024 namespace android {
-00025 
-00026 /** Callback for startPreview() */
-00027 typedef void (*preview_callback)(const sp<IMemory>& mem, void* user);
-00028 
-00029 /** Callback for takePicture() */
-00030 typedef void (*shutter_callback)(void* user);
-00031 
-00032 /** Callback for takePicture() */
-00033 typedef void (*raw_callback)(const sp<IMemory>& mem, void* user);
-00034 
-00035 /** Callback for takePicture() */
-00036 typedef void (*jpeg_callback)(const sp<IMemory>& mem, void* user);
-00037 
-00038 /** Callback for autoFocus() */
-00039 typedef void (*autofocus_callback)(bool focused, void* user);
-00040 
-00041 /**
-00042  * CameraHardwareInterface.h defines the interface to the
-00043  * camera hardware abstraction layer, used for setting and getting
-00044  * parameters, live previewing, and taking pictures.
-00045  *
-00046  * It is a referenced counted interface with RefBase as its base class.
-00047  * CameraService calls openCameraHardware() to retrieve a strong pointer to the
-00048  * instance of this interface and may be called multiple times. The
-00049  * following steps describe a typical sequence:
-00050  *
-00051  *   -# After CameraService calls openCameraHardware(), getParameters() and
-00052  *      setParameters() are used to initialize the camera instance.
-00053  *      CameraService calls getPreviewHeap() to establish access to the
-00054  *      preview heap so it can be registered with SurfaceFlinger for
-00055  *      efficient display updating while in preview mode.
-00056  *   -# startPreview() is called, which is passed a preview_callback()
-00057  *      function and a user parameter. The camera instance then periodically
-00058  *      calls preview_callback() each time a new preview frame is available.
-00059  *      The callback routine has two parameters: the first is a pointer to
-00060  *      the IMemory containing the frame and the second a user parameter. If
-00061  *      the preview_callback code needs to use this memory after returning,
-00062  *      it must copy the data.
-00063  *
-00064  * Prior to taking a picture, CameraService calls autofocus() with
-00065  * autofocus_callback() and a user parameter. When auto focusing has
-00066  * completed, the camera instance calls autofocus_callback(), which informs
-00067  * the application whether focusing was successful. The camera instance
-00068  * only calls autofocus_callback() once and it is up to the application to
-00069  * call autoFocus() again if refocusing is desired.
-00070  *
-00071  * CameraService calls takePicture() to request the camera instance take a
-00072  * picture. This method has two callbacks: raw_callback() and jpeg_callback().
-00073  * When the raw image is available, raw_callback() is called with a pointer
-00074  * to the IMemory containing the raw image. When the jpeg image is available,
-00075  * jpeg_callback() is called with a pointer to the IMemory containing the
-00076  * jpeg image. As with preview_callback(), the memory must be copied if it's
-00077  * needed after returning.
-00078  */
-00079 class CameraHardwareInterface : public virtual RefBase {
-00080 public:
-00081     virtual ~CameraHardwareInterface() { }
-00082 
-00083     /** Return the IMemoryHeap for the preview image heap */
-00084     virtual sp<IMemoryHeap>         getPreviewHeap() const = 0;
-00085 
-00086     /**
-00087      * Start preview mode. When a preview image is available
-00088      * preview_callback is called with the user parameter. The
-00089      * call back parameter may be null.
-00090      */
-00091     virtual status_t    startPreview(preview_callback cb, void* user) = 0;
-00092 
-00093     /**
-00094      * Stop a previously started preview.
-00095      */
-00096     virtual void        stopPreview() = 0;
-00097 
-00098     /**
-00099      * Start auto focus, the callback routine is called
-00100      * once when focusing is complete. autoFocus() will
-00101      * be called again if another auto focus is needed.
-00102      */
-00103     virtual status_t    autoFocus(autofocus_callback,
-00104                                   void* user) = 0;
-00105 
-00106     /**
-00107      * Take a picture. The raw_callback is called when
-00108      * the uncompressed image is available. The jpeg_callback
-00109      * is called when the compressed image is available. These
-00110      * call backs may be null. The user parameter is passed
-00111      * to each of the call back routines.
-00112      */
-00113     virtual status_t    takePicture(shutter_callback,
-00114                                     raw_callback,
-00115                                     jpeg_callback,
-00116                                     void* user) = 0;
-00117 
-00118     /**
-00119      * Cancel a picture that was started with takePicture.  You may cancel any
-00120      * of the shutter, raw, or jpeg callbacks.  Calling this method when no
-00121      * picture is being taken is a no-op.
-00122      */
-00123     virtual status_t    cancelPicture(bool cancel_shutter,
-00124                                       bool cancel_raw,
-00125                                       bool cancel_jpeg) = 0;
-00126 
-00127     /** Set the camera parameters. */
-00128     virtual status_t    setParameters(const CameraParameters& params) = 0;
-00129 
-00130     /** Return the camera parameters. */
-00131     virtual CameraParameters  getParameters() const = 0;
-00132 
-00133     /**
-00134      * Release the hardware resources owned by this object.  Note that this is
-00135      * *not* done in the destructor.
-00136      */
-00137     virtual void release() = 0;
-00138     
-00139     /**
-00140      * Dump state of the camera hardware
-00141      */
-00142     virtual status_t dump(int fd, const Vector<String16>& args) const = 0;
-00143 };
-00144 
-00145 /** factory function to instantiate a camera hardware object */
-00146 extern "C" sp<CameraHardwareInterface> openCameraHardware();
-00147 
-00148 };  // namespace android
-00149 
-00150 #endif
-
- - diff --git a/pdk/docs/_camera_hardware_interface_8h.html b/pdk/docs/_camera_hardware_interface_8h.html deleted file mode 100755 index 633461ff5..000000000 --- a/pdk/docs/_camera_hardware_interface_8h.html +++ /dev/null @@ -1,62 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

CameraHardwareInterface.h File Reference

-

-Go to the source code of this file. - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Namespaces

namespace  android

Data Structures

class  android::CameraHardwareInterface
 CameraHardwareInterface.h defines the interface to the camera hardware abstraction layer, used for setting and getting parameters, live previewing, and taking pictures. More...

Typedefs

typedef void(* android::preview_callback )(const sp< IMemory > &mem, void *user)
 Callback for startPreview().
typedef void(* android::shutter_callback )(void *user)
 Callback for takePicture().
typedef void(* android::raw_callback )(const sp< IMemory > &mem, void *user)
 Callback for takePicture().
typedef void(* android::jpeg_callback )(const sp< IMemory > &mem, void *user)
 Callback for takePicture().
typedef void(* android::autofocus_callback )(bool focused, void *user)
 Callback for autoFocus().

Functions

sp< CameraHardwareInterface > android::openCameraHardware ()
 factory function to instantiate a camera hardware object
-

- - diff --git a/pdk/docs/annotated.html b/pdk/docs/annotated.html deleted file mode 100755 index c8ea2e2d7..000000000 --- a/pdk/docs/annotated.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

Data Structures

Here are the data structures with brief descriptions: - - - - - - - - - - - - - -
android::AudioHardwareInterfaceAudioHardwareInterface.h defines the interface to the audio hardware abstraction layer
android::AudioStreamInAudioStreamIn is the abstraction interface for the audio input hardware
android::AudioStreamOutAudioStreamOut is the abstraction interface for the audio output hardware
android::CameraHardwareInterfaceCameraHardwareInterface.h defines the interface to the camera hardware abstraction layer, used for setting and getting parameters, live previewing, and taking pictures
GpsCallbacksGPS callback structure
GpsInterfaceRepresents the standard GPS interface
GpsLocationRepresents a location
GpsStatusRepresents the status
GpsSuplInterfaceExtended interface for SUPL support
GpsSvInfoRepresents SV information
GpsSvStatusRepresents SV status
GpsXtraCallbacksCallback structure for the XTRA interface
GpsXtraInterfaceExtended interface for XTRA support
-
- - diff --git a/pdk/docs/audio_sub_system.html b/pdk/docs/audio_sub_system.html index e0cf2173d..8639cf0b1 100755 --- a/pdk/docs/audio_sub_system.html +++ b/pdk/docs/audio_sub_system.html @@ -227,7 +227,7 @@ include $(BUILD_SHARED_LIBRARY)

Note: This document relies on some Doxygen-generated content that appears in an iFrame below. To return to the Doxygen default content for this page, click here.

- +

diff --git a/pdk/docs/camera.html b/pdk/docs/camera.html index ae44b6806..1b6565984 100755 --- a/pdk/docs/camera.html +++ b/pdk/docs/camera.html @@ -246,7 +246,7 @@ include $(BUILD_SHARED_LIBRARY)

Note: This document relies on some Doxygen-generated content that appears in an iFrame below. To return to the Doxygen default content for this page, click here.

- +

diff --git a/pdk/docs/classandroid_1_1_audio_hardware_interface.html b/pdk/docs/classandroid_1_1_audio_hardware_interface.html deleted file mode 100755 index d2e9ac884..000000000 --- a/pdk/docs/classandroid_1_1_audio_hardware_interface.html +++ /dev/null @@ -1,584 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - -

-
-

android::AudioHardwareInterface Class Reference

AudioHardwareInterface.h defines the interface to the audio hardware abstraction layer. -More... -

-#include <AudioHardwareInterface.h> -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Public Member Functions

virtual status_t initCheck ()=0
 check to see if the audio hardware interface has been initialized.
virtual status_t standby ()=0
 put the audio hardware into standby mode to conserve power.
virtual status_t setVoiceVolume (float volume)=0
 set the audio volume of a voice call.
virtual status_t setMasterVolume (float volume)=0
 set the audio volume for all audio activities other than voice call.
virtual status_t setRouting (int mode, uint32_t routes)=0
 Audio routing methods.
virtual status_t getRouting (int mode, uint32_t *routes)=0
virtual status_t setMode (int mode)=0
 setMode is called when the audio mode changes.
virtual status_t getMode (int *mode)=0
virtual status_t setMicMute (bool state)=0
virtual status_t getMicMute (bool *state)=0
virtual status_t setParameter (const char *key, const char *value)=0
virtual size_t getInputBufferSize (uint32_t sampleRate, int format, int channelCount)=0
virtual AudioStreamOutopenOutputStream (int format=0, int channelCount=0, uint32_t sampleRate=0, status_t *status=0)=0
 This method creates and opens the audio hardware output stream.
virtual AudioStreamInopenInputStream (int format, int channelCount, uint32_t sampleRate, status_t *status)=0
 This method creates and opens the audio hardware input stream.
virtual status_t dumpState (int fd, const Vector< String16 > &args)=0
 This method dumps the state of the audio hardware.

Static Public Member Functions

static AudioHardwareInterfacecreate ()

Protected Member Functions

virtual status_t doRouting ()=0
 doRouting actually initiates the routing.
virtual status_t dump (int fd, const Vector< String16 > &args)=0
-


Detailed Description

-AudioHardwareInterface.h defines the interface to the audio hardware abstraction layer. -

-The interface supports setting and getting parameters, selecting audio routing paths, and defining input and output streams.

-AudioFlinger initializes the audio hardware and immediately opens an output stream. You can set Audio routing to output to handset, speaker, Bluetooth, or a headset.

-The audio input stream is initialized when AudioFlinger is called to carry out a record operation. -

Definition at line 144 of file AudioHardwareInterface.h.

-

Member Function Documentation

- -
-
- - - - - - - - -
virtual status_t android::AudioHardwareInterface::initCheck (  )  [pure virtual]
-
-
- -

-check to see if the audio hardware interface has been initialized. -

-return status based on values defined in include/utils/Errors.h -

-

- -

-
- - - - - - - - -
virtual status_t android::AudioHardwareInterface::standby (  )  [pure virtual]
-
-
- -

-put the audio hardware into standby mode to conserve power. -

-Returns status based on include/utils/Errors.h -

-

- -

-
- - - - - - - - - -
virtual status_t android::AudioHardwareInterface::setVoiceVolume (float  volume  )  [pure virtual]
-
-
- -

-set the audio volume of a voice call. -

-Range is between 0.0 and 1.0 -

-

- -

-
- - - - - - - - - -
virtual status_t android::AudioHardwareInterface::setMasterVolume (float  volume  )  [pure virtual]
-
-
- -

-set the audio volume for all audio activities other than voice call. -

-Range between 0.0 and 1.0. If any value other than NO_ERROR is returned, the software mixer will emulate this capability. -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::AudioHardwareInterface::setRouting (int  mode,
uint32_t  routes 
) [pure virtual]
-
-
- -

-Audio routing methods. -

-Routes defined in include/hardware/AudioSystem.h. Audio routes can be (ROUTE_EARPIECE | ROUTE_SPEAKER | ROUTE_BLUETOOTH | ROUTE_HEADSET)

-setRouting sets the routes for a mode. This is called at startup. It is also called when a new device is connected, such as a wired headset is plugged in or a Bluetooth headset is paired. -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::AudioHardwareInterface::getRouting (int  mode,
uint32_t *  routes 
) [pure virtual]
-
-
- -

- -

-

- -

-
- - - - - - - - - -
virtual status_t android::AudioHardwareInterface::setMode (int  mode  )  [pure virtual]
-
-
- -

-setMode is called when the audio mode changes. -

-NORMAL mode is for standard audio playback, RINGTONE when a ringtone is playing, and IN_CALL when a call is in progress. -

-

- -

-
- - - - - - - - - -
virtual status_t android::AudioHardwareInterface::getMode (int *  mode  )  [pure virtual]
-
-
- -

- -

-

- -

-
- - - - - - - - - -
virtual status_t android::AudioHardwareInterface::setMicMute (bool  state  )  [pure virtual]
-
-
- -

- -

-

- -

-
- - - - - - - - - -
virtual status_t android::AudioHardwareInterface::getMicMute (bool *  state  )  [pure virtual]
-
-
- -

- -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::AudioHardwareInterface::setParameter (const char *  key,
const char *  value 
) [pure virtual]
-
-
- -

- -

-

- -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
virtual size_t android::AudioHardwareInterface::getInputBufferSize (uint32_t  sampleRate,
int  format,
int  channelCount 
) [pure virtual]
-
-
- -

- -

-

- -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
virtual AudioStreamOut* android::AudioHardwareInterface::openOutputStream (int  format = 0,
int  channelCount = 0,
uint32_t  sampleRate = 0,
status_t *  status = 0 
) [pure virtual]
-
-
- -

-This method creates and opens the audio hardware output stream. -

- -

-

- -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
virtual AudioStreamIn* android::AudioHardwareInterface::openInputStream (int  format,
int  channelCount,
uint32_t  sampleRate,
status_t *  status 
) [pure virtual]
-
-
- -

-This method creates and opens the audio hardware input stream. -

- -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::AudioHardwareInterface::dumpState (int  fd,
const Vector< String16 > &  args 
) [pure virtual]
-
-
- -

-This method dumps the state of the audio hardware. -

- -

-

- -

-
- - - - - - - - -
static AudioHardwareInterface* android::AudioHardwareInterface::create (  )  [static]
-
-
- -

- -

-

- -

-
- - - - - - - - -
virtual status_t android::AudioHardwareInterface::doRouting (  )  [protected, pure virtual]
-
-
- -

-doRouting actually initiates the routing. -

-A call to setRouting or setMode may result in a routing change. The generic logic calls doRouting when required. If the device has any special requirements these methods can be overriden. -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::AudioHardwareInterface::dump (int  fd,
const Vector< String16 > &  args 
) [protected, pure virtual]
-
-
- -

- -

-

-


The documentation for this class was generated from the following file: -
- - diff --git a/pdk/docs/classandroid_1_1_audio_stream_in.html b/pdk/docs/classandroid_1_1_audio_stream_in.html deleted file mode 100755 index 54391944a..000000000 --- a/pdk/docs/classandroid_1_1_audio_stream_in.html +++ /dev/null @@ -1,292 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

android::AudioStreamIn Class Reference

AudioStreamIn is the abstraction interface for the audio input hardware. -More... -

-#include <AudioHardwareInterface.h> -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Public Member Functions

virtual ~AudioStreamIn ()=0
virtual size_t bufferSize () const =0
 return the input buffer size allowed by audio driver
virtual int channelCount () const =0
 return the number of audio input channels
virtual int format () const =0
 return audio format in 8bit or 16bit PCM format - eg.
uint32_t frameSize () const
 return the frame size (number of bytes per sample).
virtual status_t setGain (float gain)=0
 set the input gain for the audio driver.
virtual ssize_t read (void *buffer, ssize_t bytes)=0
 read audio buffer in from audio driver
virtual status_t dump (int fd, const Vector< String16 > &args)=0
 dump the state of the audio input device
virtual status_t standby ()=0
 Put the audio hardware input into standby mode.
-


Detailed Description

-AudioStreamIn is the abstraction interface for the audio input hardware. -

-It defines the various properties of the audio hardware input driver. -

Definition at line 93 of file AudioHardwareInterface.h.

-

Constructor & Destructor Documentation

- -
-
- - - - - - - - -
virtual android::AudioStreamIn::~AudioStreamIn (  )  [pure virtual]
-
-
- -

- -

-

-


Member Function Documentation

- -
-
- - - - - - - - -
virtual size_t android::AudioStreamIn::bufferSize (  )  const [pure virtual]
-
-
- -

-return the input buffer size allowed by audio driver -

- -

-

- -

-
- - - - - - - - -
virtual int android::AudioStreamIn::channelCount (  )  const [pure virtual]
-
-
- -

-return the number of audio input channels -

- -

-

- -

-
- - - - - - - - -
virtual int android::AudioStreamIn::format (  )  const [pure virtual]
-
-
- -

-return audio format in 8bit or 16bit PCM format - eg. -

-AudioSystem:PCM_16_BIT -

-

- -

-
- - - - - - - - -
uint32_t android::AudioStreamIn::frameSize (  )  const [inline]
-
-
- -

-return the frame size (number of bytes per sample). -

- -

Definition at line 112 of file AudioHardwareInterface.h.

- -
-

- -

-
- - - - - - - - - -
virtual status_t android::AudioStreamIn::setGain (float  gain  )  [pure virtual]
-
-
- -

-set the input gain for the audio driver. -

-This method is for for future use -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual ssize_t android::AudioStreamIn::read (void *  buffer,
ssize_t  bytes 
) [pure virtual]
-
-
- -

-read audio buffer in from audio driver -

- -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::AudioStreamIn::dump (int  fd,
const Vector< String16 > &  args 
) [pure virtual]
-
-
- -

-dump the state of the audio input device -

- -

-

- -

-
- - - - - - - - -
virtual status_t android::AudioStreamIn::standby (  )  [pure virtual]
-
-
- -

-Put the audio hardware input into standby mode. -

-Returns status based on include/utils/Errors.h -

-

-


The documentation for this class was generated from the following file: -
- - diff --git a/pdk/docs/classandroid_1_1_audio_stream_out.html b/pdk/docs/classandroid_1_1_audio_stream_out.html deleted file mode 100755 index 5d727ee0b..000000000 --- a/pdk/docs/classandroid_1_1_audio_stream_out.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

android::AudioStreamOut Class Reference

AudioStreamOut is the abstraction interface for the audio output hardware. -More... -

-#include <AudioHardwareInterface.h> -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Public Member Functions

virtual ~AudioStreamOut ()=0
virtual uint32_t sampleRate () const =0
 return audio sampling rate in hz - eg.
virtual size_t bufferSize () const =0
 returns size of output buffer - eg.
virtual int channelCount () const =0
 return number of output audio channels.
virtual int format () const =0
 return audio format in 8bit or 16bit PCM format - eg.
uint32_t frameSize () const
 return the frame size (number of bytes per sample).
virtual uint32_t latency () const =0
 return the audio hardware driver latency in milli seconds.
virtual status_t setVolume (float volume)=0
 Use this method in situations where audio mixing is done in the hardware.
virtual ssize_t write (const void *buffer, size_t bytes)=0
 write audio buffer to driver.
virtual status_t dump (int fd, const Vector< String16 > &args)=0
 dump the state of the audio output device
-


Detailed Description

-AudioStreamOut is the abstraction interface for the audio output hardware. -

-It provides information about various properties of the audio output hardware driver. -

Definition at line 40 of file AudioHardwareInterface.h.

-

Constructor & Destructor Documentation

- -
-
- - - - - - - - -
virtual android::AudioStreamOut::~AudioStreamOut (  )  [pure virtual]
-
-
- -

- -

-

-


Member Function Documentation

- -
-
- - - - - - - - -
virtual uint32_t android::AudioStreamOut::sampleRate (  )  const [pure virtual]
-
-
- -

-return audio sampling rate in hz - eg. -

-44100 -

-

- -

-
- - - - - - - - -
virtual size_t android::AudioStreamOut::bufferSize (  )  const [pure virtual]
-
-
- -

-returns size of output buffer - eg. -

-4800 -

-

- -

-
- - - - - - - - -
virtual int android::AudioStreamOut::channelCount (  )  const [pure virtual]
-
-
- -

-return number of output audio channels. -

-Acceptable values are 1 (mono) or 2 (stereo) -

-

- -

-
- - - - - - - - -
virtual int android::AudioStreamOut::format (  )  const [pure virtual]
-
-
- -

-return audio format in 8bit or 16bit PCM format - eg. -

-AudioSystem:PCM_16_BIT -

-

- -

-
- - - - - - - - -
uint32_t android::AudioStreamOut::frameSize (  )  const [inline]
-
-
- -

-return the frame size (number of bytes per sample). -

- -

Definition at line 65 of file AudioHardwareInterface.h.

- -
-

- -

-
- - - - - - - - -
virtual uint32_t android::AudioStreamOut::latency (  )  const [pure virtual]
-
-
- -

-return the audio hardware driver latency in milli seconds. -

- -

-

- -

-
- - - - - - - - - -
virtual status_t android::AudioStreamOut::setVolume (float  volume  )  [pure virtual]
-
-
- -

-Use this method in situations where audio mixing is done in the hardware. -

-This method serves as a direct interface with hardware, allowing you to directly set the volume as apposed to via the framework. This method might produce multiple PCM outputs or hardware accelerated codecs, such as MP3 or AAC. -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual ssize_t android::AudioStreamOut::write (const void *  buffer,
size_t  bytes 
) [pure virtual]
-
-
- -

-write audio buffer to driver. -

-Returns number of bytes written -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::AudioStreamOut::dump (int  fd,
const Vector< String16 > &  args 
) [pure virtual]
-
-
- -

-dump the state of the audio output device -

- -

-

-


The documentation for this class was generated from the following file: -
- - diff --git a/pdk/docs/classandroid_1_1_camera_hardware_interface.html b/pdk/docs/classandroid_1_1_camera_hardware_interface.html deleted file mode 100755 index cddb82c31..000000000 --- a/pdk/docs/classandroid_1_1_camera_hardware_interface.html +++ /dev/null @@ -1,393 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

android::CameraHardwareInterface Class Reference

CameraHardwareInterface.h defines the interface to the camera hardware abstraction layer, used for setting and getting parameters, live previewing, and taking pictures. -More... -

-#include <CameraHardwareInterface.h> -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Public Member Functions

virtual ~CameraHardwareInterface ()
virtual sp< IMemoryHeap > getPreviewHeap () const =0
 Return the IMemoryHeap for the preview image heap.
virtual status_t startPreview (preview_callback cb, void *user)=0
 Start preview mode.
virtual void stopPreview ()=0
 Stop a previously started preview.
virtual status_t autoFocus (autofocus_callback, void *user)=0
 Start auto focus, the callback routine is called once when focusing is complete.
virtual status_t takePicture (shutter_callback, raw_callback, jpeg_callback, void *user)=0
 Take a picture.
virtual status_t cancelPicture (bool cancel_shutter, bool cancel_raw, bool cancel_jpeg)=0
 Cancel a picture that was started with takePicture.
virtual status_t setParameters (const CameraParameters &params)=0
 Set the camera parameters.
virtual CameraParameters getParameters () const =0
 Return the camera parameters.
virtual void release ()=0
 Release the hardware resources owned by this object.
virtual status_t dump (int fd, const Vector< String16 > &args) const =0
 Dump state of the camera hardware.
-


Detailed Description

-CameraHardwareInterface.h defines the interface to the camera hardware abstraction layer, used for setting and getting parameters, live previewing, and taking pictures. -

-It is a referenced counted interface with RefBase as its base class. CameraService calls openCameraHardware() to retrieve a strong pointer to the instance of this interface and may be called multiple times. The following steps describe a typical sequence:

-

    -
  1. After CameraService calls openCameraHardware(), getParameters() and setParameters() are used to initialize the camera instance. CameraService calls getPreviewHeap() to establish access to the preview heap so it can be registered with SurfaceFlinger for efficient display updating while in preview mode.
  2. startPreview() is called, which is passed a preview_callback() function and a user parameter. The camera instance then periodically calls preview_callback() each time a new preview frame is available. The callback routine has two parameters: the first is a pointer to the IMemory containing the frame and the second a user parameter. If the preview_callback code needs to use this memory after returning, it must copy the data.
-

-Prior to taking a picture, CameraService calls autofocus() with autofocus_callback() and a user parameter. When auto focusing has completed, the camera instance calls autofocus_callback(), which informs the application whether focusing was successful. The camera instance only calls autofocus_callback() once and it is up to the application to call autoFocus() again if refocusing is desired.

-CameraService calls takePicture() to request the camera instance take a picture. This method has two callbacks: raw_callback() and jpeg_callback(). When the raw image is available, raw_callback() is called with a pointer to the IMemory containing the raw image. When the jpeg image is available, jpeg_callback() is called with a pointer to the IMemory containing the jpeg image. As with preview_callback(), the memory must be copied if it's needed after returning. -

Definition at line 79 of file CameraHardwareInterface.h.

-

Constructor & Destructor Documentation

- -
-
- - - - - - - - -
virtual android::CameraHardwareInterface::~CameraHardwareInterface (  )  [inline, virtual]
-
-
- -

- -

Definition at line 81 of file CameraHardwareInterface.h.

- -
-

-


Member Function Documentation

- -
-
- - - - - - - - -
virtual sp<IMemoryHeap> android::CameraHardwareInterface::getPreviewHeap (  )  const [pure virtual]
-
-
- -

-Return the IMemoryHeap for the preview image heap. -

- -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::CameraHardwareInterface::startPreview (preview_callback  cb,
void *  user 
) [pure virtual]
-
-
- -

-Start preview mode. -

-When a preview image is available preview_callback is called with the user parameter. The call back parameter may be null. -

-

- -

-
- - - - - - - - -
virtual void android::CameraHardwareInterface::stopPreview (  )  [pure virtual]
-
-
- -

-Stop a previously started preview. -

- -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::CameraHardwareInterface::autoFocus (autofocus_callback ,
void *  user 
) [pure virtual]
-
-
- -

-Start auto focus, the callback routine is called once when focusing is complete. -

-autoFocus() will be called again if another auto focus is needed. -

-

- -

-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
virtual status_t android::CameraHardwareInterface::takePicture (shutter_callback ,
raw_callback ,
jpeg_callback ,
void *  user 
) [pure virtual]
-
-
- -

-Take a picture. -

-The raw_callback is called when the uncompressed image is available. The jpeg_callback is called when the compressed image is available. These call backs may be null. The user parameter is passed to each of the call back routines. -

-

- -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
virtual status_t android::CameraHardwareInterface::cancelPicture (bool  cancel_shutter,
bool  cancel_raw,
bool  cancel_jpeg 
) [pure virtual]
-
-
- -

-Cancel a picture that was started with takePicture. -

-You may cancel any of the shutter, raw, or jpeg callbacks. Calling this method when no picture is being taken is a no-op. -

-

- -

-
- - - - - - - - - -
virtual status_t android::CameraHardwareInterface::setParameters (const CameraParameters &  params  )  [pure virtual]
-
-
- -

-Set the camera parameters. -

- -

-

- -

-
- - - - - - - - -
virtual CameraParameters android::CameraHardwareInterface::getParameters (  )  const [pure virtual]
-
-
- -

-Return the camera parameters. -

- -

-

- -

-
- - - - - - - - -
virtual void android::CameraHardwareInterface::release (  )  [pure virtual]
-
-
- -

-Release the hardware resources owned by this object. -

-Note that this is *not* done in the destructor. -

-

- -

-
- - - - - - - - - - - - - - - - - - -
virtual status_t android::CameraHardwareInterface::dump (int  fd,
const Vector< String16 > &  args 
) const [pure virtual]
-
-
- -

-Dump state of the camera hardware. -

- -

-

-


The documentation for this class was generated from the following file: -
- - diff --git a/pdk/docs/doxygen.css b/pdk/docs/doxygen.css deleted file mode 100755 index 22c484301..000000000 --- a/pdk/docs/doxygen.css +++ /dev/null @@ -1,473 +0,0 @@ -BODY,H1,H2,H3,H4,H5,H6,P,CENTER,TD,TH,UL,DL,DIV { - font-family: Geneva, Arial, Helvetica, sans-serif; -} -BODY,TD { - font-size: 90%; -} -H1 { - text-align: center; - font-size: 160%; -} -H2 { - font-size: 120%; -} -H3 { - font-size: 100%; -} -CAPTION { - font-weight: bold -} -DIV.qindex { - width: 100%; - background-color: #e8eef2; - border: 1px solid #84b0c7; - text-align: center; - margin: 2px; - padding: 2px; - line-height: 140%; -} -DIV.navpath { - width: 100%; - background-color: #e8eef2; - border: 1px solid #84b0c7; - text-align: center; - margin: 2px; - padding: 2px; - line-height: 140%; -} -DIV.navtab { - background-color: #e8eef2; - border: 1px solid #84b0c7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} -TD.navtab { - font-size: 70%; -} -A.qindex { - text-decoration: none; - font-weight: bold; - color: #1A419D; -} -A.qindex:visited { - text-decoration: none; - font-weight: bold; - color: #1A419D -} -A.qindex:hover { - text-decoration: none; - background-color: #ddddff; -} -A.qindexHL { - text-decoration: none; - font-weight: bold; - background-color: #6666cc; - color: #ffffff; - border: 1px double #9295C2; -} -A.qindexHL:hover { - text-decoration: none; - background-color: #6666cc; - color: #ffffff; -} -A.qindexHL:visited { - text-decoration: none; - background-color: #6666cc; - color: #ffffff -} -A.el { - text-decoration: none; - font-weight: bold -} -A.elRef { - font-weight: bold -} -A.code:link { - text-decoration: none; - font-weight: normal; - color: #0000FF -} -A.code:visited { - text-decoration: none; - font-weight: normal; - color: #0000FF -} -A.codeRef:link { - font-weight: normal; - color: #0000FF -} -A.codeRef:visited { - font-weight: normal; - color: #0000FF -} -A:hover { - text-decoration: none; - background-color: #f2f2ff -} -DL.el { - margin-left: -1cm -} -.fragment { - font-family: monospace, fixed; - font-size: 95%; -} -PRE.fragment { - border: 1px solid #CCCCCC; - background-color: #f5f5f5; - margin-top: 4px; - margin-bottom: 4px; - margin-left: 2px; - margin-right: 8px; - padding-left: 6px; - padding-right: 6px; - padding-top: 4px; - padding-bottom: 4px; -} -DIV.ah { - background-color: black; - font-weight: bold; - color: #ffffff; - margin-bottom: 3px; - margin-top: 3px -} - -DIV.groupHeader { - margin-left: 16px; - margin-top: 12px; - margin-bottom: 6px; - font-weight: bold; -} -DIV.groupText { - margin-left: 16px; - font-style: italic; - font-size: 90% -} -BODY { - background: white; - color: black; - margin-right: 20px; - margin-left: 20px; -} -TD.indexkey { - background-color: #e8eef2; - font-weight: bold; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px; - border: 1px solid #CCCCCC; -} -TD.indexvalue { - background-color: #e8eef2; - font-style: italic; - padding-right : 10px; - padding-top : 2px; - padding-left : 10px; - padding-bottom : 2px; - margin-left : 0px; - margin-right : 0px; - margin-top : 2px; - margin-bottom : 2px; - border: 1px solid #CCCCCC; -} -TR.memlist { - background-color: #f0f0f0; -} -P.formulaDsp { - text-align: center; -} -IMG.formulaDsp { -} -IMG.formulaInl { - vertical-align: middle; -} -SPAN.keyword { color: #008000 } -SPAN.keywordtype { color: #604020 } -SPAN.keywordflow { color: #e08000 } -SPAN.comment { color: #800000 } -SPAN.preprocessor { color: #806020 } -SPAN.stringliteral { color: #002080 } -SPAN.charliteral { color: #008080 } -SPAN.vhdldigit { color: #ff00ff } -SPAN.vhdlchar { color: #000000 } -SPAN.vhdlkeyword { color: #700070 } -SPAN.vhdllogic { color: #ff0000 } - -.mdescLeft { - padding: 0px 8px 4px 8px; - font-size: 80%; - font-style: italic; - background-color: #FAFAFA; - border-top: 1px none #E0E0E0; - border-right: 1px none #E0E0E0; - border-bottom: 1px none #E0E0E0; - border-left: 1px none #E0E0E0; - margin: 0px; -} -.mdescRight { - padding: 0px 8px 4px 8px; - font-size: 80%; - font-style: italic; - background-color: #FAFAFA; - border-top: 1px none #E0E0E0; - border-right: 1px none #E0E0E0; - border-bottom: 1px none #E0E0E0; - border-left: 1px none #E0E0E0; - margin: 0px; -} -.memItemLeft { - padding: 1px 0px 0px 8px; - margin: 4px; - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - border-top-color: #E0E0E0; - border-right-color: #E0E0E0; - border-bottom-color: #E0E0E0; - border-left-color: #E0E0E0; - border-top-style: solid; - border-right-style: none; - border-bottom-style: none; - border-left-style: none; - background-color: #FAFAFA; - font-size: 80%; -} -.memItemRight { - padding: 1px 8px 0px 8px; - margin: 4px; - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - border-top-color: #E0E0E0; - border-right-color: #E0E0E0; - border-bottom-color: #E0E0E0; - border-left-color: #E0E0E0; - border-top-style: solid; - border-right-style: none; - border-bottom-style: none; - border-left-style: none; - background-color: #FAFAFA; - font-size: 80%; -} -.memTemplItemLeft { - padding: 1px 0px 0px 8px; - margin: 4px; - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - border-top-color: #E0E0E0; - border-right-color: #E0E0E0; - border-bottom-color: #E0E0E0; - border-left-color: #E0E0E0; - border-top-style: none; - border-right-style: none; - border-bottom-style: none; - border-left-style: none; - background-color: #FAFAFA; - font-size: 80%; -} -.memTemplItemRight { - padding: 1px 8px 0px 8px; - margin: 4px; - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - border-top-color: #E0E0E0; - border-right-color: #E0E0E0; - border-bottom-color: #E0E0E0; - border-left-color: #E0E0E0; - border-top-style: none; - border-right-style: none; - border-bottom-style: none; - border-left-style: none; - background-color: #FAFAFA; - font-size: 80%; -} -.memTemplParams { - padding: 1px 0px 0px 8px; - margin: 4px; - border-top-width: 1px; - border-right-width: 1px; - border-bottom-width: 1px; - border-left-width: 1px; - border-top-color: #E0E0E0; - border-right-color: #E0E0E0; - border-bottom-color: #E0E0E0; - border-left-color: #E0E0E0; - border-top-style: solid; - border-right-style: none; - border-bottom-style: none; - border-left-style: none; - color: #606060; - background-color: #FAFAFA; - font-size: 80%; -} -.search { - color: #003399; - font-weight: bold; -} -FORM.search { - margin-bottom: 0px; - margin-top: 0px; -} -INPUT.search { - font-size: 75%; - color: #000080; - font-weight: normal; - background-color: #e8eef2; -} -TD.tiny { - font-size: 75%; -} -a { - color: #1A41A8; -} -a:visited { - color: #2A3798; -} -.dirtab { - padding: 4px; - border-collapse: collapse; - border: 1px solid #84b0c7; -} -TH.dirtab { - background: #e8eef2; - font-weight: bold; -} -HR { - height: 1px; - border: none; - border-top: 1px solid black; -} - -/* Style for detailed member documentation */ -.memtemplate { - font-size: 80%; - color: #606060; - font-weight: normal; - margin-left: 3px; -} -.memnav { - background-color: #e8eef2; - border: 1px solid #84b0c7; - text-align: center; - margin: 2px; - margin-right: 15px; - padding: 2px; -} -.memitem { - padding: 4px; - background-color: #eef3f5; - border-width: 1px; - border-style: solid; - border-color: #dedeee; - -moz-border-radius: 8px 8px 8px 8px; -} -.memname { - white-space: nowrap; - font-weight: bold; -} -.memdoc{ - padding-left: 10px; -} -.memproto { - background-color: #d5e1e8; - width: 100%; - border-width: 1px; - border-style: solid; - border-color: #84b0c7; - font-weight: bold; - -moz-border-radius: 8px 8px 8px 8px; -} -.paramkey { - text-align: right; -} -.paramtype { - white-space: nowrap; -} -.paramname { - color: #602020; - font-style: italic; - white-space: nowrap; -} -/* End Styling for detailed member documentation */ - -/* for the tree view */ -.ftvtree { - font-family: sans-serif; - margin:0.5em; -} -/* these are for tree view when used as main index */ -.directory { - font-size: 9pt; - font-weight: bold; -} -.directory h3 { - margin: 0px; - margin-top: 1em; - font-size: 11pt; -} - -/* The following two styles can be used to replace the root node title */ -/* with an image of your choice. Simply uncomment the next two styles, */ -/* specify the name of your image and be sure to set 'height' to the */ -/* proper pixel height of your image. */ - -/* .directory h3.swap { */ -/* height: 61px; */ -/* background-repeat: no-repeat; */ -/* background-image: url("yourimage.gif"); */ -/* } */ -/* .directory h3.swap span { */ -/* display: none; */ -/* } */ - -.directory > h3 { - margin-top: 0; -} -.directory p { - margin: 0px; - white-space: nowrap; -} -.directory div { - display: none; - margin: 0px; -} -.directory img { - vertical-align: -30%; -} -/* these are for tree view when not used as main index */ -.directory-alt { - font-size: 100%; - font-weight: bold; -} -.directory-alt h3 { - margin: 0px; - margin-top: 1em; - font-size: 11pt; -} -.directory-alt > h3 { - margin-top: 0; -} -.directory-alt p { - margin: 0px; - white-space: nowrap; -} -.directory-alt div { - display: none; - margin: 0px; -} -.directory-alt img { - vertical-align: -30%; -} - diff --git a/pdk/docs/doxygen.png b/pdk/docs/doxygen.png deleted file mode 100755 index f0a274bba..000000000 Binary files a/pdk/docs/doxygen.png and /dev/null differ diff --git a/pdk/docs/files.html b/pdk/docs/files.html deleted file mode 100755 index ec7523914..000000000 --- a/pdk/docs/files.html +++ /dev/null @@ -1,42 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

File List

Here is a list of all files with brief descriptions: - - - - -
AudioHardwareInterface.h [code]
CameraHardwareInterface.h [code]
gps.h [code]
wifi.h [code]
-
- - diff --git a/pdk/docs/functions.html b/pdk/docs/functions.html deleted file mode 100755 index c31d517b6..000000000 --- a/pdk/docs/functions.html +++ /dev/null @@ -1,258 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-Here is a list of all struct and union fields with links to the structures/unions they belong to: -

-

- a -

-

- b -

-

- c -

-

- d -

-

- e -

-

- f -

-

- g -

-

- i -

-

- l -

-

- n -

-

- o -

-

- p -

-

- r -

-

- s -

-

- t -

-

- u -

-

- w -

-

- ~ -

-
- - diff --git a/pdk/docs/functions_func.html b/pdk/docs/functions_func.html deleted file mode 100755 index 2d1c1dcc3..000000000 --- a/pdk/docs/functions_func.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-  -

-

- a -

-

- b -

-

- c -

-

- d -

-

- f -

-

- g -

-

- i -

-

- l -

-

- o -

-

- r -

-

- s -

-

- t -

-

- w -

-

- ~ -

-
- - diff --git a/pdk/docs/functions_vars.html b/pdk/docs/functions_vars.html deleted file mode 100755 index 6d4b71802..000000000 --- a/pdk/docs/functions_vars.html +++ /dev/null @@ -1,158 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-  -

-

- a -

-

- b -

-

- c -

-

- d -

-

- e -

-

- f -

-

- g -

-

- i -

-

- l -

-

- n -

-

- p -

-

- s -

-

- t -

-

- u -

-
- - diff --git a/pdk/docs/globals.html b/pdk/docs/globals.html deleted file mode 100755 index 2ae967fce..000000000 --- a/pdk/docs/globals.html +++ /dev/null @@ -1,91 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-Here is a list of all functions, variables, defines, enums, and typedefs with links to the files they belong to: -

-

    -
  • do_dhcp_request() -: wifi.h -
  • get_dhcp_error_string() -: wifi.h -
  • gps_get_hardware_interface() -: gps.h -
  • gps_get_interface() -: gps.h -
  • gps_get_qemu_interface() -: gps.h -
  • gps_location_callback -: gps.h -
  • gps_status_callback -: gps.h -
  • gps_sv_status_callback -: gps.h -
  • gps_xtra_download_request -: gps.h -
  • GpsAidingData -: gps.h -
  • GpsLocationFlags -: gps.h -
  • GpsPositionMode -: gps.h -
  • GpsStatusValue -: gps.h -
  • GpsUtcTime -: gps.h -
  • wifi_close_supplicant_connection() -: wifi.h -
  • wifi_command() -: wifi.h -
  • wifi_connect_to_supplicant() -: wifi.h -
  • wifi_load_driver() -: wifi.h -
  • wifi_start_supplicant() -: wifi.h -
  • wifi_stop_supplicant() -: wifi.h -
  • wifi_unload_driver() -: wifi.h -
  • wifi_wait_for_event() -: wifi.h -
-
- - diff --git a/pdk/docs/globals_func.html b/pdk/docs/globals_func.html deleted file mode 100755 index 436cbf7a6..000000000 --- a/pdk/docs/globals_func.html +++ /dev/null @@ -1,73 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-  -

-

    -
  • do_dhcp_request() -: wifi.h -
  • get_dhcp_error_string() -: wifi.h -
  • gps_get_hardware_interface() -: gps.h -
  • gps_get_interface() -: gps.h -
  • gps_get_qemu_interface() -: gps.h -
  • wifi_close_supplicant_connection() -: wifi.h -
  • wifi_command() -: wifi.h -
  • wifi_connect_to_supplicant() -: wifi.h -
  • wifi_load_driver() -: wifi.h -
  • wifi_start_supplicant() -: wifi.h -
  • wifi_stop_supplicant() -: wifi.h -
  • wifi_unload_driver() -: wifi.h -
  • wifi_wait_for_event() -: wifi.h -
-
- - diff --git a/pdk/docs/globals_type.html b/pdk/docs/globals_type.html deleted file mode 100755 index ec0afbc91..000000000 --- a/pdk/docs/globals_type.html +++ /dev/null @@ -1,65 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-  -

-

    -
  • gps_location_callback -: gps.h -
  • gps_status_callback -: gps.h -
  • gps_sv_status_callback -: gps.h -
  • gps_xtra_download_request -: gps.h -
  • GpsAidingData -: gps.h -
  • GpsLocationFlags -: gps.h -
  • GpsPositionMode -: gps.h -
  • GpsStatusValue -: gps.h -
  • GpsUtcTime -: gps.h -
-
- - diff --git a/pdk/docs/gps_8h-source.html b/pdk/docs/gps_8h-source.html deleted file mode 100755 index dbf6a16bc..000000000 --- a/pdk/docs/gps_8h-source.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -

gps.h

Go to the documentation of this file.
00001 /*
-00002  * Copyright (C) 2008 The Android Open Source Project
-00003  *
-00004  * Licensed under the Apache License, Version 2.0 (the "License");
-00005  * you may not use this file except in compliance with the License.
-00006  * You may obtain a copy of the License at
-00007  *
-00008  *      http://www.apache.org/licenses/LICENSE-2.0
-00009  *
-00010  * Unless required by applicable law or agreed to in writing, software
-00011  * distributed under the License is distributed on an "AS IS" BASIS,
-00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-00013  * See the License for the specific language governing permissions and
-00014  * limitations under the License.
-00015  */
-00016 
-00017 #ifndef _HARDWARE_GPS_H
-00018 #define _HARDWARE_GPS_H
-00019 
-00020 #include <stdint.h>
-00021 
-00022 #if __cplusplus
-00023 extern "C" {
-00024 #endif
-00025 
-00026 /** Milliseconds since January 1, 1970 */
-00027 typedef int64_t GpsUtcTime;
-00028 
-00029 /** Maximum number of SVs for gps_sv_status_callback(). */
-00030 #define GPS_MAX_SVS 32
-00031 
-00032 /** Requested mode for GPS operation. */
-00033 typedef uint16_t GpsPositionMode;
-00034 // IMPORTANT: Note that the following values must match
-00035 // constants in GpsLocationProvider.java.
-00036 /** Mode for running GPS standalone (no assistance). */
-00037 #define GPS_POSITION_MODE_STANDALONE    0
-00038 /** SUPL MS-Based mode. */
-00039 #define GPS_POSITION_MODE_MS_BASED      1
-00040 /** SUPL MS-Assisted mode. */
-00041 #define GPS_POSITION_MODE_MS_ASSISTED   2
-00042 
-00043 /** GPS status event values. */
-00044 typedef uint16_t GpsStatusValue;
-00045 // IMPORTANT: Note that the following values must match
-00046 // constants in GpsLocationProvider.java.
-00047 /** GPS status unknown. */
-00048 #define GPS_STATUS_NONE             0
-00049 /** GPS has begun navigating. */
-00050 #define GPS_STATUS_SESSION_BEGIN    1
-00051 /** GPS has stopped navigating. */
-00052 #define GPS_STATUS_SESSION_END      2
-00053 /** GPS has powered on but is not navigating. */
-00054 #define GPS_STATUS_ENGINE_ON        3
-00055 /** GPS is powered off. */
-00056 #define GPS_STATUS_ENGINE_OFF       4
-00057 
-00058 /** Flags to indicate which values are valid in a GpsLocation. */
-00059 typedef uint16_t GpsLocationFlags;
-00060 // IMPORTANT: Note that the following values must match
-00061 // constants in GpsLocationProvider.java.
-00062 /** GpsLocation has valid latitude and longitude. */
-00063 #define GPS_LOCATION_HAS_LAT_LONG   0x0001
-00064 /** GpsLocation has valid altitude. */
-00065 #define GPS_LOCATION_HAS_ALTITUDE   0x0002
-00066 /** GpsLocation has valid speed. */
-00067 #define GPS_LOCATION_HAS_SPEED      0x0004
-00068 /** GpsLocation has valid bearing. */
-00069 #define GPS_LOCATION_HAS_BEARING    0x0008
-00070 /** GpsLocation has valid accuracy. */
-00071 #define GPS_LOCATION_HAS_ACCURACY   0x0010
-00072 
-00073 /** Flags used to specify which aiding data to delete
-00074     when calling delete_aiding_data(). */
-00075 typedef uint16_t GpsAidingData;
-00076 // IMPORTANT: Note that the following values must match
-00077 // constants in GpsLocationProvider.java.
-00078 #define GPS_DELETE_EPHEMERIS        0x0001
-00079 #define GPS_DELETE_ALMANAC          0x0002
-00080 #define GPS_DELETE_POSITION         0x0004
-00081 #define GPS_DELETE_TIME             0x0008
-00082 #define GPS_DELETE_IONO             0x0010
-00083 #define GPS_DELETE_UTC              0x0020
-00084 #define GPS_DELETE_HEALTH           0x0040
-00085 #define GPS_DELETE_SVDIR            0x0080
-00086 #define GPS_DELETE_SVSTEER          0x0100
-00087 #define GPS_DELETE_SADATA           0x0200
-00088 #define GPS_DELETE_RTI              0x0400
-00089 #define GPS_DELETE_CELLDB_INFO      0x8000
-00090 #define GPS_DELETE_ALL              0xFFFF
-00091 
-00092 /**
-00093  * Name for the GPS XTRA interface.
-00094  */
-00095 #define GPS_XTRA_INTERFACE      "gps-xtra"
-00096 
-00097 /**
-00098  * Name for the GPS SUPL interface.
-00099  */
-00100 #define GPS_SUPL_INTERFACE      "gps-supl"
-00101 
-00102 /** Represents a location. */
-00103 typedef struct {
-00104     /** Contains GpsLocationFlags bits. */
-00105     uint16_t        flags;
-00106     /** Represents latitude in degrees. */
-00107     double          latitude;
-00108     /** Represents longitude in degrees. */
-00109     double          longitude;
-00110     /** Represents altitude in meters above the WGS 84 reference
-00111      * ellipsoid. */
-00112     double          altitude;
-00113     /** Represents speed in meters per second. */
-00114     float           speed;
-00115     /** Represents heading in degrees. */
-00116     float           bearing;
-00117     /** Represents expected accuracy in meters. */
-00118     float           accuracy;
-00119     /** Timestamp for the location fix. */
-00120     GpsUtcTime      timestamp;
-00121 } GpsLocation;
-00122 
-00123 /** Represents the status. */
-00124 typedef struct {
-00125     GpsStatusValue status;
-00126 } GpsStatus;
-00127 
-00128 /** Represents SV information. */
-00129 typedef struct {
-00130     /** Pseudo-random number for the SV. */
-00131     int     prn;
-00132     /** Signal to noise ratio. */
-00133     float   snr;
-00134     /** Elevation of SV in degrees. */
-00135     float   elevation;
-00136     /** Azimuth of SV in degrees. */
-00137     float   azimuth;
-00138 } GpsSvInfo;
-00139 
-00140 /** Represents SV status. */
-00141 typedef struct {
-00142         /** Number of SVs currently visible. */
-00143         int         num_svs;
-00144 
-00145         /** Contains an array of SV information. */
-00146         GpsSvInfo   sv_list[GPS_MAX_SVS];
-00147 
-00148         /** Represents a bit mask indicating which SVs
-00149          * have ephemeris data.
-00150          */
-00151         uint32_t    ephemeris_mask;
-00152 
-00153         /** Represents a bit mask indicating which SVs
-00154          * have almanac data.
-00155          */
-00156         uint32_t    almanac_mask;
-00157 
-00158         /**
-00159          * Represents a bit mask indicating which SVs
-00160          * were used for computing the most recent position fix.
-00161          */
-00162         uint32_t    used_in_fix_mask;
-00163 } GpsSvStatus;
-00164 
-00165 /** Callback with location information. */
-00166 typedef void (* gps_location_callback)(GpsLocation* location);
-00167 
-00168 /** Callback with status information. */
-00169 typedef void (* gps_status_callback)(GpsStatus* status);
-00170 
-00171 /** Callback with SV status information. */
-00172 typedef void (* gps_sv_status_callback)(GpsSvStatus* sv_info);
-00173 
-00174 /** GPS callback structure. */
-00175 typedef struct {
-00176         gps_location_callback location_cb;
-00177         gps_status_callback status_cb;
-00178         gps_sv_status_callback sv_status_cb;
-00179 } GpsCallbacks;
-00180 
-00181 
-00182 /** Represents the standard GPS interface. */
-00183 typedef struct {
-00184     /**
-00185      * Opens the interface and provides the callback routines
-00186      * to the implemenation of this interface.
-00187      */
-00188     int   (*init)( GpsCallbacks* callbacks );
-00189 
-00190     /** Starts navigating. */
-00191     int   (*start)( void );
-00192 
-00193     /** Stops navigating. */
-00194     int   (*stop)( void );
-00195 
-00196     /** Sets requested frequency of fixes in seconds. */
-00197     void  (*set_fix_frequency)( int frequency );
-00198 
-00199     /** Closes the interface. */
-00200     void  (*cleanup)( void );
-00201 
-00202     /** Injects the current time. */
-00203     int   (*inject_time)(GpsUtcTime time, int64_t timeReference,
-00204                          int uncertainty);
-00205 
-00206     /**
-00207      * Specifies that the next call to start will not use the
-00208      * information defined in the flags. GPS_DELETE_ALL is passed for
-00209      * a cold start.
-00210      */
-00211     void  (*delete_aiding_data)(GpsAidingData flags);
-00212 
-00213     /**
-00214      * fix_frequency represents the time between fixes in seconds.
-00215      * Set fix_frequency to zero for a single-shot fix.
-00216      */
-00217     int   (*set_position_mode)(GpsPositionMode mode, int fix_frequency);
-00218 
-00219     /** Get a pointer to extension information. */
-00220     const void* (*get_extension)(const char* name);
-00221 } GpsInterface;
-00222 
-00223 /** Callback to request the client to download XTRA data.
-00224     The client should download XTRA data and inject it by calling
-00225      inject_xtra_data(). */
-00226 typedef void (* gps_xtra_download_request)();
-00227 
-00228 /** Callback structure for the XTRA interface. */
-00229 typedef struct {
-00230         gps_xtra_download_request download_request_cb;
-00231 } GpsXtraCallbacks;
-00232 
-00233 /** Extended interface for XTRA support. */
-00234 typedef struct {
-00235     /**
-00236      * Opens the XTRA interface and provides the callback routines
-00237      * to the implemenation of this interface.
-00238      */
-00239     int  (*init)( GpsXtraCallbacks* callbacks );
-00240     /** Injects XTRA data into the GPS. */
-00241     int  (*inject_xtra_data)( char* data, int length );
-00242 } GpsXtraInterface;
-00243 
-00244 /** Extended interface for SUPL support. */
-00245 typedef struct {
-00246     /**
-00247      * Sets the name of the APN to be used for SUPL.
-00248      */
-00249     int  (*set_apn)( const char* apn );
-00250 } GpsSuplInterface;
-00251 
-00252 /** Returns the hardware GPS interface. */
-00253 const GpsInterface* gps_get_hardware_interface();
-00254 
-00255 /**
-00256  * Returns the qemu emulated GPS interface.
-00257  */
-00258 const GpsInterface* gps_get_qemu_interface();
-00259 
-00260 /**
-00261  * Returns the default GPS interface.
-00262  */
-00263 const GpsInterface* gps_get_interface();
-00264 
-00265 #if __cplusplus
-00266 }  // extern "C"
-00267 #endif
-00268 
-00269 #endif  // _HARDWARE_GPS_H
-
- - diff --git a/pdk/docs/gps_8h.html b/pdk/docs/gps_8h.html deleted file mode 100755 index 726d25e7c..000000000 --- a/pdk/docs/gps_8h.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

gps.h File Reference

-

-Go to the source code of this file. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Structures

struct  GpsLocation
 Represents a location. More...
struct  GpsStatus
 Represents the status. More...
struct  GpsSvInfo
 Represents SV information. More...
struct  GpsSvStatus
 Represents SV status. More...
struct  GpsCallbacks
 GPS callback structure. More...
struct  GpsInterface
 Represents the standard GPS interface. More...
struct  GpsXtraCallbacks
 Callback structure for the XTRA interface. More...
struct  GpsXtraInterface
 Extended interface for XTRA support. More...
struct  GpsSuplInterface
 Extended interface for SUPL support. More...

Typedefs

typedef int64_t GpsUtcTime
 Milliseconds since January 1, 1970.
typedef uint16_t GpsPositionMode
 Requested mode for GPS operation.
typedef uint16_t GpsStatusValue
 GPS status event values.
typedef uint16_t GpsLocationFlags
 Flags to indicate which values are valid in a GpsLocation.
typedef uint16_t GpsAidingData
 Flags used to specify which aiding data to delete when calling delete_aiding_data().
typedef void(* gps_location_callback )(GpsLocation *location)
 Callback with location information.
typedef void(* gps_status_callback )(GpsStatus *status)
 Callback with status information.
typedef void(* gps_sv_status_callback )(GpsSvStatus *sv_info)
 Callback with SV status information.
typedef void(* gps_xtra_download_request )()
 Callback to request the client to download XTRA data.

Functions

const GpsInterfacegps_get_hardware_interface ()
 Returns the hardware GPS interface.
const GpsInterfacegps_get_qemu_interface ()
 Returns the qemu emulated GPS interface.
const GpsInterfacegps_get_interface ()
 Returns the default GPS interface.
-


Typedef Documentation

- -
-
- - - - -
typedef void(* gps_location_callback)(GpsLocation *location)
-
-
- -

-Callback with location information. -

- -

Definition at line 166 of file gps.h.

- -
-

- -

-
- - - - -
typedef void(* gps_status_callback)(GpsStatus *status)
-
-
- -

-Callback with status information. -

- -

Definition at line 169 of file gps.h.

- -
-

- -

-
- - - - -
typedef void(* gps_sv_status_callback)(GpsSvStatus *sv_info)
-
-
- -

-Callback with SV status information. -

- -

Definition at line 172 of file gps.h.

- -
-

- -

-
- - - - -
typedef void(* gps_xtra_download_request)()
-
-
- -

-Callback to request the client to download XTRA data. -

-The client should download XTRA data and inject it by calling inject_xtra_data(). -

Definition at line 226 of file gps.h.

- -
-

- -

-
- - - - -
typedef uint16_t GpsAidingData
-
-
- -

-Flags used to specify which aiding data to delete when calling delete_aiding_data(). -

- -

Definition at line 75 of file gps.h.

- -
-

- -

-
- - - - -
typedef uint16_t GpsLocationFlags
-
-
- -

-Flags to indicate which values are valid in a GpsLocation. -

- -

Definition at line 59 of file gps.h.

- -
-

- -

-
- - - - -
typedef uint16_t GpsPositionMode
-
-
- -

-Requested mode for GPS operation. -

- -

Definition at line 33 of file gps.h.

- -
-

- -

-
- - - - -
typedef uint16_t GpsStatusValue
-
-
- -

-GPS status event values. -

- -

Definition at line 44 of file gps.h.

- -
-

- -

-
- - - - -
typedef int64_t GpsUtcTime
-
-
- -

-Milliseconds since January 1, 1970. -

- -

Definition at line 27 of file gps.h.

- -
-

-


Function Documentation

- -
-
- - - - - - - - -
const GpsInterface* gps_get_hardware_interface (  ) 
-
-
- -

-Returns the hardware GPS interface. -

- -

-

- -

-
- - - - - - - - -
const GpsInterface* gps_get_interface (  ) 
-
-
- -

-Returns the default GPS interface. -

- -

-

- -

-
- - - - - - - - -
const GpsInterface* gps_get_qemu_interface (  ) 
-
-
- -

-Returns the qemu emulated GPS interface. -

- -

-

-

- - diff --git a/pdk/docs/groups_8dox.html b/pdk/docs/groups_8dox.html deleted file mode 100755 index fe63adaf1..000000000 --- a/pdk/docs/groups_8dox.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

groups.dox File Reference

- -
-
- - diff --git a/pdk/docs/main_8dox.html b/pdk/docs/main_8dox.html deleted file mode 100755 index b4bf17773..000000000 --- a/pdk/docs/main_8dox.html +++ /dev/null @@ -1,33 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

main.dox File Reference

- -
-
- - diff --git a/pdk/docs/namespaceandroid.html b/pdk/docs/namespaceandroid.html deleted file mode 100755 index ee0b03f92..000000000 --- a/pdk/docs/namespaceandroid.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

android Namespace Reference

-

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Structures

class  AudioStreamOut
 AudioStreamOut is the abstraction interface for the audio output hardware. More...
class  AudioStreamIn
 AudioStreamIn is the abstraction interface for the audio input hardware. More...
class  AudioHardwareInterface
 AudioHardwareInterface.h defines the interface to the audio hardware abstraction layer. More...
class  CameraHardwareInterface
 CameraHardwareInterface.h defines the interface to the camera hardware abstraction layer, used for setting and getting parameters, live previewing, and taking pictures. More...

Typedefs

typedef void(* preview_callback )(const sp< IMemory > &mem, void *user)
 Callback for startPreview().
typedef void(* shutter_callback )(void *user)
 Callback for takePicture().
typedef void(* raw_callback )(const sp< IMemory > &mem, void *user)
 Callback for takePicture().
typedef void(* jpeg_callback )(const sp< IMemory > &mem, void *user)
 Callback for takePicture().
typedef void(* autofocus_callback )(bool focused, void *user)
 Callback for autoFocus().

Functions

AudioHardwareInterfacecreateAudioHardware (void)
sp< CameraHardwareInterfaceopenCameraHardware ()
 factory function to instantiate a camera hardware object
-


Typedef Documentation

- -
-
- - - - -
typedef void(* android::autofocus_callback)(bool focused, void *user)
-
-
- -

-Callback for autoFocus(). -

- -

Definition at line 39 of file CameraHardwareInterface.h.

- -
-

- -

-
- - - - -
typedef void(* android::jpeg_callback)(const sp< IMemory > &mem, void *user)
-
-
- -

-Callback for takePicture(). -

- -

Definition at line 36 of file CameraHardwareInterface.h.

- -
-

- -

-
- - - - -
typedef void(* android::preview_callback)(const sp< IMemory > &mem, void *user)
-
-
- -

-Callback for startPreview(). -

- -

Definition at line 27 of file CameraHardwareInterface.h.

- -
-

- -

-
- - - - -
typedef void(* android::raw_callback)(const sp< IMemory > &mem, void *user)
-
-
- -

-Callback for takePicture(). -

- -

Definition at line 33 of file CameraHardwareInterface.h.

- -
-

- -

-
- - - - -
typedef void(* android::shutter_callback)(void *user)
-
-
- -

-Callback for takePicture(). -

- -

Definition at line 30 of file CameraHardwareInterface.h.

- -
-

-


Function Documentation

- -
-
- - - - - - - - - -
AudioHardwareInterface* android::createAudioHardware (void   ) 
-
-
- -

- -

-

- -

-
- - - - - - - - -
sp<CameraHardwareInterface> android::openCameraHardware (  ) 
-
-
- -

-factory function to instantiate a camera hardware object -

- -

-

-

- - diff --git a/pdk/docs/namespacemembers.html b/pdk/docs/namespacemembers.html deleted file mode 100755 index 9644de2d5..000000000 --- a/pdk/docs/namespacemembers.html +++ /dev/null @@ -1,61 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-Here is a list of all namespace members with links to the namespace documentation for each member: -

-

-
- - diff --git a/pdk/docs/namespacemembers_func.html b/pdk/docs/namespacemembers_func.html deleted file mode 100755 index eaa31a555..000000000 --- a/pdk/docs/namespacemembers_func.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-  -

-

-
- - diff --git a/pdk/docs/namespacemembers_type.html b/pdk/docs/namespacemembers_type.html deleted file mode 100755 index 29c17f1ea..000000000 --- a/pdk/docs/namespacemembers_type.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-  -

-

-
- - diff --git a/pdk/docs/namespaces.html b/pdk/docs/namespaces.html deleted file mode 100755 index 23a967916..000000000 --- a/pdk/docs/namespaces.html +++ /dev/null @@ -1,39 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

Namespace List

Here is a list of all namespaces with brief descriptions: - -
android
-
- - diff --git a/pdk/docs/struct_gps_callbacks.html b/pdk/docs/struct_gps_callbacks.html deleted file mode 100755 index 42a148fe0..000000000 --- a/pdk/docs/struct_gps_callbacks.html +++ /dev/null @@ -1,110 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

GpsCallbacks Struct Reference

GPS callback structure. -More... -

-#include <gps.h> -

- - - - - - - - - -

Data Fields

gps_location_callback location_cb
gps_status_callback status_cb
gps_sv_status_callback sv_status_cb
-


Detailed Description

-GPS callback structure. -

- -

Definition at line 175 of file gps.h.

-

Field Documentation

- -
- -
- -

- -

Definition at line 176 of file gps.h.

- -
-

- -

- -
- -

- -

Definition at line 177 of file gps.h.

- -
-

- -

- -
- -

- -

Definition at line 178 of file gps.h.

- -
-

-


The documentation for this struct was generated from the following file: -
- - diff --git a/pdk/docs/struct_gps_interface.html b/pdk/docs/struct_gps_interface.html deleted file mode 100755 index f99e8249c..000000000 --- a/pdk/docs/struct_gps_interface.html +++ /dev/null @@ -1,233 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

GpsInterface Struct Reference

Represents the standard GPS interface. -More... -

-#include <gps.h> -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Fields

int(* init )(GpsCallbacks *callbacks)
 Opens the interface and provides the callback routines to the implemenation of this interface.
int(* start )(void)
 Starts navigating.
int(* stop )(void)
 Stops navigating.
void(* set_fix_frequency )(int frequency)
 Sets requested frequency of fixes in seconds.
void(* cleanup )(void)
 Closes the interface.
int(* inject_time )(GpsUtcTime time, int64_t timeReference, int uncertainty)
 Injects the current time.
void(* delete_aiding_data )(GpsAidingData flags)
 Specifies that the next call to start will not use the information defined in the flags.
int(* set_position_mode )(GpsPositionMode mode, int fix_frequency)
 fix_frequency represents the time between fixes in seconds.
const void *(* get_extension )(const char *name)
 Get a pointer to extension information.
-


Detailed Description

-Represents the standard GPS interface. -

- -

Definition at line 183 of file gps.h.

-

Field Documentation

- -
-
- - - - -
int(* GpsInterface::init)(GpsCallbacks *callbacks)
-
-
- -

-Opens the interface and provides the callback routines to the implemenation of this interface. -

- -

-

- -

-
- - - - -
int(* GpsInterface::start)(void)
-
-
- -

-Starts navigating. -

- -

-

- -

-
- - - - -
int(* GpsInterface::stop)(void)
-
-
- -

-Stops navigating. -

- -

-

- -

-
- - - - -
void(* GpsInterface::set_fix_frequency)(int frequency)
-
-
- -

-Sets requested frequency of fixes in seconds. -

- -

-

- -

-
- - - - -
void(* GpsInterface::cleanup)(void)
-
-
- -

-Closes the interface. -

- -

-

- -

-
- - - - -
int(* GpsInterface::inject_time)(GpsUtcTime time, int64_t timeReference, int uncertainty)
-
-
- -

-Injects the current time. -

- -

-

- -

- -
- -

-Specifies that the next call to start will not use the information defined in the flags. -

-GPS_DELETE_ALL is passed for a cold start. -

-

- -

-
- - - - -
int(* GpsInterface::set_position_mode)(GpsPositionMode mode, int fix_frequency)
-
-
- -

-fix_frequency represents the time between fixes in seconds. -

-Set fix_frequency to zero for a single-shot fix. -

-

- -

-
- - - - -
const void*(* GpsInterface::get_extension)(const char *name)
-
-
- -

-Get a pointer to extension information. -

- -

-

-


The documentation for this struct was generated from the following file: -
- - diff --git a/pdk/docs/struct_gps_location.html b/pdk/docs/struct_gps_location.html deleted file mode 100755 index 33a61fdf0..000000000 --- a/pdk/docs/struct_gps_location.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

GpsLocation Struct Reference

Represents a location. -More... -

-#include <gps.h> -

- - - - - - - - - - - - - - - - - - - - - - - - - - - -

Data Fields

uint16_t flags
 Contains GpsLocationFlags bits.
double latitude
 Represents latitude in degrees.
double longitude
 Represents longitude in degrees.
double altitude
 Represents altitude in meters above the WGS 84 reference ellipsoid.
float speed
 Represents speed in meters per second.
float bearing
 Represents heading in degrees.
float accuracy
 Represents expected accuracy in meters.
GpsUtcTime timestamp
 Timestamp for the location fix.
-


Detailed Description

-Represents a location. -

- -

Definition at line 103 of file gps.h.

-

Field Documentation

- -
-
- - - - -
uint16_t GpsLocation::flags
-
-
- -

-Contains GpsLocationFlags bits. -

- -

Definition at line 105 of file gps.h.

- -
-

- -

-
- - - - -
double GpsLocation::latitude
-
-
- -

-Represents latitude in degrees. -

- -

Definition at line 107 of file gps.h.

- -
-

- -

-
- - - - -
double GpsLocation::longitude
-
-
- -

-Represents longitude in degrees. -

- -

Definition at line 109 of file gps.h.

- -
-

- -

-
- - - - -
double GpsLocation::altitude
-
-
- -

-Represents altitude in meters above the WGS 84 reference ellipsoid. -

- -

Definition at line 112 of file gps.h.

- -
-

- -

-
- - - - -
float GpsLocation::speed
-
-
- -

-Represents speed in meters per second. -

- -

Definition at line 114 of file gps.h.

- -
-

- -

-
- - - - -
float GpsLocation::bearing
-
-
- -

-Represents heading in degrees. -

- -

Definition at line 116 of file gps.h.

- -
-

- -

-
- - - - -
float GpsLocation::accuracy
-
-
- -

-Represents expected accuracy in meters. -

- -

Definition at line 118 of file gps.h.

- -
-

- -

- -
- -

-Timestamp for the location fix. -

- -

Definition at line 120 of file gps.h.

- -
-

-


The documentation for this struct was generated from the following file: -
- - diff --git a/pdk/docs/struct_gps_status.html b/pdk/docs/struct_gps_status.html deleted file mode 100755 index c4a767f8d..000000000 --- a/pdk/docs/struct_gps_status.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

GpsStatus Struct Reference

Represents the status. -More... -

-#include <gps.h> -

- - - - - -

Data Fields

GpsStatusValue status
-


Detailed Description

-Represents the status. -

- -

Definition at line 124 of file gps.h.

-

Field Documentation

- -
- -
- -

- -

Definition at line 125 of file gps.h.

- -
-

-


The documentation for this struct was generated from the following file: -
- - diff --git a/pdk/docs/struct_gps_sv_info.html b/pdk/docs/struct_gps_sv_info.html deleted file mode 100755 index b7ee8a1d1..000000000 --- a/pdk/docs/struct_gps_sv_info.html +++ /dev/null @@ -1,141 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

GpsSvInfo Struct Reference

Represents SV information. -More... -

-#include <gps.h> -

- - - - - - - - - - - - - - - -

Data Fields

int prn
 Pseudo-random number for the SV.
float snr
 Signal to noise ratio.
float elevation
 Elevation of SV in degrees.
float azimuth
 Azimuth of SV in degrees.
-


Detailed Description

-Represents SV information. -

- -

Definition at line 129 of file gps.h.

-

Field Documentation

- -
-
- - - - -
int GpsSvInfo::prn
-
-
- -

-Pseudo-random number for the SV. -

- -

Definition at line 131 of file gps.h.

- -
-

- -

-
- - - - -
float GpsSvInfo::snr
-
-
- -

-Signal to noise ratio. -

- -

Definition at line 133 of file gps.h.

- -
-

- -

-
- - - - -
float GpsSvInfo::elevation
-
-
- -

-Elevation of SV in degrees. -

- -

Definition at line 135 of file gps.h.

- -
-

- -

-
- - - - -
float GpsSvInfo::azimuth
-
-
- -

-Azimuth of SV in degrees. -

- -

Definition at line 137 of file gps.h.

- -
-

-


The documentation for this struct was generated from the following file: -
- - diff --git a/pdk/docs/struct_gps_sv_status.html b/pdk/docs/struct_gps_sv_status.html deleted file mode 100755 index c18feada8..000000000 --- a/pdk/docs/struct_gps_sv_status.html +++ /dev/null @@ -1,163 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

GpsSvStatus Struct Reference

Represents SV status. -More... -

-#include <gps.h> -

- - - - - - - - - - - - - - - - - - -

Data Fields

int num_svs
 Number of SVs currently visible.
GpsSvInfo sv_list [GPS_MAX_SVS]
 Contains an array of SV information.
uint32_t ephemeris_mask
 Represents a bit mask indicating which SVs have ephemeris data.
uint32_t almanac_mask
 Represents a bit mask indicating which SVs have almanac data.
uint32_t used_in_fix_mask
 Represents a bit mask indicating which SVs were used for computing the most recent position fix.
-


Detailed Description

-Represents SV status. -

- -

Definition at line 141 of file gps.h.

-

Field Documentation

- -
-
- - - - -
int GpsSvStatus::num_svs
-
-
- -

-Number of SVs currently visible. -

- -

Definition at line 143 of file gps.h.

- -
-

- -

-
- - - - -
GpsSvInfo GpsSvStatus::sv_list[GPS_MAX_SVS]
-
-
- -

-Contains an array of SV information. -

- -

Definition at line 146 of file gps.h.

- -
-

- -

-
- - - - -
uint32_t GpsSvStatus::ephemeris_mask
-
-
- -

-Represents a bit mask indicating which SVs have ephemeris data. -

- -

Definition at line 151 of file gps.h.

- -
-

- -

-
- - - - -
uint32_t GpsSvStatus::almanac_mask
-
-
- -

-Represents a bit mask indicating which SVs have almanac data. -

- -

Definition at line 156 of file gps.h.

- -
-

- -

-
- - - - -
uint32_t GpsSvStatus::used_in_fix_mask
-
-
- -

-Represents a bit mask indicating which SVs were used for computing the most recent position fix. -

- -

Definition at line 162 of file gps.h.

- -
-

-


The documentation for this struct was generated from the following file: -
- - diff --git a/pdk/docs/struct_gps_xtra_callbacks.html b/pdk/docs/struct_gps_xtra_callbacks.html deleted file mode 100755 index 08130e329..000000000 --- a/pdk/docs/struct_gps_xtra_callbacks.html +++ /dev/null @@ -1,72 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

GpsXtraCallbacks Struct Reference

Callback structure for the XTRA interface. -More... -

-#include <gps.h> -

- - - - - -

Data Fields

gps_xtra_download_request download_request_cb
-


Detailed Description

-Callback structure for the XTRA interface. -

- -

Definition at line 229 of file gps.h.

-

Field Documentation

- -
- -
- -

- -

Definition at line 230 of file gps.h.

- -
-

-


The documentation for this struct was generated from the following file: -
- - diff --git a/pdk/docs/struct_gps_xtra_interface.html b/pdk/docs/struct_gps_xtra_interface.html deleted file mode 100755 index d21fa10d7..000000000 --- a/pdk/docs/struct_gps_xtra_interface.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

GpsXtraInterface Struct Reference

Extended interface for XTRA support. -More... -

-#include <gps.h> -

- - - - - - - - - -

Data Fields

int(* init )(GpsXtraCallbacks *callbacks)
 Opens the XTRA interface and provides the callback routines to the implemenation of this interface.
int(* inject_xtra_data )(char *data, int length)
 Injects XTRA data into the GPS.
-


Detailed Description

-Extended interface for XTRA support. -

- -

Definition at line 234 of file gps.h.

-

Field Documentation

- -
-
- - - - -
int(* GpsXtraInterface::init)(GpsXtraCallbacks *callbacks)
-
-
- -

-Opens the XTRA interface and provides the callback routines to the implemenation of this interface. -

- -

-

- -

-
- - - - -
int(* GpsXtraInterface::inject_xtra_data)(char *data, int length)
-
-
- -

-Injects XTRA data into the GPS. -

- -

-

-


The documentation for this struct was generated from the following file: -
- - diff --git a/pdk/docs/tab_b.gif b/pdk/docs/tab_b.gif deleted file mode 100755 index 0d623483f..000000000 Binary files a/pdk/docs/tab_b.gif and /dev/null differ diff --git a/pdk/docs/tab_l.gif b/pdk/docs/tab_l.gif deleted file mode 100755 index 9b1e6337c..000000000 Binary files a/pdk/docs/tab_l.gif and /dev/null differ diff --git a/pdk/docs/tab_r.gif b/pdk/docs/tab_r.gif deleted file mode 100755 index ce9dd9f53..000000000 Binary files a/pdk/docs/tab_r.gif and /dev/null differ diff --git a/pdk/docs/tabs.css b/pdk/docs/tabs.css deleted file mode 100755 index 95f00a91d..000000000 --- a/pdk/docs/tabs.css +++ /dev/null @@ -1,102 +0,0 @@ -/* tabs styles, based on http://www.alistapart.com/articles/slidingdoors */ - -DIV.tabs -{ - float : left; - width : 100%; - background : url("tab_b.gif") repeat-x bottom; - margin-bottom : 4px; -} - -DIV.tabs UL -{ - margin : 0px; - padding-left : 10px; - list-style : none; -} - -DIV.tabs LI, DIV.tabs FORM -{ - display : inline; - margin : 0px; - padding : 0px; -} - -DIV.tabs FORM -{ - float : right; -} - -DIV.tabs A -{ - float : left; - background : url("tab_r.gif") no-repeat right top; - border-bottom : 1px solid #84B0C7; - font-size : x-small; - font-weight : bold; - text-decoration : none; -} - -DIV.tabs A:hover -{ - background-position: 100% -150px; -} - -DIV.tabs A:link, DIV.tabs A:visited, -DIV.tabs A:active, DIV.tabs A:hover -{ - color: #1A419D; -} - -DIV.tabs SPAN -{ - float : left; - display : block; - background : url("tab_l.gif") no-repeat left top; - padding : 5px 9px; - white-space : nowrap; -} - -DIV.tabs INPUT -{ - float : right; - display : inline; - font-size : 1em; -} - -DIV.tabs TD -{ - font-size : x-small; - font-weight : bold; - text-decoration : none; -} - - - -/* Commented Backslash Hack hides rule from IE5-Mac \*/ -DIV.tabs SPAN {float : none;} -/* End IE5-Mac hack */ - -DIV.tabs A:hover SPAN -{ - background-position: 0% -150px; -} - -DIV.tabs LI.current A -{ - background-position: 100% -150px; - border-width : 0px; -} - -DIV.tabs LI.current SPAN -{ - background-position: 0% -150px; - padding-bottom : 6px; -} - -DIV.navpath -{ - background : none; - border : none; - border-bottom : 1px solid #84B0C7; -} diff --git a/pdk/docs/wifi_8h-source.html b/pdk/docs/wifi_8h-source.html deleted file mode 100755 index 806dd7972..000000000 --- a/pdk/docs/wifi_8h-source.html +++ /dev/null @@ -1,200 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -

wifi.h

Go to the documentation of this file.
00001 /*
-00002  * Copyright (C) 2008 The Android Open Source Project
-00003  *
-00004  * Licensed under the Apache License, Version 2.0 (the "License");
-00005  * you may not use this file except in compliance with the License.
-00006  * You may obtain a copy of the License at
-00007  *
-00008  *      http://www.apache.org/licenses/LICENSE-2.0
-00009  *
-00010  * Unless required by applicable law or agreed to in writing, software
-00011  * distributed under the License is distributed on an "AS IS" BASIS,
-00012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-00013  * See the License for the specific language governing permissions and
-00014  * limitations under the License.
-00015  */
-00016 
-00017 #ifndef _WIFI_H
-00018 #define _WIFI_H
-00019 
-00020 #if __cplusplus
-00021 extern "C" {
-00022 #endif
-00023 
-00024 /**
-00025  * Load the Wi-Fi driver.
-00026  *
-00027  * @return 0 on success, < 0 on failure.
-00028  */
-00029 int wifi_load_driver();
-00030 
-00031 /**
-00032  * Unload the Wi-Fi driver.
-00033  *
-00034  * @return 0 on success, < 0 on failure.
-00035  */
-00036 int wifi_unload_driver();
-00037 
-00038 /**
-00039  * Start supplicant.
-00040  *
-00041  * @return 0 on success, < 0 on failure.
-00042  */
-00043 int wifi_start_supplicant();
-00044 
-00045 /**
-00046  * Stop supplicant.
-00047  *
-00048  * @return 0 on success, < 0 on failure.
-00049  */
-00050 int wifi_stop_supplicant();
-00051 
-00052 /**
-00053  * Open a connection to supplicant.
-00054  *
-00055  * @return 0 on success, < 0 on failure.
-00056  */
-00057 int wifi_connect_to_supplicant();
-00058 
-00059 /**
-00060  * Close connection supplicant.
-00061  *
-00062  * @return 0 on success, < 0 on failure.
-00063  */
-00064 void wifi_close_supplicant_connection();
-00065 
-00066 /**
-00067  * wifi_wait_for_event() performs a blocking call to 
-00068  * get a Wi-Fi event and returns a string representing 
-00069  * a Wi-Fi event when it occurs.
-00070  *
-00071  * @param buf is the buffer that receives the event
-00072  * @param len is the maximum length of the buffer
-00073  *
-00074  * @returns number of bytes in buffer, 0 if no
-00075  * event (for instance, no connection), and less than 0
-00076  * if there is an error.
-00077  */
-00078 int wifi_wait_for_event(char *buf, size_t len);
-00079 
-00080 /**
-00081  * wifi_command() issues a command to the Wi-Fi driver.
-00082  *
-00083  * Android extends the standard commands listed at 
-00084  * /link http://hostap.epitest.fi/wpa_supplicant/devel/ctrl_iface_page.html 
-00085  * to include support for sending commands to the driver:
-00086  *
-00087  * <table border="2" cellspacing="2" cellpadding="2">
-00088  *   <tr>
-00089  *     <td><strong>Command / Command summary</strong></td>
-00090  *     <td><strong>Form of Response</strong></td>
-00091  *     <td><strong>Processing</strong></td>
-00092  *   </tr>
-00093  *   <tr>
-00094  *     <td>DRIVER START<BR>&nbsp;&nbsp;Turn on Wi-Fi Hardware</td>
-00095  *     <td>OK if successful</td>
-00096  *     <td>OK ? true : false</td>
-00097  *   </tr>
-00098  *   <tr>
-00099  *     <td>DRIVER STOP<BR>&nbsp;&nbsp;Turn off Wi-Fi hardware</td>
-00100  *     <td>OK if successful</td>
-00101  *     <td>OK ? true : false</td>
-00102  *   </tr>
-00103  *   <tr>
-00104  *     <td>DRIVER RSSI<BR>&nbsp;&nbsp;Return received signal strength indicator in -db for current AP</td>
-00105  *     <td>&lt;ssid&gt; Rssi xx</td>
-00106  *     <td>%*s %*s %d", &rssi</td>
-00107  *   </tr>
-00108  *   <tr>
-00109  *     <td>DRIVER LINKSPEED<BR>&nbsp;&nbsp;Return link speed in MBPS</td>
-00110  *     <td>LinkSpeed xx</td>
-00111  *     <td>%*s %d", &linkspd</td>
-00112  *   </tr>
-00113  *   <tr>
-00114  *     <td>DRIVER MACADDR<BR>&nbsp;&nbsp;Return mac address of the station</td>
-00115  *     <td>Macaddr = xx.xx.xx.xx.xx.xx</td>
-00116  *     <td>"%*s = %s", &macadr</td>
-00117  *   </tr>
-00118  *   <tr>
-00119  *     <td>DRIVER SCAN-ACTIVE<BR>&nbsp;&nbsp;Set scan type to active</td>
-00120  *     <td>"OK" if successful</td>
-00121  *     <td>"OK" ? true : false</td>
-00122  *   </tr>
-00123  *   <tr>
-00124  *     <td>DRIVER SCAN-PASSIVE<BR>&nbsp;&nbsp;Set scan type to passive</td>
-00125  *     <td>"OK" if successful</td>
-00126  *     <td>"OK" ? true : false</td>
-00127  *   </tr>
-00128  * </table>
-00129  *
-00130  * See libs/android_runtime/android_net_wifi_Wifi.cpp for more information
-00131  * describing how these and other commands are invoked.
-00132  *
-00133  * @param command is the string command
-00134  * @param reply is a buffer to receive a reply string
-00135  * @param reply_len on entry, this is the maximum length of
-00136  *        the reply buffer. On exit, the number of
-00137  *        bytes in the reply buffer.
-00138  *
-00139  * @return 0 if successful, < 0 if an error.
-00140  */
-00141 int wifi_command(const char *command, char *reply, size_t *reply_len);
-00142 
-00143 /**
-00144  * do_dhcp_request() issues a dhcp request and returns the acquired
-00145  * information. 
-00146  * 
-00147  * All IPV4 addresses/mask are in network byte order.
-00148  *
-00149  * @param ipaddr return the assigned IPV4 address
-00150  * @param gateway return the gateway being used
-00151  * @param mask return the IPV4 mask
-00152  * @param dns1 return the IPV4 address of a DNS server
-00153  * @param dns2 return the IPV4 address of a DNS server
-00154  * @param server return the IPV4 address of DHCP server
-00155  * @param lease return the length of lease in seconds.
-00156  *
-00157  * @return 0 if successful, < 0 if error.
-00158  */
-00159 int do_dhcp_request(int *ipaddr, int *gateway, int *mask,
-00160                    int *dns1, int *dns2, int *server, int *lease);
-00161 
-00162 /**
-00163  * Return the error string of the last do_dhcp_request().
-00164  */
-00165 const char *get_dhcp_error_string();
-00166 
-00167 #if __cplusplus
-00168 };  // extern "C"
-00169 #endif
-00170 
-00171 #endif  // _WIFI_H
-
- - diff --git a/pdk/docs/wifi_8h.html b/pdk/docs/wifi_8h.html deleted file mode 100755 index c8285d011..000000000 --- a/pdk/docs/wifi_8h.html +++ /dev/null @@ -1,405 +0,0 @@ - - - - -Doxygen-Generated Content - - - - - - -
-

wifi.h File Reference

-

-Go to the source code of this file. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

Functions

int wifi_load_driver ()
 Load the Wi-Fi driver.
int wifi_unload_driver ()
 Unload the Wi-Fi driver.
int wifi_start_supplicant ()
 Start supplicant.
int wifi_stop_supplicant ()
 Stop supplicant.
int wifi_connect_to_supplicant ()
 Open a connection to supplicant.
void wifi_close_supplicant_connection ()
 Close connection supplicant.
int wifi_wait_for_event (char *buf, size_t len)
 wifi_wait_for_event() performs a blocking call to get a Wi-Fi event and returns a string representing a Wi-Fi event when it occurs.
int wifi_command (const char *command, char *reply, size_t *reply_len)
 wifi_command() issues a command to the Wi-Fi driver.
int do_dhcp_request (int *ipaddr, int *gateway, int *mask, int *dns1, int *dns2, int *server, int *lease)
 do_dhcp_request() issues a dhcp request and returns the acquired information.
const char * get_dhcp_error_string ()
 Return the error string of the last do_dhcp_request().
-


Function Documentation

- -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
int do_dhcp_request (int *  ipaddr,
int *  gateway,
int *  mask,
int *  dns1,
int *  dns2,
int *  server,
int *  lease 
)
-
-
- -

-do_dhcp_request() issues a dhcp request and returns the acquired information. -

-All IPV4 addresses/mask are in network byte order.

-

Parameters:
- - - - - - - - -
ipaddr return the assigned IPV4 address
gateway return the gateway being used
mask return the IPV4 mask
dns1 return the IPV4 address of a DNS server
dns2 return the IPV4 address of a DNS server
server return the IPV4 address of DHCP server
lease return the length of lease in seconds.
-
-
Returns:
0 if successful, < 0 if error.
- -
-

- -

-
- - - - - - - - -
const char* get_dhcp_error_string (  ) 
-
-
- -

-Return the error string of the last do_dhcp_request(). -

- -

-

- -

-
- - - - - - - - -
void wifi_close_supplicant_connection (  ) 
-
-
- -

-Close connection supplicant. -

-

Returns:
0 on success, < 0 on failure.
- -
-

- -

-
- - - - - - - - - - - - - - - - - - - - - - - - -
int wifi_command (const char *  command,
char *  reply,
size_t *  reply_len 
)
-
-
- -

-wifi_command() issues a command to the Wi-Fi driver. -

-Android extends the standard commands listed at /link http://hostap.epitest.fi/wpa_supplicant/devel/ctrl_iface_page.html to include support for sending commands to the driver:

- - - - - - - - - - - - - - - - - -
Command / Command summary Form of Response Processing
DRIVER START
-  Turn on Wi-Fi Hardware
OK if successful OK ? true : false
DRIVER STOP
-  Turn off Wi-Fi hardware
OK if successful OK ? true : false
DRIVER RSSI
-  Return received signal strength indicator in -db for current AP
<ssid> Rssi xx *s *s d", &rssi
DRIVER LINKSPEED
-  Return link speed in MBPS
LinkSpeed xx *s d", &linkspd
DRIVER MACADDR
-  Return mac address of the station
Macaddr = xx.xx.xx.xx.xx.xx "%*s = %s", &macadr
DRIVER SCAN-ACTIVE
-  Set scan type to active
"OK" if successful "OK" ? true : false
DRIVER SCAN-PASSIVE
-  Set scan type to passive
"OK" if successful "OK" ? true : false
-

-See libs/android_runtime/android_net_wifi_Wifi.cpp for more information describing how these and other commands are invoked.

-

Parameters:
- - - - -
command is the string command
reply is a buffer to receive a reply string
reply_len on entry, this is the maximum length of the reply buffer. On exit, the number of bytes in the reply buffer.
-
-
Returns:
0 if successful, < 0 if an error.
- -
-

- -

-
- - - - - - - - -
int wifi_connect_to_supplicant (  ) 
-
-
- -

-Open a connection to supplicant. -

-

Returns:
0 on success, < 0 on failure.
- -
-

- -

-
- - - - - - - - -
int wifi_load_driver (  ) 
-
-
- -

-Load the Wi-Fi driver. -

-

Returns:
0 on success, < 0 on failure.
- -
-

- -

-
- - - - - - - - -
int wifi_start_supplicant (  ) 
-
-
- -

-Start supplicant. -

-

Returns:
0 on success, < 0 on failure.
- -
-

- -

-
- - - - - - - - -
int wifi_stop_supplicant (  ) 
-
-
- -

-Stop supplicant. -

-

Returns:
0 on success, < 0 on failure.
- -
-

- -

-
- - - - - - - - -
int wifi_unload_driver (  ) 
-
-
- -

-Unload the Wi-Fi driver. -

-

Returns:
0 on success, < 0 on failure.
- -
-

- -

-
- - - - - - - - - - - - - - - - - - -
int wifi_wait_for_event (char *  buf,
size_t  len 
)
-
-
- -

-wifi_wait_for_event() performs a blocking call to get a Wi-Fi event and returns a string representing a Wi-Fi event when it occurs. -

-

Parameters:
- - - -
buf is the buffer that receives the event
len is the maximum length of the buffer
-
-
Returns:
number of bytes in buffer, 0 if no event (for instance, no connection), and less than 0 if there is an error.
- -
-

-

- - diff --git a/pdk/doxygen_config/docsfiles/groups.dox b/pdk/doxygen_config/docsfiles/groups.dox new file mode 100644 index 000000000..79f9d3f4f --- /dev/null +++ b/pdk/doxygen_config/docsfiles/groups.dox @@ -0,0 +1,3 @@ + +/*! +*/ diff --git a/pdk/doxygen_config/docsfiles/main.dox b/pdk/doxygen_config/docsfiles/main.dox new file mode 100644 index 000000000..069c1a29d --- /dev/null +++ b/pdk/doxygen_config/docsfiles/main.dox @@ -0,0 +1,5 @@ +/*! \mainpage Google Client Location Library (CLL): location Interface + *

This documentation is part of Google's Client Location Library (CLL) Getting Started Guide.

+ *

In most cases, this Doxygen-generated content opens in a new window (or tab), so look for this window's parent to return to the Getting Started guide. If you maintained + * the original directory structure when you unzipped the documentation, you may also return to the Getting Started guide by clicking Client Location Library (CLL) Getting Started Guide.

+ */ \ No newline at end of file diff --git a/pdk/doxygen_config/overrideconfig.conf b/pdk/doxygen_config/overrideconfig.conf new file mode 100644 index 000000000..f1e381968 --- /dev/null +++ b/pdk/doxygen_config/overrideconfig.conf @@ -0,0 +1,50 @@ + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = pdk +PROJECT_NUMBER = + +INPUT = sources \ + docsfiles + +OUTPUT_DIRECTORY = generatedDocs +HTML_HEADER = header.html +HTML_FOOTER = footer.html +# FILL IN PATH TO HEADER BLOB WANTED IN EVERY FILE +# RELATIVE PATH TO WHER ERUNNING DOXYGEN FROM +HTML_STYLESHEET = +# PATH TO STYLE SHEET\ + +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES + +OPTIMIZE_OUTPUT_FOR_C = YES + +ALWAYS_DETAILED_SEC = YES +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO + +QUIET = NO +WARNINGS = YES + + + +SOURCE_BROWSER = YES + +GENERATE_HTML = YES +ENABLE_PREPROCESSING = NO + +# ADDED JULY 08 TO TRY TO FIGURE OUT DOCUMENING C FILES +EXTRACT_ALL = YES +STRIP_CODE_COMMENTS = NO diff --git a/pdk/doxygen_config/pdk_config.conf b/pdk/doxygen_config/pdk_config.conf new file mode 100644 index 000000000..1f1f349a1 --- /dev/null +++ b/pdk/doxygen_config/pdk_config.conf @@ -0,0 +1,273 @@ +# Doxyfile 1.5.6 + +#--------------------------------------------------------------------------- +# Project related configuration options +#--------------------------------------------------------------------------- +DOXYFILE_ENCODING = UTF-8 +PROJECT_NAME = pdk +PROJECT_NUMBER = +OUTPUT_DIRECTORY = +CREATE_SUBDIRS = NO +OUTPUT_LANGUAGE = English +BRIEF_MEMBER_DESC = YES +REPEAT_BRIEF = YES +ABBREVIATE_BRIEF = "The $name class" \ + "The $name widget" \ + "The $name file" \ + is \ + provides \ + specifies \ + contains \ + represents \ + a \ + an \ + the +ALWAYS_DETAILED_SEC = YES +INLINE_INHERITED_MEMB = NO +FULL_PATH_NAMES = NO +STRIP_FROM_PATH = +STRIP_FROM_INC_PATH = +SHORT_NAMES = NO +JAVADOC_AUTOBRIEF = YES +QT_AUTOBRIEF = NO +MULTILINE_CPP_IS_BRIEF = NO +DETAILS_AT_TOP = NO +INHERIT_DOCS = YES +SEPARATE_MEMBER_PAGES = NO +TAB_SIZE = 8 +ALIASES = +OPTIMIZE_OUTPUT_FOR_C = NO +OPTIMIZE_OUTPUT_JAVA = NO +OPTIMIZE_FOR_FORTRAN = NO +OPTIMIZE_OUTPUT_VHDL = NO +BUILTIN_STL_SUPPORT = NO +CPP_CLI_SUPPORT = NO +SIP_SUPPORT = NO +IDL_PROPERTY_SUPPORT = YES +DISTRIBUTE_GROUP_DOC = NO +SUBGROUPING = YES +TYPEDEF_HIDES_STRUCT = NO +#--------------------------------------------------------------------------- +# Build related configuration options +#--------------------------------------------------------------------------- +EXTRACT_ALL = YES +EXTRACT_PRIVATE = NO +EXTRACT_STATIC = NO +EXTRACT_LOCAL_CLASSES = NO +EXTRACT_LOCAL_METHODS = NO +EXTRACT_ANON_NSPACES = YES +HIDE_UNDOC_MEMBERS = NO +HIDE_UNDOC_CLASSES = NO +HIDE_FRIEND_COMPOUNDS = NO +HIDE_IN_BODY_DOCS = NO +INTERNAL_DOCS = NO +CASE_SENSE_NAMES = YES +HIDE_SCOPE_NAMES = NO +SHOW_INCLUDE_FILES = NO +# MIGHT WANT TO TWEAK LEATER +INLINE_INFO = YES +SORT_MEMBER_DOCS = YES +SORT_BRIEF_DOCS = YES +SORT_GROUP_NAMES = NO +SORT_BY_SCOPE_NAME = NO +GENERATE_TODOLIST = NO +GENERATE_TESTLIST = NO +GENERATE_BUGLIST = NO +GENERATE_DEPRECATEDLIST= YES +ENABLED_SECTIONS = +MAX_INITIALIZER_LINES = 30 +SHOW_USED_FILES = NO +SHOW_DIRECTORIES = NO +SHOW_FILES = YES +SHOW_NAMESPACES = YES +FILE_VERSION_FILTER = +#--------------------------------------------------------------------------- +# configuration options related to warning and progress messages +#--------------------------------------------------------------------------- +QUIET = NO +WARNINGS = YES +WARN_IF_UNDOCUMENTED = YES +WARN_IF_DOC_ERROR = YES +WARN_NO_PARAMDOC = NO +WARN_FORMAT = "$file:$line: $text" +WARN_LOGFILE = +#--------------------------------------------------------------------------- +# configuration options related to the input files +#--------------------------------------------------------------------------- +INPUT = +INPUT_ENCODING = UTF-8 +FILE_PATTERNS = *.c \ + *.cpp \ + *.dox \ + *.h \ + *.htm \ + *.html +RECURSIVE = YES +EXCLUDE = +# ecxlude entire directories or files +EXCLUDE_SYMLINKS = NO +EXCLUDE_PATTERNS = +EXCLUDE_SYMBOLS = +EXAMPLE_PATH = +EXAMPLE_PATTERNS = * +EXAMPLE_RECURSIVE = NO +IMAGE_PATH = +INPUT_FILTER = +FILTER_PATTERNS = +FILTER_SOURCE_FILES = NO +#--------------------------------------------------------------------------- +# configuration options related to source browsing +#--------------------------------------------------------------------------- +SOURCE_BROWSER = YES +INLINE_SOURCES = NO +STRIP_CODE_COMMENTS = YES +REFERENCED_BY_RELATION = NO +REFERENCES_RELATION = YES +REFERENCES_LINK_SOURCE = NO +USE_HTAGS = NO +VERBATIM_HEADERS = NO +#--------------------------------------------------------------------------- +# configuration options related to the alphabetical class index +#--------------------------------------------------------------------------- +ALPHABETICAL_INDEX = NO +COLS_IN_ALPHA_INDEX = 1 +IGNORE_PREFIX = +#--------------------------------------------------------------------------- +# configuration options related to the HTML output +#--------------------------------------------------------------------------- +GENERATE_HTML = YES +HTML_OUTPUT = html +HTML_FILE_EXTENSION = .html +HTML_HEADER = +# FILL IN PATH TO HEADER BLOB WANTED IN EVERY FILE +# RELATIVE PATH TO WHER ERUNNING DOXYGEN FROM +HTML_FOOTER = +HTML_STYLESHEET = +# PATH TO STYLE SHEET +HTML_ALIGN_MEMBERS = YES +GENERATE_HTMLHELP = NO +GENERATE_DOCSET = NO +DOCSET_FEEDNAME = "Doxygen generated docs" +DOCSET_BUNDLE_ID = org.doxygen.Project +HTML_DYNAMIC_SECTIONS = NO +CHM_FILE = +HHC_LOCATION = +GENERATE_CHI = NO +CHM_INDEX_ENCODING = +BINARY_TOC = NO +TOC_EXPAND = NO +DISABLE_INDEX = NO +ENUM_VALUES_PER_LINE = 4 +GENERATE_TREEVIEW = NONE +TREEVIEW_WIDTH = 250 +FORMULA_FONTSIZE = 10 +#--------------------------------------------------------------------------- +# configuration options related to the LaTeX output +#--------------------------------------------------------------------------- +GENERATE_LATEX = NO +LATEX_OUTPUT = latex +LATEX_CMD_NAME = latex +MAKEINDEX_CMD_NAME = makeindex +COMPACT_LATEX = NO +PAPER_TYPE = a4wide +EXTRA_PACKAGES = +LATEX_HEADER = +PDF_HYPERLINKS = YES +USE_PDFLATEX = YES +LATEX_BATCHMODE = NO +LATEX_HIDE_INDICES = NO +#--------------------------------------------------------------------------- +# configuration options related to the RTF output +#--------------------------------------------------------------------------- +GENERATE_RTF = NO +RTF_OUTPUT = rtf +COMPACT_RTF = NO +RTF_HYPERLINKS = NO +RTF_STYLESHEET_FILE = +RTF_EXTENSIONS_FILE = +#--------------------------------------------------------------------------- +# configuration options related to the man page output +#--------------------------------------------------------------------------- +GENERATE_MAN = NO +MAN_OUTPUT = man +MAN_EXTENSION = .3 +MAN_LINKS = NO +#--------------------------------------------------------------------------- +# configuration options related to the XML output +#--------------------------------------------------------------------------- +GENERATE_XML = NO +XML_OUTPUT = xml +XML_SCHEMA = +XML_DTD = +XML_PROGRAMLISTING = YES +#--------------------------------------------------------------------------- +# configuration options for the AutoGen Definitions output +#--------------------------------------------------------------------------- +GENERATE_AUTOGEN_DEF = NO +#--------------------------------------------------------------------------- +# configuration options related to the Perl module output +#--------------------------------------------------------------------------- +GENERATE_PERLMOD = NO +PERLMOD_LATEX = NO +PERLMOD_PRETTY = YES +PERLMOD_MAKEVAR_PREFIX = +#--------------------------------------------------------------------------- +# Configuration options related to the preprocessor +#--------------------------------------------------------------------------- +ENABLE_PREPROCESSING = NO +# KEY CONSIDERATION TWEAK BACK AND FORTH. function in an # if/def preprocessor directive. Processor evalutes whether true. Should doxygen follow compiles behavior or document everything? +# usually have optional things that people may want to tweak. +MACRO_EXPANSION = YES +EXPAND_ONLY_PREDEF = YES +SEARCH_INCLUDES = NO +INCLUDE_PATH = +INCLUDE_FILE_PATTERNS = +PREDEFINED = +#to mimic preprocessor behaviors. +EXPAND_AS_DEFINED = +SKIP_FUNCTION_MACROS = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to external references +#--------------------------------------------------------------------------- +TAGFILES = +GENERATE_TAGFILE = +ALLEXTERNALS = NO +EXTERNAL_GROUPS = NO +PERL_PATH = +#--------------------------------------------------------------------------- +# Configuration options related to the dot tool +#--------------------------------------------------------------------------- +CLASS_DIAGRAMS = NO +#CHANGE WHEN HAVE DIAGRAMS +MSCGEN_PATH = YES +HIDE_UNDOC_RELATIONS = YES +HAVE_DOT = NO +DOT_FONTNAME = FreeSans +DOT_FONTPATH = +CLASS_GRAPH = YES +COLLABORATION_GRAPH = YES +GROUP_GRAPHS = YES +UML_LOOK = NO +TEMPLATE_RELATIONS = NO +INCLUDE_GRAPH = YES +INCLUDED_BY_GRAPH = YES +CALL_GRAPH = NO +CALLER_GRAPH = NO +GRAPHICAL_HIERARCHY = YES +DIRECTORY_GRAPH = YES +DOT_IMAGE_FORMAT = png +DOT_PATH = +DOTFILE_DIRS = +DOT_GRAPH_MAX_NODES = 50 +MAX_DOT_GRAPH_DEPTH = 1000 +DOT_TRANSPARENT = YES +DOT_MULTI_TARGETS = NO +GENERATE_LEGEND = YES +DOT_CLEANUP = YES +#--------------------------------------------------------------------------- +# Configuration::additions related to the search engine +#--------------------------------------------------------------------------- +SEARCHENGINE = NO +@INCLUDE = overrideconfig.conf +# relative to where running doxygen from +# @INCLUDE = $(PROJECTCONF) diff --git a/pdk/ndk/Ndk.mk b/pdk/ndk/Ndk.mk index d5d0b1b96..32400e303 100644 --- a/pdk/ndk/Ndk.mk +++ b/pdk/ndk/Ndk.mk @@ -60,7 +60,7 @@ endef # The JNI-only version is provided for partners that want to create shared # libraries that can be packaged with APK files and called from Java code. -LOCAL_PATH := $(my-dir) +LOCAL_PATH := $(call my-dir) # Source trees for the ndk samples_src_dir := $(LOCAL_PATH)/samples @@ -183,9 +183,9 @@ ndk_with_src: $(ndk_with_src_tarfile_zipped) ndk_jni_with_src: $(ndk_jni_with_src_tarfile_zipped) # Put the ndk zip files in the distribution directory -$(call dist-for-goals,pdk,$(ndk_tarfile_zipped)) -$(call dist-for-goals,pdk,$(ndk_with_src_tarfile_zipped)) -$(call dist-for-goals,pdk,$(ndk_jni_with_src_tarfile_zipped)) +$(call dist-for-goals,ndk,$(ndk_tarfile_zipped)) +$(call dist-for-goals,ndk,$(ndk_with_src_tarfile_zipped)) +$(call dist-for-goals,ndk,$(ndk_jni_with_src_tarfile_zipped)) # zip up tar files %.tar.gz: %.tar diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml index bfefbf059..f8fc1b24f 100644 --- a/samples/ApiDemos/AndroidManifest.xml +++ b/samples/ApiDemos/AndroidManifest.xml @@ -152,6 +152,15 @@ + + + + + + + + + diff --git a/samples/ApiDemos/res/layout/intents.xml b/samples/ApiDemos/res/layout/intents.xml new file mode 100644 index 000000000..023e4e84d --- /dev/null +++ b/samples/ApiDemos/res/layout/intents.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml index 2b2cc164d..7db3e1b7c 100644 --- a/samples/ApiDemos/res/values/strings.xml +++ b/samples/ApiDemos/res/values/strings.xml @@ -205,6 +205,14 @@ Content/Resources/Themes Content/Resources/Resources + + + + + App/Intents + Example of launching various Intents. + Get Music + diff --git a/samples/ApiDemos/src/com/android/samples/app/VoiceRecognition.java b/samples/ApiDemos/src/com/android/samples/app/VoiceRecognition.java index aa45c8eb1..35d94307d 100644 --- a/samples/ApiDemos/src/com/android/samples/app/VoiceRecognition.java +++ b/samples/ApiDemos/src/com/android/samples/app/VoiceRecognition.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2008 Google Inc. + * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -29,7 +29,10 @@ import com.example.android.apis.R; import java.util.ArrayList; -public class VoiceRecognition extends Activity { +/** + * Sample code that invokes the speech recognition intent API. + */ +public class VoiceRecognition extends Activity implements OnClickListener { private static final int VOICE_RECOGNITION_REQUEST_CODE = 1234; @@ -51,34 +54,41 @@ public class VoiceRecognition extends Activity { mList = (ListView) findViewById(R.id.list); // Attach actions to buttons - speakButton.setOnClickListener(new OnClickListener() { - public void onClick(View v) { - startVoiceRecognitionActivity(); - } - }); + speakButton.setOnClickListener(this); } - void startVoiceRecognitionActivity() { - Intent intent = new Intent("android.intent.action.VOICE_RECOGNITION"); - this.startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); + /** + * Handle the click on the start recognition button. + */ + public void onClick(View v) { + if (v.getId() == R.id.btn_speak) { + startVoiceRecognitionActivity(); + } } + /** + * Fire an intent to start the speech recognition activity. + */ + private void startVoiceRecognitionActivity() { + //TODO Get these values from constants + Intent intent = new Intent("android.speech.action.RECOGNIZE_SPEECH"); + intent.putExtra("language_model", "free_form"); + intent.putExtra("prompt", "Speech recognition demo"); + startActivityForResult(intent, VOICE_RECOGNITION_REQUEST_CODE); + } + + /** + * Handle the results from the recognition activity. + */ @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { - - android.util.Log.d("mike", "************** onActivityResult" + data ); - if (requestCode == VOICE_RECOGNITION_REQUEST_CODE && resultCode == RESULT_OK) { - ArrayListmatches = data.getStringArrayListExtra("queries"); - - - android.util.Log.d("mike", "************** onActivityResult" + matches); - - mList.setAdapter(new ArrayAdapter(this, - android.R.layout.simple_list_item_1, matches)); + //TODO get the value from a constant + ArrayListmatches = data.getStringArrayListExtra("results"); + mList.setAdapter(new ArrayAdapter(this, android.R.layout.simple_list_item_1, + matches)); } - + super.onActivityResult(requestCode, resultCode, data); } - } diff --git a/samples/ApiDemos/src/com/example/android/apis/app/Intents.java b/samples/ApiDemos/src/com/example/android/apis/app/Intents.java new file mode 100644 index 000000000..8f02b8322 --- /dev/null +++ b/samples/ApiDemos/src/com/example/android/apis/app/Intents.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.example.android.apis.app; + +import com.example.android.apis.R; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; + +public class Intents extends Activity { + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + setContentView(R.layout.intents); + + // Watch for button clicks. + Button button = (Button)findViewById(R.id.get_music); + button.setOnClickListener(mGetMusicListener); + } + + private OnClickListener mGetMusicListener = new OnClickListener() { + public void onClick(View v) { + Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + intent.setType("audio/*"); + startActivity(Intent.createChooser(intent, "Select music")); + } + }; +} diff --git a/samples/Home/res/drawable/ic_menu_gallery.png b/samples/Home/res/drawable/ic_menu_gallery.png deleted file mode 100644 index f61bbd8ba..000000000 Binary files a/samples/Home/res/drawable/ic_menu_gallery.png and /dev/null differ diff --git a/samples/Home/res/drawable/ic_menu_notifications.png b/samples/Home/res/drawable/ic_menu_notifications.png deleted file mode 100644 index 866d4e0bd..000000000 Binary files a/samples/Home/res/drawable/ic_menu_notifications.png and /dev/null differ diff --git a/samples/Home/res/drawable/ic_menu_preferences.png b/samples/Home/res/drawable/ic_menu_preferences.png deleted file mode 100755 index b8e71412d..000000000 Binary files a/samples/Home/res/drawable/ic_menu_preferences.png and /dev/null differ diff --git a/samples/Home/src/com/example/android/home/Home.java b/samples/Home/src/com/example/android/home/Home.java index f2fbefffb..de67ef4d2 100644 --- a/samples/Home/src/com/example/android/home/Home.java +++ b/samples/Home/src/com/example/android/home/Home.java @@ -388,13 +388,13 @@ public class Home extends Activity { super.onCreateOptionsMenu(menu); menu.add(0, MENU_WALLPAPER_SETTINGS, 0, R.string.menu_wallpaper) - .setIcon(R.drawable.ic_menu_gallery) + .setIcon(android.R.drawable.ic_menu_gallery) .setAlphabeticShortcut('W'); menu.add(0, MENU_SEARCH, 0, R.string.menu_search) .setIcon(android.R.drawable.ic_search_category_default) .setAlphabeticShortcut(SearchManager.MENU_KEY); menu.add(0, MENU_SETTINGS, 0, R.string.menu_settings) - .setIcon(R.drawable.ic_menu_preferences) + .setIcon(android.R.drawable.ic_menu_preferences) .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS)); return true; diff --git a/samples/PlatformLibrary/Android.mk b/samples/PlatformLibrary/Android.mk index d70038696..afb54a26e 100644 --- a/samples/PlatformLibrary/Android.mk +++ b/samples/PlatformLibrary/Android.mk @@ -34,6 +34,23 @@ LOCAL_SRC_FILES := $(call all-java-files-under, java) include $(BUILD_JAVA_LIBRARY) +# ============================================================ +include $(CLEAR_VARS) + +LOCAL_MODULE := com.example.android.platform_library.xml + +LOCAL_MODULE_TAGS := samples + +LOCAL_MODULE_CLASS := ETC + +# This will install the file in /system/etc/permissions +# +LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/permissions + +LOCAL_SRC_FILES := $(LOCAL_MODULE) + +include $(BUILD_PREBUILT) + # ============================================================ # Also build all of the sub-targets under this one: the library's diff --git a/samples/PlatformLibrary/README.txt b/samples/PlatformLibrary/README.txt index e2a7c80b7..5ce9d2f77 100644 --- a/samples/PlatformLibrary/README.txt +++ b/samples/PlatformLibrary/README.txt @@ -12,18 +12,14 @@ create a system image that will be delivered on a device which will include a custom library as shown here. It can not be used to create a third party shared library, which is not currently supported in Android. -Note that while this example is almost entirely self-contained -- you can -build it and run the client app without any changes to the framework -- there -is one change you must make so that the system will recognize your library: - -In frameworks/base/data/etc/permissions.xml is a list of all of the optional -shared libraries available in the system. You will need to add an entry at -the bottom of this file for your own shared library, which looks like this -for our sample code here: +To declare your library to the framework, you must place a file with a .xml +extension in the /system/etc/permissions directory with the following contents: + + - + There are three major parts of this example, supplying three distinct build targets and corresponding build outputs: diff --git a/samples/PlatformLibrary/com.example.android.platform_library.xml b/samples/PlatformLibrary/com.example.android.platform_library.xml new file mode 100644 index 000000000..b9491d85b --- /dev/null +++ b/samples/PlatformLibrary/com.example.android.platform_library.xml @@ -0,0 +1,5 @@ + + + + diff --git a/samples/SoftKeyboard/res/values/dimens.xml b/samples/SoftKeyboard/res/values/dimens.xml index cea6e505a..cdaf27a2d 100644 --- a/samples/SoftKeyboard/res/values/dimens.xml +++ b/samples/SoftKeyboard/res/values/dimens.xml @@ -21,4 +21,5 @@ 50px 16sp + 6sp \ No newline at end of file diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java index 1e79cd7c4..7cadead8a 100755 --- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java +++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/CandidateView.java @@ -55,6 +55,7 @@ public class CandidateView extends View { private int mColorNormal; private int mColorRecommended; private int mColorOther; + private int mVerticalPadding; private Paint mPaint; private boolean mScrolled; private int mTargetScrollX; @@ -86,6 +87,7 @@ public class CandidateView extends View { mColorNormal = r.getColor(R.color.candidate_normal); mColorRecommended = r.getColor(R.color.candidate_recommended); mColorOther = r.getColor(R.color.candidate_other); + mVerticalPadding = r.getDimensionPixelSize(R.dimen.candidate_vertical_padding); mPaint = new Paint(); mPaint.setColor(mColorNormal); @@ -139,7 +141,7 @@ public class CandidateView extends View { // not have a divider below) Rect padding = new Rect(); mSelectionHighlight.getPadding(padding); - final int desiredHeight = ((int)mPaint.getTextSize()) + 1 + final int desiredHeight = ((int)mPaint.getTextSize()) + mVerticalPadding + padding.top + padding.bottom; // Maximum possible width and desired height @@ -174,7 +176,7 @@ public class CandidateView extends View { final int scrollX = getScrollX(); final boolean scrolled = mScrolled; final boolean typedWordValid = mTypedWordValid; - final int y = (int) (height + mPaint.getTextSize()) / 2; + final int y = (int) (((height - mPaint.getTextSize()) / 2) - mPaint.ascent()); for (int i = 0; i < count; i++) { String suggestion = mSuggestions.get(i); diff --git a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java index baa45942d..5d68b56f1 100644 --- a/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java +++ b/samples/SoftKeyboard/src/com/example/android/softkeyboard/SoftKeyboard.java @@ -20,8 +20,9 @@ import android.content.Context; import android.inputmethodservice.InputMethodService; import android.inputmethodservice.Keyboard; import android.inputmethodservice.KeyboardView; -import android.text.TextUtils; +import android.text.method.MetaKeyKeyListener; import android.util.Log; +import android.view.KeyCharacterMap; import android.view.KeyEvent; import android.view.View; import android.view.WindowManager; @@ -48,12 +49,12 @@ public class SoftKeyboard extends InputMethodService private CompletionInfo[] mCompletions; private StringBuilder mComposing = new StringBuilder(); - private boolean mPredicting; private boolean mPredictionOn; private boolean mCompletionOn; private int mLastDisplayWidth; private boolean mCapsLock; private long mLastShiftTime; + private long mMetaState; private Keyboard mSymbolsKeyboard; private Keyboard mSymbolsShiftedKeyboard; @@ -61,8 +62,6 @@ public class SoftKeyboard extends InputMethodService private String mWordSeparators; - private InputConnection mOldConnection; - 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 @@ -80,7 +79,6 @@ public class SoftKeyboard extends InputMethodService @Override public void onCreate() { super.onCreate(); - //setStatusIcon(R.drawable.ime_qwerty); makeKeyboards(); mWordSeparators = getResources().getString(R.string.word_separators); } @@ -97,7 +95,6 @@ public class SoftKeyboard extends InputMethodService @Override public View onCreateCandidatesView() { - makeKeyboards(); mCandidateView = new CandidateView(this); mCandidateView.setService(this); return mCandidateView; @@ -105,33 +102,28 @@ public class SoftKeyboard extends InputMethodService @Override public void onStartInputView(EditorInfo attribute, boolean restarting) { - // In landscape mode, this method gets called without the input view being created. - if (mInputView == null) { - return; - } - - if (mQwertyKeyboard == null) { - makeKeyboards(); - } - - if (mOldConnection != null) { - commitTyped(mOldConnection); + mComposing.setLength(0); + updateCandidates(); + + if (!restarting) { + // Clear shift states. + mMetaState = 0; } mPredictionOn = false; mCompletionOn = false; mCompletions = null; + Keyboard keyboard; switch (attribute.inputType&EditorInfo.TYPE_MASK_CLASS) { case EditorInfo.TYPE_CLASS_NUMBER: case EditorInfo.TYPE_CLASS_DATETIME: - mInputView.setKeyboard(mSymbolsKeyboard); + keyboard = mSymbolsKeyboard; break; case EditorInfo.TYPE_CLASS_PHONE: - mInputView.setKeyboard(mSymbolsKeyboard); + keyboard = mSymbolsKeyboard; break; default: - mInputView.setKeyboard(mQwertyKeyboard); - //startPrediction(); + keyboard = mQwertyKeyboard; mPredictionOn = true; // Make sure that passwords are not displayed in candidate view int variation = attribute.inputType & EditorInfo.TYPE_MASK_VARIATION; @@ -149,34 +141,49 @@ public class SoftKeyboard extends InputMethodService updateShiftKeyState(attribute); break; } - mInputView.closing(); + + if (mInputView != null) { + mInputView.setKeyboard(keyboard); + mInputView.closing(); + } + mComposing.setLength(0); - mCandidateView.setSuggestions(null, false, false); - mOldConnection = getCurrentInputConnection(); - setCandidatesViewShown(mPredictionOn || mCompletionOn); + setSuggestions(null, false, false); } @Override public void onFinishInput() { super.onFinishInput(); - commitTyped(mOldConnection); + mComposing.setLength(0); + updateCandidates(); if (mInputView != null) { mInputView.closing(); } } @Override - public void onDisplayCompletions(CompletionInfo[] completions) { - if (false) { - Log.i("foo", "Received completions:"); - for (int i=0; i<(completions != null ? completions.length : 0); i++) { - Log.i("foo", " #" + i + ": " + completions[i]); + 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 + || newSelEnd != candidatesEnd)) { + mComposing.setLength(0); + updateCandidates(); + InputConnection ic = getCurrentInputConnection(); + if (ic != null) { + ic.finishComposingText(); } } + } + + @Override + public void onDisplayCompletions(CompletionInfo[] completions) { if (mCompletionOn) { mCompletions = completions; if (completions == null) { - mCandidateView.setSuggestions(null, false, false); + setSuggestions(null, false, false); return; } @@ -185,10 +192,42 @@ public class SoftKeyboard extends InputMethodService CompletionInfo ci = completions[i]; if (ci != null) stringList.add(ci.getText().toString()); } - mCandidateView.setSuggestions(stringList, true, true); + setSuggestions(stringList, true, true); } } + private boolean translateKeyDown(int keyCode, KeyEvent event) { + mMetaState = MetaKeyKeyListener.handleKeyDown(mMetaState, + keyCode, event); + int c = event.getUnicodeChar(MetaKeyKeyListener.getMetaState(mMetaState)); + mMetaState = MetaKeyKeyListener.adjustMetaAfterKeypress(mMetaState); + InputConnection ic = getCurrentInputConnection(); + if (c == 0 || ic == null) { + return false; + } + + boolean dead = false; + + if ((c & KeyCharacterMap.COMBINING_ACCENT) != 0) { + dead = true; + c = c & KeyCharacterMap.COMBINING_ACCENT_MASK; + } + + if (mComposing.length() > 0) { + char accent = mComposing.charAt(mComposing.length() -1 ); + int composed = KeyEvent.getDeadChar(accent, c); + + if (composed != 0) { + c = composed; + mComposing.setLength(mComposing.length()-1); + } + } + + onKey(c, null); + + return true; + } + @Override public boolean onKeyDown(int keyCode, KeyEvent event) { switch (keyCode) { @@ -199,12 +238,16 @@ public class SoftKeyboard extends InputMethodService } } break; - case KeyEvent.KEYCODE_DPAD_DOWN: - case KeyEvent.KEYCODE_DPAD_UP: - case KeyEvent.KEYCODE_DPAD_LEFT: - case KeyEvent.KEYCODE_DPAD_RIGHT: - abortComposition(); + case KeyEvent.KEYCODE_DEL: + if (mComposing.length() > 0) { + onKey(Keyboard.KEYCODE_DELETE, null); + return true; + } break; + default: + if (mPredictionOn && translateKeyDown(keyCode, event)) { + return true; + } } return super.onKeyDown(keyCode, event); } @@ -225,6 +268,11 @@ public class SoftKeyboard extends InputMethodService return true; } break; + default: + if (mPredictionOn) { + mMetaState = MetaKeyKeyListener.handleKeyUp(mMetaState, + keyCode, event); + } } return super.onKeyUp(keyCode, event); } @@ -262,7 +310,7 @@ public class SoftKeyboard extends InputMethodService private void sendKey(int keyCode) { switch (keyCode) { - case 10: + case '\n': keyDownUp(KeyEvent.KEYCODE_ENTER); break; default: @@ -280,11 +328,11 @@ public class SoftKeyboard extends InputMethodService public void onKey(int primaryCode, int[] keyCodes) { if (isWordSeparator(primaryCode)) { // Handle separator - if (mPredicting) { + if (mComposing.length() > 0) { commitTyped(getCurrentInputConnection()); } sendKey(primaryCode); - updateShiftKeyState(getCurrentInputInfo()); + updateShiftKeyState(getCurrentInputEditorInfo()); } else if (primaryCode == Keyboard.KEYCODE_DELETE) { handleBackspace(); } else if (primaryCode == Keyboard.KEYCODE_SHIFT) { @@ -294,7 +342,8 @@ public class SoftKeyboard extends InputMethodService return; } else if (primaryCode == LatinKeyboardView.KEYCODE_OPTIONS) { // Show a menu or somethin' - } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE) { + } else if (primaryCode == Keyboard.KEYCODE_MODE_CHANGE + && mInputView != null) { Keyboard current = mInputView.getKeyboard(); if (current == mSymbolsKeyboard || current == mSymbolsShiftedKeyboard) { current = mQwertyKeyboard; @@ -320,34 +369,47 @@ public class SoftKeyboard extends InputMethodService if (mComposing.length() > 0) { ArrayList list = new ArrayList(); list.add(mComposing.toString()); - mCandidateView.setSuggestions(list, true, true); + setSuggestions(list, true, true); } else { - mCandidateView.setSuggestions(null, false, false); + setSuggestions(null, false, false); } } } + public void setSuggestions(List 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); + } + } + private void handleBackspace() { - if (mPredicting) { - final int length = mComposing.length(); - if (length > 0) { - mComposing.delete(length - 1, length); - getCurrentInputConnection().setComposingText(mComposing, mComposing.length()); - updateCandidates(); - if (mComposing.length() == 0) { - mPredicting = false; - } - } else { - getCurrentInputConnection().deleteSurroundingText(1, 0); - } + final int length = mComposing.length(); + if (length > 1) { + mComposing.delete(length - 1, length); + getCurrentInputConnection().setComposingText(mComposing, mComposing.length()); + updateCandidates(); + } else if (length > 0) { + mComposing.setLength(0); + getCurrentInputConnection().commitText("", 0); + updateCandidates(); } else { //getCurrentInputConnection().deleteSurroundingText(1, 0); keyDownUp(KeyEvent.KEYCODE_DEL); } - updateShiftKeyState(getCurrentInputInfo()); + updateShiftKeyState(getCurrentInputEditorInfo()); } private void handleShift() { + if (mInputView == null) { + return; + } + Keyboard currentKeyboard = mInputView.getKeyboard(); if (mQwertyKeyboard == currentKeyboard) { // Alphabet keyboard @@ -365,19 +427,20 @@ public class SoftKeyboard extends InputMethodService } private void handleCharacter(int primaryCode, int[] keyCodes) { - if (isAlphabet(primaryCode) && mPredictionOn && !isCursorTouchingWord()) { - if (!mPredicting) { - mPredicting = true; - mComposing.setLength(0); + if (isInputViewShown()) { + if (mInputView.isShifted()) { + primaryCode = Character.toUpperCase(primaryCode); } } - if (mInputView.isShifted()) { - primaryCode = Character.toUpperCase(primaryCode); + if (isAlphabet(primaryCode) && mPredictionOn) { + mComposing.append((char) primaryCode); + getCurrentInputConnection().setComposingText(mComposing, mComposing.length()); + updateShiftKeyState(getCurrentInputEditorInfo()); + updateCandidates(); + } else { + getCurrentInputConnection().commitText( + String.valueOf((char) primaryCode), 0); } - mComposing.append((char) primaryCode); - getCurrentInputConnection().setComposingText(mComposing, mComposing.length()); - updateShiftKeyState(getCurrentInputInfo()); - updateCandidates(); } private void handleClose() { @@ -396,20 +459,6 @@ public class SoftKeyboard extends InputMethodService } } - private boolean isCursorTouchingWord() { - CharSequence toLeft = getCurrentInputConnection().getTextBeforeCursor(1); - CharSequence toRight = getCurrentInputConnection().getTextAfterCursor(1); - if (!TextUtils.isEmpty(toLeft) - && !isWordSeparator(toLeft.charAt(0))) { - return true; - } - if (!TextUtils.isEmpty(toRight) - && !isWordSeparator(toRight.charAt(0))) { - return true; - } - return false; - } - protected String getWordSeparators() { return mWordSeparators; } @@ -431,7 +480,12 @@ public class SoftKeyboard extends InputMethodService if (mCandidateView != null) { mCandidateView.clear(); } - updateShiftKeyState(getCurrentInputInfo()); + updateShiftKeyState(getCurrentInputEditorInfo()); + } else if (mComposing.length() > 0) { + // If we were generating candidate suggestions for the current + // text, we would commit one of them here. But for this sample, + // we will just commit the current text. + commitTyped(getCurrentInputConnection()); } } @@ -452,10 +506,4 @@ public class SoftKeyboard extends InputMethodService public void swipeUp() { // ? } - - private void abortComposition() { - commitTyped(getCurrentInputConnection()); - mComposing.setLength(0); // Don't want to allow uncommit after this - updateCandidates(); - } } diff --git a/tools/anttasks/.classpath b/tools/anttasks/.classpath new file mode 100644 index 000000000..08ced2120 --- /dev/null +++ b/tools/anttasks/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tools/anttasks/.project b/tools/anttasks/.project new file mode 100644 index 000000000..aed1b6164 --- /dev/null +++ b/tools/anttasks/.project @@ -0,0 +1,17 @@ + + + ant-tasks + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tools/anttasks/Android.mk b/tools/anttasks/Android.mk new file mode 100644 index 000000000..15ee90361 --- /dev/null +++ b/tools/anttasks/Android.mk @@ -0,0 +1,17 @@ +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +ANTTASKS_LOCAL_DIR := $(call my-dir) +include $(ANTTASKS_LOCAL_DIR)/src/Android.mk diff --git a/tools/anttasks/src/Android.mk b/tools/anttasks/src/Android.mk new file mode 100644 index 000000000..dbaf2bc29 --- /dev/null +++ b/tools/anttasks/src/Android.mk @@ -0,0 +1,28 @@ +# +# Copyright (C) 2008 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +LOCAL_PATH := $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_JAVA_LIBRARIES := \ + sdklib \ + ant + +LOCAL_MODULE := anttasks + +include $(BUILD_HOST_JAVA_LIBRARY) + diff --git a/tools/anttasks/src/com/android/ant/AndroidInitTask.java b/tools/anttasks/src/com/android/ant/AndroidInitTask.java new file mode 100644 index 000000000..84c1d27a1 --- /dev/null +++ b/tools/anttasks/src/com/android/ant/AndroidInitTask.java @@ -0,0 +1,150 @@ +/* + * 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.ant; + +import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.ISdkLog; +import com.android.sdklib.SdkManager; +import com.android.sdklib.project.ProjectProperties; + +import org.apache.tools.ant.BuildException; +import org.apache.tools.ant.Project; +import org.apache.tools.ant.taskdefs.ImportTask; + +import java.io.File; +import java.util.ArrayList; + +/** + * Import Target Ant task. This task accomplishes: + *
    + *
  • Gets the project target hash string from {@link ProjectProperties#PROPERTY_TARGET}, + * and resolves it.
  • + *
  • Sets up ant properties so that the rest of the Ant scripts finds: + *
      + *
    • Path to the underlying platform to access the build rules ('android-platform')
    • + *
    + *
  • + *
+ * + * This is used in build.xml/template. + * + */ +public class AndroidInitTask extends ImportTask { + private final static String ANDROID_RULES = "android_rules.xml"; + + private final static String PROPERTY_ANDROID_JAR = "android-jar"; + private final static String PROPERTY_ANDROID_AIDL = "android-aidl"; + + @Override + public void execute() throws BuildException { + Project antProject = getProject(); + + // get the SDK location + String sdkLocation = antProject.getProperty(ProjectProperties.PROPERTY_SDK); + + // check if it's valid and exists + if (sdkLocation == null || sdkLocation.length() == 0) { + throw new BuildException("SDK Location is not set."); + } + + File sdk = new File(sdkLocation); + if (sdk.isDirectory() == false) { + throw new BuildException(String.format("SDK Location '%s' is not valid.", sdkLocation)); + } + + // get the target property value + String targetHashString = antProject.getProperty(ProjectProperties.PROPERTY_TARGET); + if (targetHashString == null) { + throw new BuildException("Android Target is not set."); + } + + // load up the sdk targets. + final ArrayList messages = new ArrayList(); + SdkManager manager = SdkManager.createManager(sdkLocation, new ISdkLog() { + public void error(Throwable t, String errorFormat, Object... args) { + if (errorFormat != null) { + messages.add(String.format("Error: " + errorFormat, args)); + } + if (t != null) { + messages.add("Error: " + t.getMessage()); + } + } + + public void printf(String msgFormat, Object... args) { + messages.add(String.format(msgFormat, args)); + } + + public void warning(String warningFormat, Object... args) { + messages.add(String.format("Warning: " + warningFormat, args)); + } + }); + + if (manager == null) { + // since we failed to parse the SDK, lets display the parsing output. + for (String msg : messages) { + System.out.println(msg); + } + throw new BuildException("Failed to parse SDK content."); + } + + // resolve it + IAndroidTarget androidTarget = manager.getTargetFromHashString(targetHashString); + + if (androidTarget == null) { + throw new BuildException(String.format( + "Unable to resolve target '%s'", targetHashString)); + } + + // display it + System.out.println("Project Target: " + androidTarget.getName()); + if (androidTarget.isPlatform() == false) { + System.out.println("Vendor: " + androidTarget.getVendor()); + } + System.out.println("Platform Version: " + androidTarget.getApiVersionName()); + System.out.println("API level: " + androidTarget.getApiVersionNumber()); + + // sets up the properties. + String androidJar = androidTarget.getPath(IAndroidTarget.ANDROID_JAR); + String androidAidl = androidTarget.getPath(IAndroidTarget.ANDROID_AIDL); + + antProject.setProperty(PROPERTY_ANDROID_JAR, androidJar); + antProject.setProperty(PROPERTY_ANDROID_AIDL, androidAidl); + + // find the file to import, and import it. + String templateFolder = androidTarget.getPath(IAndroidTarget.TEMPLATES); + + // make sure the file exists. + File templates = new File(templateFolder); + if (templates.isDirectory() == false) { + throw new BuildException(String.format("Template directory '%s' is missing.", + templateFolder)); + } + + // now check the rules file exists. + File rules = new File(templateFolder, ANDROID_RULES); + if (rules.isFile() == false) { + throw new BuildException(String.format("Build rules file '%s' is missing.", + templateFolder)); + } + + // set the file location to import + setFile(rules.getAbsolutePath()); + + // and import it + super.execute(); + } +} diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java index a031a1b03..8291f591e 100644 --- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java +++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/Device.java @@ -69,6 +69,9 @@ public final class Device implements IDevice { /** Serial number of the device */ String serialNumber = null; + /** Name of the vm */ + String mVmName = null; + /** State of the device. */ DeviceState state = null; @@ -91,6 +94,11 @@ public final class Device implements IDevice { return serialNumber; } + public String getVmName() { + return mVmName; + } + + /* * (non-Javadoc) * @see com.android.ddmlib.IDevice#getState() diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java index 4b81116c3..8547ac1f4 100644 --- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java +++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/DeviceMonitor.java @@ -349,7 +349,7 @@ final class DeviceMonitor { } if (device.getPropertyCount() == 0) { - queryForBuild(device); + queryNewDeviceForInfo(device); } } } @@ -387,7 +387,7 @@ final class DeviceMonitor { // look for their build info. if (newDevice.isOnline()) { - queryForBuild(newDevice); + queryNewDeviceForInfo(newDevice); } } } @@ -413,11 +413,20 @@ final class DeviceMonitor { * Queries a device for its build info. * @param device the device to query. */ - private void queryForBuild(Device device) { + private void queryNewDeviceForInfo(Device device) { // TODO: do this in a separate thread. try { + // first get the list of properties. device.executeShellCommand(GetPropReceiver.GETPROP_COMMAND, new GetPropReceiver(device)); + + // now get the emulator VM name (if applicable). + if (device.isEmulator()) { + EmulatorConsole console = EmulatorConsole.getConsole(device); + if (console != null) { + device.mVmName = console.getVmName(); + } + } } catch (IOException e) { // if we can't get the build info, it doesn't matter too much } diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java index 4aac0e131..e00073c15 100644 --- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java +++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/EmulatorConsole.java @@ -54,6 +54,7 @@ public final class EmulatorConsole { private final static String HOST = "127.0.0.1"; //$NON-NLS-1$ private final static String COMMAND_PING = "help\r\n"; //$NON-NLS-1$ + private final static String COMMAND_VM_NAME = "vm name\r\n"; //$NON-NLS-1$ private final static String COMMAND_KILL = "kill\r\n"; //$NON-NLS-1$ private final static String COMMAND_GSM_STATUS = "gsm status\r\n"; //$NON-NLS-1$ private final static String COMMAND_GSM_CALL = "gsm call %1$s\r\n"; //$NON-NLS-1$ @@ -307,6 +308,24 @@ public final class EmulatorConsole { RemoveConsole(mPort); } } + + public synchronized String getVmName() { + if (sendCommand(COMMAND_VM_NAME)) { + String[] result = readLines(); + if (result != null && result.length == 2) { // this should be the name on first line, + // and ok on 2nd line + return result[0]; + } else { + // try to see if there's a message after KO + Matcher m = RE_KO.matcher(result[result.length-1]); + if (m.matches()) { + return m.group(1); + } + } + } + + return null; + } /** * Get the network status of the emulator. diff --git a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java index 106b76f5d..61d1ca462 100755 --- a/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java +++ b/tools/ddms/libs/ddmlib/src/com/android/ddmlib/IDevice.java @@ -44,6 +44,15 @@ public interface IDevice { * Returns the serial number of the device. */ public String getSerialNumber(); + + /** + * Returns the name of the VM the emulator is running. + *

This is only valid if {@link #isEmulator()} returns true. + *

If the emulator is not running any VM (for instance it's running from an Android source + * tree build), this method will return "<build>". + * @return the name of the VM or null if there isn't any. + */ + public String getVmName(); /** * Returns the state of the device. diff --git a/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java b/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java index cd4aa2671..556fc9b8e 100644 --- a/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java +++ b/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib/testrunner/RemoteAndroidTestRunnerTest.java @@ -201,6 +201,10 @@ public class RemoteAndroidTestRunnerTest extends TestCase { throw new UnsupportedOperationException(); } + public String getVmName() { + return ""; + } + } /** An empty implementation of TestRunListener diff --git a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java index adaa3c345..1331a097c 100644 --- a/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java +++ b/tools/ddms/libs/ddmuilib/src/com/android/ddmuilib/DevicePanel.java @@ -200,12 +200,22 @@ public final class DevicePanel extends Panel implements IDebugBridgeChangeListen case DEVICE_COL_STATE: return getStateString(device); case DEVICE_COL_BUILD: { + String vmName = device.getVmName(); String debuggable = device.getProperty(Device.PROP_DEBUGGABLE); String version = device.getProperty(Device.PROP_BUILD_VERSION); - if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$ - return String.format("%1$s (debug)", version); //$NON-NLS-1$ + if (device.isEmulator()) { + if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$ + return String.format("%1$s [%2$s, debug]", vmName, //$NON-NLS-1$ + version); + } else { + return String.format("%1$s [%2$s]", vmName, version); //$NON-NLS-1$ + } } else { - return String.format("%1$s", version); //$NON-NLS-1$ + if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$ + return String.format("%1$s, debug", version); //$NON-NLS-1$ + } else { + return String.format("%1$s", version); //$NON-NLS-1$ + } } } } diff --git a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml index 191b76d99..676a89e49 100644 --- a/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml +++ b/tools/eclipse/features/com.android.ide.eclipse.adt/feature.xml @@ -40,6 +40,13 @@ + + + + + + + * "ERROR at line <line>: <error>"
- * " (Occured while parsing <path>)" + * " (Occurred while parsing <path>)" */ private final static Pattern sPattern1Line1 = Pattern.compile( "^ERROR\\s+at\\s+line\\s+(\\d+):\\s+(.*)$"); //$NON-NLS-1$ /** * Second line of dual line aapt error.
* "ERROR at line <line>: <error>"
- * " (Occured while parsing <path>)"
- * @see sPattern1Line1 + * " (Occurred while parsing <path>)"
+ * @see #sPattern1Line1 */ private final static Pattern sPattern1Line2 = Pattern.compile( "^\\s+\\(Occurred while parsing\\s+(.*)\\)$"); //$NON-NLS-1$ @@ -92,7 +92,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { * Second line of dual line aapt error.
* "ERROR: <error>"
* "Defined at file <path> line <line>"
- * @see sPattern2Line1 + * @see #sPattern2Line1 */ private final static Pattern sPattern2Line2 = Pattern.compile( "Defined\\s+at\\s+file\\s+(.+)\\s+line\\s+(\\d+)"); //$NON-NLS-1$ @@ -113,7 +113,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { * Second line of dual line aapt error.
* "ERROR parsing XML file <path>"
* "<error> at line <line>"
- * @see sPattern4Line1 + * @see #sPattern4Line1 */ private final static Pattern sPattern4Line2 = Pattern.compile( "^(.+)\\s+at\\s+line\\s+(\\d+)$"); //$NON-NLS-1$ @@ -263,7 +263,7 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { /** * Adds a marker to the current project. - * @param file the file to be marked + * * @param markerId The id of the marker to add. * @param message the message associated with the mark * @param severity the severity of the marker. @@ -292,12 +292,11 @@ abstract class BaseBuilder extends IncrementalProjectBuilder { /** * Removes markers from a container and its children. - * @param container The container from which to delete the markers. + * @param folder The container from which to delete the markers. * @param markerId The id of the markers to remove. If null, all marker of * type IMarker.PROBLEM will be removed. */ - protected final void removeMarkersFromContainer(IContainer folder, - String markerId) { + protected final void removeMarkersFromContainer(IContainer folder, String markerId) { try { if (folder.exists()) { folder.deleteMarkers(markerId, true, IResource.DEPTH_INFINITE); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java index 1a4aa8ce0..9fc434880 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerBuilder.java @@ -1128,10 +1128,8 @@ public class PreCompilerBuilder extends BaseBuilder { * Finish a file created/modified by an outside command line process. * The file is marked as modified by Android, and the parent folder is refreshed, so that, * in case the file didn't exist beforehand, the file appears in the package explorer. - * @param file The file to "finish". - * @param parent The parent container. Can be null (in which case it'll be - * figured out from the file's IResource. - * @param monitor a monitor to display progress. + * @param rFile The R file to "finish". + * @param manifestFile The manifest file to "finish". * @throws CoreException */ private void finishJavaFilesAfterExternalModification(IFile rFile, IFile manifestFile) @@ -1150,9 +1148,7 @@ public class PreCompilerBuilder extends BaseBuilder { * The file is marked as modified by Android, and the parent folder is refreshed, so that, * in case the file didn't exist beforehand, the file appears in the package explorer. * @param file The file to "finish". - * @param parent The parent container. Can be null (in which case it'll be - * figured out from the file's IResource. - * @param monitor a monitor to display progress. + * @param aidlFile The AIDL file to "finish". * @throws CoreException */ private void finishFileAfterExternalModification(IFile file, IFile aidlFile) diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java index 33d5fa6cf..f4778d796 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/build/PreCompilerDeltaVisitor.java @@ -23,6 +23,7 @@ import com.android.ide.eclipse.adt.project.ProjectHelper; import com.android.ide.eclipse.common.AndroidConstants; import com.android.ide.eclipse.common.project.AndroidManifestParser; import com.android.ide.eclipse.common.project.BaseProjectHelper; +import com.android.sdklib.SdkConstants; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -154,7 +155,7 @@ class PreCompilerDeltaVisitor extends BaseDeltaVisitor implements // then we are not yet in a source or resource folder mInRes = mInSrc = false; - if (AndroidConstants.FD_RESOURCES.equalsIgnoreCase(segments[1])) { + if (SdkConstants.FD_RESOURCES.equalsIgnoreCase(segments[1])) { // this is the resource folder that was modified. we want to // see its content. diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java index 48ec7c3bb..2b7d01d81 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/AndroidLaunchController.java @@ -31,8 +31,12 @@ import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.debug.launching.DeviceChooserDialog.DeviceChooserResponse; import com.android.ide.eclipse.adt.debug.ui.EmulatorConfigTab; import com.android.ide.eclipse.adt.project.ProjectHelper; +import com.android.ide.eclipse.adt.sdk.Sdk; import com.android.ide.eclipse.common.project.AndroidManifestHelper; -import com.android.sdklib.SdkConstants; +import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkManager; +import com.android.sdklib.vm.VmManager; +import com.android.sdklib.vm.VmManager.VmInfo; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -58,6 +62,7 @@ import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.HashMap; +import java.util.Map.Entry; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -69,9 +74,9 @@ import java.util.regex.Pattern; public final class AndroidLaunchController implements IDebugBridgeChangeListener, IDeviceChangeListener, IClientChangeListener { + private static final String FLAG_VM = "-vm"; //$NON-NLS-1$ private static final String FLAG_NETDELAY = "-netdelay"; //$NON-NLS-1$ private static final String FLAG_NETSPEED = "-netspeed"; //$NON-NLS-1$ - private static final String FLAG_SKIN = "-skin"; //$NON-NLS-1$ private static final String FLAG_WIPE_DATA = "-wipe-data"; //$NON-NLS-1$ private static final String FLAG_NO_BOOT_ANIM = "-no-boot-anim"; //$NON-NLS-1$ @@ -223,11 +228,10 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener public boolean mNoBootAnim = LaunchConfigDelegate.DEFAULT_NO_BOOT_ANIM; /** - * Screen size parameters. - * This value can be provided to the emulator directly for the option "-skin" + * Vm Name. */ - public String mSkin = null; - + public String mVmName = null; + public String mNetworkSpeed = EmulatorConfigTab.getSpeed( LaunchConfigDelegate.DEFAULT_SPEED); public String mNetworkDelay = EmulatorConfigTab.getDelay( @@ -258,12 +262,8 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener } try { - mSkin = config.getAttribute(LaunchConfigDelegate.ATTR_SKIN, mSkin); - if (mSkin == null) { - mSkin = SdkConstants.SKIN_DEFAULT; - } + mVmName = config.getAttribute(LaunchConfigDelegate.ATTR_VM_NAME, mVmName); } catch (CoreException e) { - mSkin = SdkConstants.SKIN_DEFAULT; } int index = LaunchConfigDelegate.DEFAULT_SPEED; @@ -526,11 +526,14 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener // set the launch mode to default. wc.setAttribute(LaunchConfigDelegate.ATTR_LAUNCH_ACTION, LaunchConfigDelegate.DEFAULT_LAUNCH_ACTION); - + // set default target mode wc.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE, LaunchConfigDelegate.DEFAULT_TARGET_MODE); + // default VM: None + wc.setAttribute(LaunchConfigDelegate.ATTR_VM_NAME, (String)null); + // set the default network speed wc.setAttribute(LaunchConfigDelegate.ATTR_SPEED, LaunchConfigDelegate.DEFAULT_SPEED); @@ -539,9 +542,6 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener wc.setAttribute(LaunchConfigDelegate.ATTR_DELAY, LaunchConfigDelegate.DEFAULT_DELAY); - // default skin - wc.setAttribute(LaunchConfigDelegate.ATTR_SKIN, SdkConstants.SKIN_DEFAULT); - // default wipe data mode wc.setAttribute(LaunchConfigDelegate.ATTR_WIPE_DATA, LaunchConfigDelegate.DEFAULT_WIPE_DATA); @@ -627,32 +627,171 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener // set the debug mode launchInfo.mDebugMode = mode.equals(ILaunchManager.DEBUG_MODE); - // device chooser response. + // get the SDK + Sdk currentSdk = Sdk.getCurrent(); + VmManager vmManager = currentSdk.getVmManager(); + + // get the project target + final IAndroidTarget projectTarget = currentSdk.getTarget(project); + + // FIXME: check errors on missing sdk, vm manager, or project target. + + // device chooser response object. final DeviceChooserResponse response = new DeviceChooserResponse(); + /* + * Launch logic: + * - Manually Mode + * Always display a UI that lets a user see the current running emulators/devices. + * The UI must show which devices are compatibles, and allow launching new emulators + * with compatible (and not yet running) VM. + * - Automatic Way + * * Preferred VM set. + * If Preferred VM is not running: launch it. + * Launch the application on the preferred VM. + * * No preferred VM. + * Count the number of compatible emulators/devices. + * If != 1, display a UI similar to manual mode. + * If == 1, launch the application on this VM/device. + */ + if (config.mTargetMode == AndroidLaunchConfiguration.AUTO_TARGET_MODE) { // if we are in automatic target mode, we need to find the current devices Device[] devices = AndroidDebugBridge.getBridge().getDevices(); - // depending on the number of devices, we'll simulate an automatic choice - // from the device chooser or simply show up the device chooser. - if (devices.length == 0) { - // if zero devices, we launch the device. - AdtPlugin.printToConsole(project, "Automatic Target Mode: launching new emulator."); + // first check if we have a preferred VM name, and if it actually exists, and is valid + // (ie able to run the project). + // We need to check this in case the VM was recreated with a different target that is + // not compatible. + VmInfo preferredVm = null; + if (config.mVmName != null) { + preferredVm = vmManager.getVm(config.mVmName); + if (projectTarget.isCompatibleBaseFor(preferredVm.getTarget()) == false) { + preferredVm = null; + + AdtPlugin.printErrorToConsole(project, String.format( + "Preferred VM '%1$s' is not compatible with the project target '%2$s'. Looking for a compatible VM...", + config.mVmName, projectTarget.getName())); + } + } + + if (preferredVm != null) { + // look for a matching device + for (Device d : devices) { + String deviceVm = d.getVmName(); + if (deviceVm != null && deviceVm.equals(config.mVmName)) { + response.mustContinue = true; + response.mustLaunchEmulator = false; + response.deviceToUse = d; + + AdtPlugin.printToConsole(project, String.format( + "Automatic Target Mode: Preferred VM '%1$s' is available on emulator '%2$s'", + config.mVmName, d)); + + continueLaunch(response, project, launch, launchInfo, config); + return; + } + } + + // at this point we have a valid preferred VM that is not running. + // We need to start it. response.mustContinue = true; response.mustLaunchEmulator = true; + response.vmToLaunch = preferredVm; + + AdtPlugin.printToConsole(project, String.format( + "Automatic Target Mode: Preferred VM '%1$s' is not available. Launching new emulator.", + config.mVmName)); + continueLaunch(response, project, launch, launchInfo, config); return; - } else if (devices.length == 1) { + } + + // no (valid) preferred VM? look for one. + HashMap compatibleRunningVms = new HashMap(); + boolean hasDevice = false; // if there's 1+ device running, we may force manual mode, + // as we cannot always detect proper compatibility with + // devices. This is the case if the project target is not + // a standard platform + for (Device d : devices) { + String deviceVm = d.getVmName(); + if (deviceVm != null) { // physical devices return null. + VmInfo info = vmManager.getVm(deviceVm); + if (info != null && projectTarget.isCompatibleBaseFor(info.getTarget())) { + compatibleRunningVms.put(d, info); + } + } else { + if (projectTarget.isPlatform()) { // means this can run on any device as long + // as api level is high enough + String apiString = d.getProperty(SdkManager.PROP_VERSION_SDK); + try { + int apiNumber = Integer.parseInt(apiString); + if (apiNumber >= projectTarget.getApiVersionNumber()) { + // device is compatible with project + compatibleRunningVms.put(d, null); + continue; + } + } catch (NumberFormatException e) { + // do nothing, we'll consider it a non compatible device below. + } + } + hasDevice = true; + } + } + + // depending on the number of devices, we'll simulate an automatic choice + // from the device chooser or simply show up the device chooser. + if (hasDevice == false && compatibleRunningVms.size() == 0) { + // if zero emulators/devices, we launch an emulator. + // We need to figure out which VM first. + + // we are going to take the closest VM. ie a compatible VM that has the API level + // closest to the project target. + VmInfo[] vms = vmManager.getVms(); + VmInfo defaultVm = null; + for (VmInfo vm : vms) { + if (projectTarget.isCompatibleBaseFor(vm.getTarget())) { + if (defaultVm == null || + vm.getTarget().getApiVersionNumber() < + defaultVm.getTarget().getApiVersionNumber()) { + defaultVm = vm; + } + } + } + + if (defaultVm != null) { + response.mustContinue = true; + response.mustLaunchEmulator = true; + response.vmToLaunch = defaultVm; + + AdtPlugin.printToConsole(project, String.format( + "Automatic Target Mode: launching new emulator with compatible VM '%1$s'", + defaultVm.getName())); + + continueLaunch(response, project, launch, launchInfo, config); + return; + } else { + // FIXME: ask the user if he wants to create a VM. + // we found no compatible VM. + AdtPlugin.printErrorToConsole(project, String.format( + "Failed to find a VM compatible with target '%1$s'. Launch aborted.", + projectTarget.getName())); + launch.stopLaunch(); + return; + } + } else if (hasDevice == false && compatibleRunningVms.size() == 1) { + Entry e = compatibleRunningVms.entrySet().iterator().next(); response.mustContinue = true; response.mustLaunchEmulator = false; - response.deviceToUse = devices[0]; + response.deviceToUse = e.getKey(); - if (response.deviceToUse.isEmulator()) { - message = String.format("Automatic Target Mode: using existing emulator: %1$s", - response.deviceToUse); + // get the VmInfo, if null, the device is a physical device. + VmInfo vmInfo = e.getValue(); + if (vmInfo != null) { + message = String.format("Automatic Target Mode: using existing emulator '%1$s' running compatible VM '%2$s'", + response.deviceToUse, e.getValue().getName()); } else { - message = String.format("Automatic Target Mode: using existing device: %1$s", + message = String.format("Automatic Target Mode: using device '%1$s'", response.deviceToUse); } AdtPlugin.printToConsole(project, message); @@ -662,8 +801,13 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener } // if more than one device, we'll bring up the DeviceChooser dialog below. - AdtPlugin.printToConsole(project, - "Automatic Target Mode: user selection for 2+ devices."); + if (compatibleRunningVms.size() >= 2) { + message = "Automatic Target Mode: Several compatible targets. Please select a target device."; + } else if (hasDevice) { + message = "Automatic Target Mode: Unable to detect device compatibility. Please select a target device."; + } + + AdtPlugin.printToConsole(project, message); } // bring up the device chooser. @@ -671,7 +815,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener public void run() { DeviceChooserDialog dialog = new DeviceChooserDialog( AdtPlugin.getDisplay().getActiveShell()); - dialog.open(response, project, launch, launchInfo, config); + dialog.open(response, project, projectTarget, launch, launchInfo, config); } }); @@ -705,7 +849,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener synchronized (sListLock) { mWaitingForEmulatorLaunches.add(launchInfo); AdtPlugin.printToConsole(project, "Launching a new emulator."); - boolean status = launchEmulator(config); + boolean status = launchEmulator(config, response.vmToLaunch); if (status == false) { // launching the emulator failed! @@ -775,9 +919,6 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener * the device requires it and it is not set in the manifest, the launch will be forced to * "release" mode instead of "debug" *

    - * @param launchInfo - * @param device - * @return */ private boolean checkBuildInfo(DelayedLaunchInfo launchInfo, Device device) { if (device != null) { @@ -1122,7 +1263,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener /** * launches an application on a device or emulator * - * @param classToLaunch the fully-qualified name of the activity to launch + * @param info the {@link DelayedLaunchInfo} that indicates the activity to launch * @param device the device or emulator to launch the application on */ private void launchApp(final DelayedLaunchInfo info, Device device) { @@ -1182,7 +1323,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener } } - private boolean launchEmulator(AndroidLaunchConfiguration config) { + private boolean launchEmulator(AndroidLaunchConfiguration config, VmInfo vmToLaunch) { // split the custom command line in segments ArrayList customArgs = new ArrayList(); @@ -1212,10 +1353,8 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener ArrayList list = new ArrayList(); list.add(AdtPlugin.getOsAbsoluteEmulator()); - if (config.mSkin != null) { - list.add(FLAG_SKIN); - list.add(config.mSkin); - } + list.add(FLAG_VM); + list.add(vmToLaunch.getName()); if (config.mNetworkSpeed != null) { list.add(FLAG_NETSPEED); @@ -1329,7 +1468,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener * @param debugPort The port to connect the debugger to * @param androidLaunch The associated AndroidLaunch object. * @param monitor A Progress monitor - * @see connectRemoveDebugger() + * @see #connectRemoteDebugger(int, AndroidLaunch, IProgressMonitor) */ public static void launchRemoteDebugger( final int debugPort, final AndroidLaunch androidLaunch, final IProgressMonitor monitor) { @@ -1352,7 +1491,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener * This is sent from a non UI thread. * @param bridge the new {@link AndroidDebugBridge} object. * - * @see IDebugBridgeChangeListener#serverChanged(AndroidDebugBridge) + * @see IDebugBridgeChangeListener#bridgeChanged(AndroidDebugBridge) */ public void bridgeChanged(AndroidDebugBridge bridge) { // The adb server has changed. We cancel any pending launches. @@ -1447,7 +1586,7 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener * @param device the device that was updated. * @param changeMask the mask indicating what changed. * - * @see IDeviceChangeListener#deviceChanged(Device) + * @see IDeviceChangeListener#deviceChanged(Device, int) */ public void deviceChanged(Device device, int changeMask) { // We could check if any starting device we care about is now ready, but we can wait for @@ -1622,7 +1761,6 @@ public final class AndroidLaunchController implements IDebugBridgeChangeListener * Get the stderr/stdout outputs of a process and return when the process is done. * Both must be read or the process will block on windows. * @param process The process to get the ouput from - * @throws InterruptedException */ private void grabEmulatorOutput(final Process process) { // read the lines as they come. if null is returned, it's diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java index 2cb11c368..19ec9a7c3 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/DeviceChooserDialog.java @@ -19,6 +19,7 @@ package com.android.ide.eclipse.adt.debug.launching; import com.android.ddmlib.AndroidDebugBridge; import com.android.ddmlib.Client; import com.android.ddmlib.Device; +import com.android.ddmlib.IDevice; import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener; import com.android.ddmlib.Device.DeviceState; import com.android.ddmuilib.IImageLoader; @@ -27,7 +28,10 @@ import com.android.ddmuilib.TableHelper; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.debug.launching.AndroidLaunchController.AndroidLaunchConfiguration; import com.android.ide.eclipse.adt.debug.launching.AndroidLaunchController.DelayedLaunchInfo; +import com.android.ide.eclipse.adt.sdk.Sdk; import com.android.ide.eclipse.ddms.DdmsPlugin; +import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.vm.VmManager.VmInfo; import org.eclipse.core.resources.IProject; import org.eclipse.jface.preference.IPreferenceStore; @@ -67,19 +71,26 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener private final static String PREFS_COL_SERIAL = "deviceChooser.serial"; //$NON-NLS-1$ private final static String PREFS_COL_STATE = "deviceChooser.state"; //$NON-NLS-1$ - private final static String PREFS_COL_BUILD = "deviceChooser.build"; //$NON-NLS-1$ + private final static String PREFS_COL_VM = "deviceChooser.vm"; //$NON-NLS-1$ + private final static String PREFS_COL_TARGET = "deviceChooser.target"; //$NON-NLS-1$ + private final static String PREFS_COL_DEBUG = "deviceChooser.debug"; //$NON-NLS-1$ private Table mDeviceTable; private TableViewer mViewer; private Image mDeviceImage; private Image mEmulatorImage; + private Image mMatchImage; + private Image mNoMatchImage; + private Image mWarningImage; private Button mOkButton; private Button mCreateButton; private DeviceChooserResponse mResponse; private DelayedLaunchInfo mLaunchInfo; + private IAndroidTarget mProjectTarget; + private Sdk mSdk; /** * Basic Content Provider for a table full of {@link Device} objects. The input is @@ -111,13 +122,44 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener private class LabelProvider implements ITableLabelProvider { public Image getColumnImage(Object element, int columnIndex) { - if (columnIndex == 0 && element instanceof Device) { - if (((Device)element).isEmulator()) { - return mEmulatorImage; + if (element instanceof Device) { + Device device = (Device)element; + switch (columnIndex) { + case 0: + return device.isEmulator() ? mEmulatorImage : mDeviceImage; + + case 2: + // check for compatibility. + if (device.isEmulator() == false) { // physical device + // get the api level of the device + try { + String apiValue = device.getProperty( + IDevice.PROP_BUILD_VERSION_NUMBER); + int api = Integer.parseInt(apiValue); + if (api >= mProjectTarget.getApiVersionNumber()) { + // if the project is compiling against an add-on, the optional + // API may be missing from the device. + return mProjectTarget.isPlatform() ? + mMatchImage : mWarningImage; + } else { + return mNoMatchImage; + } + } catch (NumberFormatException e) { + // lets consider the device non compatible + return mNoMatchImage; + } + } else { + // get the VmInfo + VmInfo info = mSdk.getVmManager().getVm(device.getVmName()); + if (info == null) { + return mWarningImage; + } + return mProjectTarget.isCompatibleBaseFor(info.getTarget()) ? + mMatchImage : mNoMatchImage; + } } - - return mDeviceImage; } + return null; } @@ -128,15 +170,30 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener case 0: return device.getSerialNumber(); case 1: - return getStateString(device); - case 2: - String debuggable = device.getProperty(Device.PROP_DEBUGGABLE); - String version = device.getProperty(Device.PROP_BUILD_VERSION); - if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$ - return String.format("%1$s (debug)", version); //$NON-NLS-1$ + if (device.isEmulator()) { + return device.getVmName(); } else { - return String.format("%1$s", version); //$NON-NLS-1$ + return "N/A"; // devices don't have VM names. } + case 2: + if (device.isEmulator()) { + VmInfo info = mSdk.getVmManager().getVm(device.getVmName()); + if (info == null) { + return "?"; + } + return info.getTarget().getFullName(); + } else { + return device.getProperty(IDevice.PROP_BUILD_VERSION); + } + case 3: + String debuggable = device.getProperty(IDevice.PROP_DEBUGGABLE); + if (debuggable != null && debuggable.equals("1")) { //$NON-NLS-1$ + return "Yes"; + } else { + return ""; + } + case 4: + return getStateString(device); } } @@ -164,6 +221,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener public static class DeviceChooserResponse { public boolean mustContinue; public boolean mustLaunchEmulator; + public VmInfo vmToLaunch; public Device deviceToUse; } @@ -175,14 +233,18 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener * Prepare and display the dialog. * @param response * @param project + * @param projectTarget * @param launch * @param launchInfo * @param config */ public void open(DeviceChooserResponse response, IProject project, - AndroidLaunch launch, DelayedLaunchInfo launchInfo, AndroidLaunchConfiguration config) { + IAndroidTarget projectTarget, AndroidLaunch launch, DelayedLaunchInfo launchInfo, + AndroidLaunchConfiguration config) { mResponse = response; + mProjectTarget = projectTarget; mLaunchInfo = launchInfo; + mSdk = Sdk.getCurrent(); Shell parent = getParent(); Shell shell = new Shell(parent, getStyle()); @@ -218,6 +280,9 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener mEmulatorImage.dispose(); mDeviceImage.dispose(); + mMatchImage.dispose(); + mNoMatchImage.dispose(); + mWarningImage.dispose(); AndroidLaunchController.getInstance().continueLaunch(response, project, launch, launchInfo, config); @@ -249,14 +314,22 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener SWT.LEFT, "AAA+AAAAAAAAAAAAAAAAAAA", //$NON-NLS-1$ PREFS_COL_SERIAL, store); + TableHelper.createTableColumn(mDeviceTable, "VM Name", + SWT.LEFT, "engineering", //$NON-NLS-1$ + PREFS_COL_VM, store); + + TableHelper.createTableColumn(mDeviceTable, "Target", + SWT.LEFT, "AAA+Android 9.9.9", //$NON-NLS-1$ + PREFS_COL_TARGET, store); + + TableHelper.createTableColumn(mDeviceTable, "Debug", + SWT.LEFT, "Debug", //$NON-NLS-1$ + PREFS_COL_DEBUG, store); + TableHelper.createTableColumn(mDeviceTable, "State", SWT.LEFT, "bootloader", //$NON-NLS-1$ PREFS_COL_STATE, store); - TableHelper.createTableColumn(mDeviceTable, "Build Info", - SWT.LEFT, "engineering", //$NON-NLS-1$ - PREFS_COL_BUILD, store); - // create the viewer for it mViewer = new TableViewer(mDeviceTable); mViewer.setContentProvider(new ContentProvider()); @@ -357,20 +430,42 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener } private void loadImages() { - IImageLoader loader = DdmsPlugin.getImageLoader(); + IImageLoader ddmsLoader = DdmsPlugin.getImageLoader(); Display display = DdmsPlugin.getDisplay(); + IImageLoader adtLoader = AdtPlugin.getImageLoader(); if (mDeviceImage == null) { - mDeviceImage = ImageHelper.loadImage(loader, display, + mDeviceImage = ImageHelper.loadImage(ddmsLoader, display, "device.png", //$NON-NLS-1$ ICON_WIDTH, ICON_WIDTH, display.getSystemColor(SWT.COLOR_RED)); } if (mEmulatorImage == null) { - mEmulatorImage = ImageHelper.loadImage(loader, display, + mEmulatorImage = ImageHelper.loadImage(ddmsLoader, display, "emulator.png", ICON_WIDTH, ICON_WIDTH, //$NON-NLS-1$ display.getSystemColor(SWT.COLOR_BLUE)); } + + if (mMatchImage == null) { + mMatchImage = ImageHelper.loadImage(adtLoader, display, + "match.png", //$NON-NLS-1$ + ICON_WIDTH, ICON_WIDTH, + display.getSystemColor(SWT.COLOR_GREEN)); + } + + if (mNoMatchImage == null) { + mNoMatchImage = ImageHelper.loadImage(adtLoader, display, + "error.png", //$NON-NLS-1$ + ICON_WIDTH, ICON_WIDTH, + display.getSystemColor(SWT.COLOR_RED)); + } + + if (mWarningImage == null) { + mWarningImage = ImageHelper.loadImage(adtLoader, display, + "warning.png", //$NON-NLS-1$ + ICON_WIDTH, ICON_WIDTH, + display.getSystemColor(SWT.COLOR_YELLOW)); + } } @@ -438,7 +533,7 @@ public class DeviceChooserDialog extends Dialog implements IDeviceChangeListener * @param device the device that was updated. * @param changeMask the mask indicating what changed. * - * @see IDeviceChangeListener#deviceChanged(Device) + * @see IDeviceChangeListener#deviceChanged(Device, int) */ public void deviceChanged(final Device device, int changeMask) { if ((changeMask & (Device.CHANGE_STATE | Device.CHANGE_BUILD_INFO)) != 0) { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java index 5d3e349f6..68deec378 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/launching/LaunchConfigDelegate.java @@ -80,9 +80,8 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { */ public static final String ATTR_ACTIVITY = AdtPlugin.PLUGIN_ID + ".activity"; //$NON-NLS-1$ - /** Skin to be used to launch the emulator */ - public static final String ATTR_SKIN = AdtPlugin.PLUGIN_ID + ".skin"; //$NON-NLS-1$ - + public static final String ATTR_VM_NAME = AdtPlugin.PLUGIN_ID + ".vm"; //$NON-NLS-1$ + public static final String ATTR_SPEED = AdtPlugin.PLUGIN_ID + ".speed"; //$NON-NLS-1$ /** @@ -317,6 +316,10 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { 1 /* code, unused */, "Can't find the project!", null /* exception */)); } + /** + * {@inheritDoc} + * @throws CoreException + */ @Override public ILaunch getLaunch(ILaunchConfiguration configuration, String mode) throws CoreException { @@ -406,8 +409,6 @@ public class LaunchConfigDelegate extends LaunchConfigurationDelegate { /** * Returns the name of the activity. - * @param configuration - * @return */ private String getActivityName(ILaunchConfiguration configuration) { String empty = ""; diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java index c7b340c86..f4f5281c7 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/EmulatorConfigTab.java @@ -22,7 +22,9 @@ import com.android.ide.eclipse.adt.sdk.Sdk; import com.android.ide.eclipse.common.project.BaseProjectHelper; import com.android.ide.eclipse.ddms.DdmsPlugin; import com.android.sdklib.IAndroidTarget; -import com.android.sdklib.SdkConstants; +import com.android.sdklib.vm.VmManager; +import com.android.sdklib.vm.VmManager.VmInfo; +import com.android.sdkuilib.VmSelector; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; @@ -70,6 +72,11 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { { "UMTS", "umts" }, //$NON-NLS-2$ }; + private Button mAutoTargetButton; + private Button mManualTargetButton; + + private VmSelector mPreferredVmSelector; + private Combo mSpeedCombo; private Combo mDelayCombo; @@ -78,18 +85,10 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { private Text mEmulatorCLOptions; - private Combo mSkinCombo; - - private Button mAutoTargetButton; - - private Button mManualTargetButton; - private Button mWipeDataButton; private Button mNoBootAnimButton; - private IAndroidTarget mTarget; - /** * Returns the emulator ready speed option value. * @param value The index of the combo selection. @@ -147,6 +146,11 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { targetModeGroup.setLayout(layout); targetModeGroup.setFont(font); + mManualTargetButton = new Button(targetModeGroup, SWT.RADIO); + mManualTargetButton.setText("Manual"); + // Since there are only 2 radio buttons, we can put a listener on only one (they + // are both called on select and unselect event. + // add the radio button mAutoTargetButton = new Button(targetModeGroup, SWT.RADIO); mAutoTargetButton.setText("Automatic"); @@ -159,11 +163,16 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { } }); - mManualTargetButton = new Button(targetModeGroup, SWT.RADIO); - mManualTargetButton.setText("Manual"); - // Since there are only 2 radio buttons, we can put a listener on only - // one (they - // are both called on select and unselect event. + new Label(targetModeGroup, SWT.NONE).setText("Preferred VM"); + VmInfo[] vms = new VmInfo[0]; + mPreferredVmSelector = new VmSelector(targetModeGroup, vms, + false /*allowMultipleSelection*/); + mPreferredVmSelector.setSelectionListener(new SelectionAdapter() { + @Override + public void widgetSelected(SelectionEvent e) { + updateLaunchConfigurationDialog(); + } + }); // emulator size mEmulatorOptionsGroup = new Group(topComp, SWT.NONE); @@ -174,17 +183,6 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { mEmulatorOptionsGroup.setLayout(layout); mEmulatorOptionsGroup.setFont(font); - new Label(mEmulatorOptionsGroup, SWT.NONE).setText("Screen Size:"); - - mSkinCombo = new Combo(mEmulatorOptionsGroup, SWT.READ_ONLY); - mSkinCombo.addSelectionListener(new SelectionAdapter() { - // called when selection changes - @Override - public void widgetSelected(SelectionEvent e) { - updateLaunchConfigurationDialog(); - } - }); - // network options new Label(mEmulatorOptionsGroup, SWT.NONE).setText("Network Speed:"); @@ -279,8 +277,9 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { * @see org.eclipse.debug.ui.ILaunchConfigurationTab#initializeFrom(org.eclipse.debug.core.ILaunchConfiguration) */ public void initializeFrom(ILaunchConfiguration configuration) { - boolean value = LaunchConfigDelegate.DEFAULT_TARGET_MODE; // true == - // automatic + VmManager vmManager = Sdk.getCurrent().getVmManager(); + + boolean value = LaunchConfigDelegate.DEFAULT_TARGET_MODE; // true == automatic try { value = configuration.getAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE, value); } catch (CoreException e) { @@ -290,11 +289,12 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { mManualTargetButton.setSelection(!value); // look for the project name to get its target. - String projectName = ""; + String stringValue = ""; try { - projectName = configuration.getAttribute( - IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, projectName); + stringValue = configuration.getAttribute( + IJavaLaunchConfigurationConstants.ATTR_PROJECT_NAME, stringValue); } catch (CoreException ce) { + // let's not do anything here, we'll use the default value } IProject project = null; @@ -304,25 +304,41 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { if (projects != null) { // look for the project whose name we read from the configuration. for (IJavaProject p : projects) { - if (p.getElementName().equals(projectName)) { + if (p.getElementName().equals(stringValue)) { project = p.getProject(); break; } } } - mSkinCombo.removeAll(); + // update the VM list + VmInfo[] vms = null; + if (vmManager != null) { + vms = vmManager.getVms(); + } + + IAndroidTarget projectTarget = null; if (project != null) { - mTarget = Sdk.getCurrent().getTarget(project); - if (mTarget != null) { - String[] skins = mTarget.getSkins(); - if (skins != null) { - for (String skin : skins) { - mSkinCombo.add(skin); - } - mSkinCombo.pack(); - } - } + projectTarget = Sdk.getCurrent().getTarget(project); + } else { + vms = null; // no project? we don't want to display any "compatible" VMs. + } + + mPreferredVmSelector.setVms(vms, projectTarget); + + stringValue = ""; + try { + stringValue = configuration.getAttribute(LaunchConfigDelegate.ATTR_VM_NAME, + stringValue); + } catch (CoreException e) { + // let's not do anything here, we'll use the default value + } + + if (stringValue != null && stringValue.length() > 0 && vmManager != null) { + VmInfo targetVm = vmManager.getVm(stringValue); + mPreferredVmSelector.setSelection(targetVm); + } else { + mPreferredVmSelector.setSelection(null); } value = LaunchConfigDelegate.DEFAULT_WIPE_DATA; @@ -342,23 +358,6 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { mNoBootAnimButton.setSelection(value); int index = -1; - try { - String skin = configuration.getAttribute(LaunchConfigDelegate.ATTR_SKIN, (String)null); - if (skin == null) { - skin = SdkConstants.SKIN_DEFAULT; - } - - index = getSkinIndex(skin); - } catch (CoreException e) { - index = getSkinIndex(SdkConstants.SKIN_DEFAULT); - } - - if (index == -1) { - mSkinCombo.select(0); - updateLaunchConfigurationDialog(); - } else { - mSkinCombo.select(index); - } index = LaunchConfigDelegate.DEFAULT_SPEED; try { @@ -405,8 +404,12 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { public void performApply(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE, mAutoTargetButton.getSelection()); - configuration.setAttribute(LaunchConfigDelegate.ATTR_SKIN, - getSkinNameByIndex(mSkinCombo.getSelectionIndex())); + VmInfo vm = mPreferredVmSelector.getFirstSelected(); + if (vm != null) { + configuration.setAttribute(LaunchConfigDelegate.ATTR_VM_NAME, vm.getName()); + } else { + configuration.setAttribute(LaunchConfigDelegate.ATTR_VM_NAME, (String)null); + } configuration.setAttribute(LaunchConfigDelegate.ATTR_SPEED, mSpeedCombo.getSelectionIndex()); configuration.setAttribute(LaunchConfigDelegate.ATTR_DELAY, @@ -425,8 +428,6 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { public void setDefaults(ILaunchConfigurationWorkingCopy configuration) { configuration.setAttribute(LaunchConfigDelegate.ATTR_TARGET_MODE, LaunchConfigDelegate.DEFAULT_TARGET_MODE); - configuration.setAttribute(LaunchConfigDelegate.ATTR_SKIN, - SdkConstants.SKIN_DEFAULT); configuration.setAttribute(LaunchConfigDelegate.ATTR_SPEED, LaunchConfigDelegate.DEFAULT_SPEED); configuration.setAttribute(LaunchConfigDelegate.ATTR_DELAY, @@ -440,33 +441,4 @@ public class EmulatorConfigTab extends AbstractLaunchConfigurationTab { String emuOptions = store.getString(AdtPlugin.PREFS_EMU_OPTIONS); configuration.setAttribute(LaunchConfigDelegate.ATTR_COMMANDLINE, emuOptions); } - - private String getSkinNameByIndex(int index) { - if (mTarget != null && index > 0) { - String[] skins = mTarget.getSkins(); - if (skins != null && index < skins.length) { - return skins[index]; - } - } - - return null; - } - - private int getSkinIndex(String name) { - if (mTarget != null) { - String[] skins = mTarget.getSkins(); - if (skins != null) { - int index = 0; - for (String skin : skins) { - if (skin.equalsIgnoreCase(name)) { - return index; - } - index++; - } - } - } - - return -1; - } - } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java index af7f2bb17..6a40ed0f6 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/debug/ui/MainLaunchConfigTab.java @@ -398,11 +398,13 @@ public class MainLaunchConfigTab extends AbstractLaunchConfigurationTab { config.setMappedResources(resources); } - /** Loads the ui with the activities of the specified project, and store the - * activities in mActivities + /** + * Loads the ui with the activities of the specified project, and stores the + * activities in mActivities. + *

    * First activity is selected by default if present. - * @param project The project to load the activities from - * @return The array of activities or null if none could be found. + * + * @param project The project to load the activities from. */ private void loadActivities(IProject project) { if (project != null) { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java index 434269cd0..e64c2f4da 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/preferences/BuildPreferencePage.java @@ -199,7 +199,7 @@ public class BuildPreferencePage extends FieldEditorPreferencePage implements */ private void handleException(Throwable t) { String msg = t.getMessage(); - if (t == null) { + if (msg == null) { Throwable cause = t.getCause(); if (cause != null) { handleException(cause); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java index 1ca89cd90..7fc3318f2 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/FolderDecorator.java @@ -18,6 +18,7 @@ package com.android.ide.eclipse.adt.project; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.common.AndroidConstants; +import com.android.sdklib.SdkConstants; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; @@ -53,13 +54,13 @@ public class FolderDecorator implements ILightweightLabelDecorator { // check the folder is directly under the project. if (folder.getParent().getType() == IResource.PROJECT) { String name = folder.getName(); - if (name.equals(AndroidConstants.FD_ASSETS)) { + if (name.equals(SdkConstants.FD_ASSETS)) { decorate(decoration, " [Android assets]"); decoration.addOverlay(mDescriptor, IDecoration.TOP_RIGHT); - } else if (name.equals(AndroidConstants.FD_RESOURCES)) { + } else if (name.equals(SdkConstants.FD_RESOURCES)) { decorate(decoration, " [Android resources]"); decoration.addOverlay(mDescriptor, IDecoration.TOP_RIGHT); - } else if (name.equals(AndroidConstants.FD_NATIVE_LIBS)) { + } else if (name.equals(SdkConstants.FD_NATIVE_LIBS)) { decorate(decoration, " [Native Libraries]"); } } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java index de4b3394b..399eac958 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ExportWizard.java @@ -493,7 +493,7 @@ public final class ExportWizard extends Wizard implements IExportWizard { } // no more cause and still no message. display the first exception. - return cause.getClass().getCanonicalName(); + return t.getClass().getCanonicalName(); } return message; diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java index 3614be389..e161e1887 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/export/ProjectCheckPage.java @@ -256,7 +256,6 @@ final class ProjectCheckPage extends ExportWizardPage { /** * Checks the parameters for correctness, and update the error message and buttons. - * @return the current IProject of this launch config. */ private void handleProjectNameChange() { setPageComplete(false); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java index 2cafa01b3..4da216cd4 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/project/internal/AndroidClasspathContainerInitializer.java @@ -28,8 +28,12 @@ import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.Path; +import org.eclipse.core.runtime.Status; +import org.eclipse.core.runtime.jobs.Job; import org.eclipse.jdt.core.ClasspathContainerInitializer; import org.eclipse.jdt.core.IAccessRule; import org.eclipse.jdt.core.IClasspathAttribute; @@ -125,7 +129,7 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit */ private static IClasspathContainer allocateAndroidContainer(String containerId, IJavaProject javaProject) { - IProject iProject = javaProject.getProject(); + final IProject iProject = javaProject.getProject(); // remove potential MARKER_TARGETs. try { @@ -139,7 +143,9 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit } - // first we check if the SDK has been loaded + // First we check if the SDK has been loaded. + // By passing the javaProject to getSdkLoadStatus(), we ensure that, should the SDK + // not be loaded yet, the classpath container will be resolved again once the SDK is loaded. boolean sdkIsLoaded = AdtPlugin.getDefault().getSdkLoadStatus(javaProject) == LoadStatus.LOADED; @@ -172,8 +178,14 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit String message = null; boolean outputToConsole = true; if (hashString == null || hashString.length() == 0) { - message = String.format( - "Project has no target set. Edit the project properties to set one."); + // if there is no hash string we only show this if the SDK is loaded. + // For a project opened at start-up with no target, this would be displayed twice, + // once when the project is opened, and once after the SDK has finished loading. + // By testing the sdk is loaded, we only show this once in the console. + if (sdkIsLoaded) { + message = String.format( + "Project has no target set. Edit the project properties to set one."); + } } else if (sdkIsLoaded) { message = String.format( "Unable to resolve target '%s'", hashString); @@ -187,23 +199,41 @@ public class AndroidClasspathContainerInitializer extends ClasspathContainerInit // and it's expected. (we do keep the error marker though). outputToConsole = false; } + + if (message != null) { + // log the error and put the marker on the project if we can. + if (outputToConsole) { + AdtPlugin.printBuildToConsole(AdtConstants.BUILD_ALWAYS, iProject, message); + } + + try { + BaseProjectHelper.addMarker(iProject, AdtConstants.MARKER_TARGET, message, -1, + IMarker.SEVERITY_ERROR, IMarker.PRIORITY_HIGH); + } catch (CoreException e) { + // In some cases, the workspace may be locked for modification when we pass here. + // We schedule a new job to put the marker after. + final String fmessage = message; + Job markerJob = new Job("Android SDK: Resolving error markers") { + @SuppressWarnings("unchecked") + @Override + protected IStatus run(IProgressMonitor monitor) { + try { + BaseProjectHelper.addMarker(iProject, AdtConstants.MARKER_TARGET, + fmessage, -1, IMarker.SEVERITY_ERROR, IMarker.PRIORITY_HIGH); + } catch (CoreException e2) { + return e2.getStatus(); + } - // log the error and put the marker on the project - if (outputToConsole) { - AdtPlugin.printBuildToConsole(AdtConstants.BUILD_ALWAYS, iProject, message); + return Status.OK_STATUS; + } + }; + + // build jobs are run after other interactive jobs + markerJob.setPriority(Job.BUILD); + markerJob.schedule(); + } } - IMarker marker = BaseProjectHelper.addMarker(iProject, AdtConstants.MARKER_TARGET, message, - IMarker.SEVERITY_ERROR); - - // add a marker priority as this is an more important error than the error that will - // spring from the lack of library - try { - marker.setAttribute(IMarker.PRIORITY, IMarker.PRIORITY_HIGH); - } catch (CoreException e) { - // just log the error - AdtPlugin.log(e, "Error changing target marker priority."); - } - + // return a dummy container to replace the one we may have had before. return new IClasspathContainer() { public IClasspathEntry[] getClasspathEntries() { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java index fad4f1957..1f6ebf1e7 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidJarLoader.java @@ -37,7 +37,8 @@ import javax.management.InvalidAttributeValueException; public class AndroidJarLoader extends ClassLoader implements IAndroidClassLoader { /** - * Wrapper around a {@link Class} to provide the methods of {@link IClassDescriptor}. + * Wrapper around a {@link Class} to provide the methods of + * {@link IAndroidClassLoader.IClassDescriptor}. */ public final static class ClassWrapper implements IClassDescriptor { private Class mClass; @@ -416,7 +417,7 @@ public class AndroidJarLoader extends ClassLoader implements IAndroidClassLoader } /** - * Returns a {@link IClass} by its fully-qualified name. + * Returns a {@link IAndroidClassLoader.IClassDescriptor} by its fully-qualified name. * @param className the fully-qualified name of the class to return. * @throws ClassNotFoundException */ diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java index 232b9e891..dfe876f7f 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/AndroidTargetParser.java @@ -82,11 +82,8 @@ public final class AndroidTargetParser { /** * Parses the framework, collects all interesting information and stores them in the - * {@link FrameworkResourceManager} given to the constructor. + * {@link IAndroidTarget} given to the constructor. * - * @param osSdkPath the OS path of the SDK directory. - * @param resourceManager the {@link FrameworkResourceManager} that will store the parsed - * resources. * @param monitor A progress monitor. Can be null. Caller is responsible for calling done. * @return True if the SDK path was valid and parsing has been attempted. */ @@ -400,7 +397,6 @@ public final class AndroidTargetParser { * Loads and collects the action and category default values from the framework. * The values are added to the actions and categories lists. * - * @param osLibPath The OS path to the SDK tools/lib folder, ending with a separator. * @param activityActions the list which will receive the activity action values. * @param broadcastActions the list which will receive the broadcast action values. * @param serviceActions the list which will receive the service action values. diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java index 50d319e4e..35057d1d3 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/IAndroidClassLoader.java @@ -64,7 +64,7 @@ public interface IAndroidClassLoader { throws IOException, InvalidAttributeValueException, ClassFormatError; /** - * Returns a {@link IClass} by its fully-qualified name. + * Returns a {@link IClassDescriptor} by its fully-qualified name. * @param className the fully-qualified name of the class to return. * @throws ClassNotFoundException */ 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 3b9d10e1f..19f8f4508 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 @@ -18,17 +18,17 @@ package com.android.ide.eclipse.adt.sdk; import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.adt.project.internal.AndroidClasspathContainerInitializer; +import com.android.prefs.AndroidLocation.AndroidLocationException; import com.android.sdklib.IAndroidTarget; import com.android.sdklib.ISdkLog; import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; import com.android.sdklib.project.ProjectProperties; +import com.android.sdklib.project.ProjectProperties.PropertyType; +import com.android.sdklib.vm.VmManager; import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IStatus; -import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.jdt.core.IJavaProject; import org.eclipse.jdt.core.JavaCore; @@ -46,21 +46,20 @@ import java.util.HashMap; * To start using an SDK, call {@link #loadSdk(String)} which returns the instance of * the Sdk object. * - * To get the list of platforms present in the SDK, call {@link #getPlatforms()}. - * To get the list of add-ons present in the SDK, call {@link #getAddons()}. - * + * To get the list of platforms or add-ons present in the SDK, call {@link #getTargets()}. */ public class Sdk { - private final static String PROPERTY_PROJECT_TARGET = "androidTarget"; //$NON-NLS-1$ - private static Sdk sCurrentSdk = null; private final SdkManager mManager; + private final VmManager mVmManager; + private final HashMap mProjectMap = new HashMap(); private final HashMap mTargetMap = new HashMap(); private final String mDocBaseUrl; + /** * Loads an SDK and returns an {@link Sdk} object if success. @@ -74,18 +73,33 @@ public class Sdk { final ArrayList logMessages = new ArrayList(); ISdkLog log = new ISdkLog() { - public void error(String errorFormat, Object... arg) { - logMessages.add(String.format(errorFormat, arg)); + public void error(Throwable throwable, String errorFormat, Object... arg) { + if (errorFormat != null) { + logMessages.add(String.format(errorFormat, arg)); + } + + if (throwable != null) { + 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)); + } }; // get an SdkManager object for the location SdkManager manager = SdkManager.createManager(sdkLocation, log); if (manager != null) { - sCurrentSdk = new Sdk(manager); + VmManager vmManager = null; + try { + vmManager = new VmManager(manager, log); + } catch (AndroidLocationException e) { + log.error(e, "Error parsing the VMs"); + } + sCurrentSdk = new Sdk(manager, vmManager); return sCurrentSdk; } else { StringBuilder sb = new StringBuilder("Error Loading the SDK:\n"); @@ -105,6 +119,13 @@ public class Sdk { return sCurrentSdk; } + /** + * Returns the location (OS path) of the current SDK. + */ + public String getSdkLocation() { + return mManager.getLocation(); + } + /** * Returns the URL to the local documentation. * Can return null if no documentation is found in the current SDK. @@ -181,7 +202,8 @@ public class Sdk { */ public static String getProjectTargetHashString(IProject project) { // load the default.properties from the project folder. - ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString()); + ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(), + PropertyType.DEFAULT); if (properties == null) { AdtPlugin.log(IStatus.ERROR, "Failed to load properties file for project '%s'", project.getName()); @@ -200,10 +222,12 @@ public class Sdk { public static void setProjectTargetHashString(IProject project, String targetHashString) { // because we don't want to erase other properties from default.properties, we first load // them - ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString()); + ProjectProperties properties = ProjectProperties.load(project.getLocation().toOSString(), + PropertyType.DEFAULT); if (properties == null) { // doesn't exist yet? we create it. - properties = ProjectProperties.create(project.getLocation().toOSString()); + properties = ProjectProperties.create(project.getLocation().toOSString(), + PropertyType.DEFAULT); } // add/change the target hash string. @@ -218,7 +242,7 @@ public class Sdk { } } /** - * Return the {@link PlatformData} for a given {@link IAndroidTarget}. + * Return the {@link AndroidTargetData} for a given {@link IAndroidTarget}. */ public AndroidTargetData getTargetData(IAndroidTarget target) { synchronized (mTargetMap) { @@ -226,8 +250,17 @@ public class Sdk { } } - private Sdk(SdkManager manager) { + /** + * Returns the {@link VmManager}. If the VmManager failed to parse the VM folder, this could + * be null. + */ + public VmManager getVmManager() { + return mVmManager; + } + + private Sdk(SdkManager manager, VmManager vmManager) { mManager = manager; + mVmManager = vmManager; // pre-compute some paths mDocBaseUrl = getDocumentationBaseUrl(mManager.getLocation() + diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java index 8db09f24a..0e60f8a4e 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/sdk/WidgetClassLoader.java @@ -323,7 +323,7 @@ public final class WidgetClassLoader implements IAndroidClassLoader { } /** - * Returns a {@link IClass} by its fully-qualified name. + * Returns a {@link IAndroidClassLoader.IClassDescriptor} by its fully-qualified name. * @param className the fully-qualified name of the class to return. * @throws ClassNotFoundException */ diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java index 8044bcb79..7fc94efd8 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectCreationPage.java @@ -26,6 +26,7 @@ import com.android.ide.eclipse.adt.sdk.Sdk; import com.android.ide.eclipse.common.AndroidConstants; import com.android.ide.eclipse.common.project.AndroidManifestHelper; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; import com.android.sdkuilib.SdkTargetSelector; import org.eclipse.core.filesystem.URIUtil; @@ -64,9 +65,11 @@ import java.util.regex.Pattern; * NewAndroidProjectCreationPage is a project creation page that provides the * following fields: *

      + *
    • Project name + *
    • SDK Target + *
    • Application name *
    • Package name *
    • Activity name - *
    • Location of the SDK *
    * Note: this class is public so that it can be accessed from unit tests. * It is however an internal class. Its API may change without notice. @@ -93,13 +96,14 @@ public class NewProjectCreationPage extends WizardPage { private static final Pattern sProjectNamePattern = Pattern.compile("^[\\w][\\w. -]*$"); //$NON-NLS-1$ /** Last user-browsed location, static so that it be remembered for the whole session */ private static String sCustomLocationOsPath = ""; //$NON-NLS-1$ + private static boolean sAutoComputeCustomLocation = true; private final int MSG_NONE = 0; private final int MSG_WARNING = 1; private final int MSG_ERROR = 2; private String mUserPackageName = ""; //$NON-NLS-1$ - private String mUserActivityName = ""; //$NON-NLS-1$ + private String mUserActivityName = ""; //$NON-NLS-1$ private boolean mUserCreateActivityCheck = INITIAL_CREATE_ACTIVITY; private String mSourceFolder = ""; //$NON-NLS-1$ @@ -114,6 +118,8 @@ public class NewProjectCreationPage extends WizardPage { private Text mLocationPathField; private Button mBrowseButton; private Button mCreateActivityCheck; + private Text mMinSdkVersionField; + private SdkTargetSelector mSdkTargetSelector; private boolean mInternalLocationPathUpdate; protected boolean mInternalProjectNameUpdate; @@ -122,7 +128,7 @@ public class NewProjectCreationPage extends WizardPage { private boolean mInternalActivityNameUpdate; protected boolean mProjectNameModifiedByUser; protected boolean mApplicationNameModifiedByUser; - private SdkTargetSelector mSdkTargetSelector; + private boolean mInternalMinSdkVersionUpdate; /** @@ -133,13 +139,6 @@ public class NewProjectCreationPage extends WizardPage { public NewProjectCreationPage(String pageName) { super(pageName); setPageComplete(false); - if (sCustomLocationOsPath == null || - sCustomLocationOsPath.length() == 0 || - !new File(sCustomLocationOsPath).isDirectory()) { - // FIXME location of samples is pretty much impossible here. - //sCustomLocationOsPath = AdtPlugin.getOsSdkSamplesFolder(); - sCustomLocationOsPath = File.listRoots()[0].getAbsolutePath(); - } } // --- Getters used by NewProjectWizard --- @@ -170,6 +169,11 @@ public class NewProjectCreationPage extends WizardPage { return mActivityNameField == null ? INITIAL_NAME : mActivityNameField.getText().trim(); } + /** Returns the value of the min sdk version field with spaces trimmed. */ + public String getMinSdkVersion() { + return mMinSdkVersionField == null ? "" : mMinSdkVersionField.getText().trim(); + } + /** Returns the value of the application name field with spaces trimmed. */ public String getApplicationName() { // Return the name of the activity as default application name. @@ -200,7 +204,7 @@ public class NewProjectCreationPage extends WizardPage { * "src" constant. */ public String getSourceFolder() { if (isNewProject() || mSourceFolder == null || mSourceFolder.length() == 0) { - return AndroidConstants.FD_SOURCES; + return SdkConstants.FD_SOURCES; } else { return mSourceFolder; } @@ -389,9 +393,16 @@ public class NewProjectCreationPage extends WizardPage { } mSdkTargetSelector = new SdkTargetSelector(group, targets, false /*multi-selection*/); + + // If there's only one target, select it + if (targets != null && targets.length == 1) { + mSdkTargetSelector.setSelection(targets[0]); + } + mSdkTargetSelector.setSelectionListener(new SelectionAdapter() { @Override public void widgetSelected(SelectionEvent e) { + updateLocationPathField(null); setPageComplete(validatePage()); } }); @@ -506,6 +517,25 @@ public class NewProjectCreationPage extends WizardPage { onActivityNameFieldModified(); } }); + + // min sdk version label + label = new Label(group, SWT.NONE); + label.setText("Min SDK Version:"); + label.setFont(parent.getFont()); + label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty."); + + // min sdk version entry field + mMinSdkVersionField = new Text(group, SWT.BORDER); + data = new GridData(GridData.FILL_HORIZONTAL); + label.setToolTipText("The minimum SDK version number that the application requires. Must be an integer > 0. It can be empty."); + mMinSdkVersionField.setLayoutData(data); + mMinSdkVersionField.setFont(parent.getFont()); + mMinSdkVersionField.addListener(SWT.Modify, new Listener() { + public void handleEvent(Event event) { + onMinSdkVersionFieldModified(); + setPageComplete(validatePage()); + } + }); } @@ -588,7 +618,29 @@ public class NewProjectCreationPage extends WizardPage { mInternalLocationPathUpdate = true; if (custom_location) { if (abs_dir != null) { + // We get here if the user selected a directory with the "Browse" button. + // Disable auto-compute of the custom location unless the user selected + // the exact same path. + sAutoComputeCustomLocation = sAutoComputeCustomLocation && + abs_dir.equals(sCustomLocationOsPath); sCustomLocationOsPath = TextProcessor.process(abs_dir); + } else if (sAutoComputeCustomLocation || + !new File(sCustomLocationOsPath).isDirectory()) { + // By default select the samples directory of the current target + IAndroidTarget target = getSdkTarget(); + if (target != null) { + sCustomLocationOsPath = target.getPath(IAndroidTarget.SAMPLES); + } + + // If we don't have a target, select the base directory of the + // "universal sdk". If we don't even have that, use a root drive. + if (sCustomLocationOsPath == null || sCustomLocationOsPath.length() == 0) { + if (Sdk.getCurrent() != null) { + sCustomLocationOsPath = Sdk.getCurrent().getSdkLocation(); + } else { + sCustomLocationOsPath = File.listRoots()[0].getAbsolutePath(); + } + } } if (!mLocationPathField.getText().equals(sCustomLocationOsPath)) { mLocationPathField.setText(sCustomLocationOsPath); @@ -615,8 +667,13 @@ public class NewProjectCreationPage extends WizardPage { private void onLocationPathFieldModified() { if (!mInternalLocationPathUpdate) { // When the updates doesn't come from updateLocationPathField, it must be the user - // editing the field manually, in which case we want to save the value internally. - sCustomLocationOsPath = getLocationPathFieldValue(); + // editing the field manually, in which case we want to save the value internally + // and we disable auto-compute of the custom location (to avoid overriding the user + // value) + String newPath = getLocationPathFieldValue(); + sAutoComputeCustomLocation = sAutoComputeCustomLocation && + newPath.equals(sCustomLocationOsPath); + sCustomLocationOsPath = newPath; extractNamesFromAndroidManifest(); setPageComplete(validatePage()); } @@ -664,6 +721,31 @@ public class NewProjectCreationPage extends WizardPage { } } + /** + * Called when the min sdk version field has been modified. + * + * Ignore the internal modifications. When modified by the user, try to match + * a target with the same API level. + */ + private void onMinSdkVersionFieldModified() { + if (mInternalMinSdkVersionUpdate) { + return; + } + + try { + int version = Integer.parseInt(getMinSdkVersion()); + + for (IAndroidTarget target : mSdkTargetSelector.getTargets()) { + if (target.getApiVersionNumber() == version) { + mSdkTargetSelector.setSelection(target); + break; + } + } + } catch (NumberFormatException e) { + // ignore + } + } + /** * Called when the radio buttons are changed between the "create new project" and the * "use existing source" mode. This reverts the fields to whatever the user manually @@ -697,89 +779,132 @@ public class NewProjectCreationPage extends WizardPage { * can actually be found in the custom user directory. */ private void extractNamesFromAndroidManifest() { - if (!isNewProject()) { - File f = new File(getProjectLocation()); - if (f.isDirectory()) { - Path path = new Path(f.getPath()); - String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString(); - AndroidManifestHelper manifest = new AndroidManifestHelper(osPath); - if (manifest.exists()) { - String packageName = null; - String activityName = null; - try { - packageName = manifest.getPackageName(); - activityName = manifest.getActivityName(1); - } catch (Exception e) { - // pass - } + if (isNewProject()) { + return; + } + + String projectLocation = getProjectLocation(); + File f = new File(projectLocation); + if (!f.isDirectory()) { + return; + } + + Path path = new Path(f.getPath()); + String osPath = path.append(AndroidConstants.FN_ANDROID_MANIFEST).toOSString(); + AndroidManifestHelper manifest = new AndroidManifestHelper(osPath); + if (!manifest.exists()) { + return; + } + + String packageName = null; + String activityName = null; + String minSdkVersion = null; + try { + packageName = manifest.getPackageName(); + activityName = manifest.getActivityName(1); + minSdkVersion = manifest.getMinSdkVersion(); + } catch (Exception e) { + // ignore exceptions + } - if (packageName != null && packageName.length() > 0) { - mPackageNameField.setText(packageName); - } + if (packageName != null && packageName.length() > 0) { + mPackageNameField.setText(packageName); + } - if (activityName != null && activityName.length() > 0) { - mInternalActivityNameUpdate = true; - mInternalCreateActivityUpdate = true; - mActivityNameField.setText(activityName); - mCreateActivityCheck.setSelection(true); - mInternalCreateActivityUpdate = false; - mInternalActivityNameUpdate = false; + if (activityName != null && activityName.length() > 0) { + mInternalActivityNameUpdate = true; + mInternalCreateActivityUpdate = true; + mActivityNameField.setText(activityName); + mCreateActivityCheck.setSelection(true); + mInternalCreateActivityUpdate = false; + mInternalActivityNameUpdate = false; - // If project name and application names are empty, use the activity - // name as a default. If the activity name has dots, it's a part of a - // package specification and only the last identifier must be used. - if (activityName.indexOf('.') != -1) { - String[] ids = activityName.split(AndroidConstants.RE_DOT); - activityName = ids[ids.length - 1]; - } - if (mProjectNameField.getText().length() == 0 || - !mProjectNameModifiedByUser) { - mInternalProjectNameUpdate = true; - mProjectNameField.setText(activityName); - mInternalProjectNameUpdate = false; - } - if (mApplicationNameField.getText().length() == 0 || - !mApplicationNameModifiedByUser) { - mInternalApplicationNameUpdate = true; - mApplicationNameField.setText(activityName); - mInternalApplicationNameUpdate = false; - } - } else { - mInternalActivityNameUpdate = true; - mInternalCreateActivityUpdate = true; - mActivityNameField.setText(""); - mCreateActivityCheck.setSelection(false); - mInternalCreateActivityUpdate = false; - mInternalActivityNameUpdate = false; - - // There is no activity name to use to fill in the project and application - // name. However if there's a package name, we can use this as a base. - if (packageName != null && packageName.length() > 0) { - // Package name is a java identifier, so it's most suitable for - // an application name. + // If project name and application names are empty, use the activity + // name as a default. If the activity name has dots, it's a part of a + // package specification and only the last identifier must be used. + if (activityName.indexOf('.') != -1) { + String[] ids = activityName.split(AndroidConstants.RE_DOT); + activityName = ids[ids.length - 1]; + } + if (mProjectNameField.getText().length() == 0 || + !mProjectNameModifiedByUser) { + mInternalProjectNameUpdate = true; + mProjectNameField.setText(activityName); + mInternalProjectNameUpdate = false; + } + if (mApplicationNameField.getText().length() == 0 || + !mApplicationNameModifiedByUser) { + mInternalApplicationNameUpdate = true; + mApplicationNameField.setText(activityName); + mInternalApplicationNameUpdate = false; + } + } else { + mInternalActivityNameUpdate = true; + mInternalCreateActivityUpdate = true; + mActivityNameField.setText(""); //$NON-NLS-1$ + mCreateActivityCheck.setSelection(false); + mInternalCreateActivityUpdate = false; + mInternalActivityNameUpdate = false; + + // There is no activity name to use to fill in the project and application + // name. However if there's a package name, we can use this as a base. + if (packageName != null && packageName.length() > 0) { + // Package name is a java identifier, so it's most suitable for + // an application name. - if (mApplicationNameField.getText().length() == 0 || - !mApplicationNameModifiedByUser) { - mInternalApplicationNameUpdate = true; - mApplicationNameField.setText(packageName); - mInternalApplicationNameUpdate = false; - } + if (mApplicationNameField.getText().length() == 0 || + !mApplicationNameModifiedByUser) { + mInternalApplicationNameUpdate = true; + mApplicationNameField.setText(packageName); + mInternalApplicationNameUpdate = false; + } - // For the project name, remove any dots - packageName = packageName.replace('.', '_'); - if (mProjectNameField.getText().length() == 0 || - !mProjectNameModifiedByUser) { - mInternalProjectNameUpdate = true; - mProjectNameField.setText(packageName); - mInternalProjectNameUpdate = false; - } - - } + // For the project name, remove any dots + packageName = packageName.replace('.', '_'); + if (mProjectNameField.getText().length() == 0 || + !mProjectNameModifiedByUser) { + mInternalProjectNameUpdate = true; + mProjectNameField.setText(packageName); + mInternalProjectNameUpdate = false; + } + + } + } + + // Select the target matching the manifest's sdk, if any + boolean foundTarget = false; + if (minSdkVersion != null) { + try { + int sdkVersion = Integer.parseInt(minSdkVersion); + + for (IAndroidTarget target : mSdkTargetSelector.getTargets()) { + if (target.getApiVersionNumber() == sdkVersion) { + mSdkTargetSelector.setSelection(target); + foundTarget = true; + break; } } + } catch(NumberFormatException e) { + // ignore } } + + if (!foundTarget) { + for (IAndroidTarget target : mSdkTargetSelector.getTargets()) { + if (projectLocation.startsWith(target.getLocation())) { + mSdkTargetSelector.setSelection(target); + foundTarget = true; + break; + } + } + } + + if (!foundTarget) { + mInternalMinSdkVersionUpdate = true; + mMinSdkVersionField.setText(minSdkVersion == null ? "" : minSdkVersion); //$NON-NLS-1$ + mInternalMinSdkVersionUpdate = false; + } } /** @@ -804,6 +929,9 @@ public class NewProjectCreationPage extends WizardPage { if ((status & MSG_ERROR) == 0) { status |= validateActivityField(); } + if ((status & MSG_ERROR) == 0) { + status |= validateMinSdkVersionField(); + } if ((status & MSG_ERROR) == 0) { status |= validateSourceFolder(); } @@ -949,6 +1077,38 @@ public class NewProjectCreationPage extends WizardPage { return MSG_NONE; } + /** + * Validates the sdk target choice. + * + * @return The wizard message type, one of MSG_ERROR, MSG_WARNING or MSG_NONE. + */ + private int validateMinSdkVersionField() { + + // If the min sdk version is empty, it is always accepted. + if (getMinSdkVersion().length() == 0) { + return MSG_NONE; + } + + int version = -1; + try { + // If not empty, it must be a valid integer > 0 + version = Integer.parseInt(getMinSdkVersion()); + } catch (NumberFormatException e) { + // ignore + } + + if (version < 1) { + return setStatus("Min SDK Version must be an integer > 0.", MSG_ERROR); + } + + if (getSdkTarget() != null && getSdkTarget().getApiVersionNumber() != version) { + return setStatus("The API level for the selected SDK target does not match the Min SDK version.", + MSG_WARNING); + } + + return MSG_NONE; + } + /** * Validates the activity name field. * diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java index a58221777..607159aed 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/wizards/newproject/NewProjectWizard.java @@ -22,6 +22,7 @@ import com.android.ide.eclipse.adt.project.ProjectHelper; import com.android.ide.eclipse.adt.sdk.Sdk; import com.android.ide.eclipse.common.AndroidConstants; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -85,32 +86,36 @@ public class NewProjectWizard extends Wizard implements INewWizard { private static final String PARAM_IS_NEW_PROJECT = "IS_NEW_PROJECT"; //$NON-NLS-1$ private static final String PARAM_SRC_FOLDER = "SRC_FOLDER"; //$NON-NLS-1$ private static final String PARAM_SDK_TARGET = "SDK_TARGET"; //$NON-NLS-1$ + private static final String PARAM_MIN_SDK_VERSION = "MIN_SDK_VERSION"; //$NON-NLS-1$ private static final String PH_ACTIVITIES = "ACTIVITIES"; //$NON-NLS-1$ + private static final String PH_USES_SDK = "USES-SDK"; //$NON-NLS-1$ private static final String PH_INTENT_FILTERS = "INTENT_FILTERS"; //$NON-NLS-1$ private static final String PH_STRINGS = "STRINGS"; //$NON-NLS-1$ private static final String BIN_DIRECTORY = - AndroidConstants.FD_BINARIES + AndroidConstants.WS_SEP; + SdkConstants.FD_OUTPUT + AndroidConstants.WS_SEP; private static final String RES_DIRECTORY = - AndroidConstants.FD_RESOURCES + AndroidConstants.WS_SEP; + SdkConstants.FD_RESOURCES + AndroidConstants.WS_SEP; private static final String ASSETS_DIRECTORY = - AndroidConstants.FD_ASSETS + AndroidConstants.WS_SEP; + SdkConstants.FD_ASSETS + AndroidConstants.WS_SEP; private static final String DRAWABLE_DIRECTORY = - AndroidConstants.FD_DRAWABLE + AndroidConstants.WS_SEP; + SdkConstants.FD_DRAWABLE + AndroidConstants.WS_SEP; private static final String LAYOUT_DIRECTORY = - AndroidConstants.FD_LAYOUT + AndroidConstants.WS_SEP; + SdkConstants.FD_LAYOUT + AndroidConstants.WS_SEP; private static final String VALUES_DIRECTORY = - AndroidConstants.FD_VALUES + AndroidConstants.WS_SEP; + SdkConstants.FD_VALUES + AndroidConstants.WS_SEP; private static final String TEMPLATES_DIRECTORY = "templates/"; //$NON-NLS-1$ private static final String TEMPLATE_MANIFEST = TEMPLATES_DIRECTORY + "AndroidManifest.template"; //$NON-NLS-1$ private static final String TEMPLATE_ACTIVITIES = TEMPLATES_DIRECTORY + "activity.template"; //$NON-NLS-1$ + private static final String TEMPLATE_USES_SDK = TEMPLATES_DIRECTORY + + "uses-sdk.template"; //$NON-NLS-1$ private static final String TEMPLATE_INTENT_LAUNCHER = TEMPLATES_DIRECTORY + "launcher_intent_filter.template"; //$NON-NLS-1$ - + private static final String TEMPLATE_STRINGS = TEMPLATES_DIRECTORY + "strings.template"; //$NON-NLS-1$ private static final String TEMPLATE_STRING = TEMPLATES_DIRECTORY @@ -235,6 +240,7 @@ public class NewProjectWizard extends Wizard implements INewWizard { parameters.put(PARAM_IS_NEW_PROJECT, mMainPage.isNewProject()); parameters.put(PARAM_SRC_FOLDER, mMainPage.getSourceFolder()); parameters.put(PARAM_SDK_TARGET, mMainPage.getSdkTarget()); + parameters.put(PARAM_MIN_SDK_VERSION, mMainPage.getMinSdkVersion()); if (mMainPage.isCreateActivity()) { // An activity name can be of the form ".package.Class" or ".Class". @@ -449,6 +455,15 @@ public class NewProjectWizard extends Wizard implements INewWizard { // remove the activity(ies) from the manifest manifestTemplate = manifestTemplate.replaceAll(PH_ACTIVITIES, ""); } + + String minSdkVersion = (String) parameters.get(PARAM_MIN_SDK_VERSION); + if (minSdkVersion != null && minSdkVersion.length() > 0) { + String usesSdkTemplate = AdtPlugin.readEmbeddedTextFile(TEMPLATE_USES_SDK); + String usesSdk = replaceParameters(usesSdkTemplate, parameters); + manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, usesSdk); + } else { + manifestTemplate = manifestTemplate.replaceAll(PH_USES_SDK, ""); + } // Save in the project as UTF-8 InputStream stream = new ByteArrayInputStream( 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 f3f7b7941..0e780a982 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 @@ -130,48 +130,14 @@ public class AndroidConstants { public final static String FN_TRACEVIEW = (CURRENT_PLATFORM == PLATFORM_WINDOWS) ? "traceview.exe" : "traceview"; //$NON-NLS-1$ //$NON-NLS-2$ - /** Folder Names for Android Projects . */ - - /* Resources folder name, i.e. "res". */ - public final static String FD_RESOURCES = "res"; //$NON-NLS-1$ - /** Assets folder name, i.e. "assets" */ - public final static String FD_ASSETS = "assets"; //$NON-NLS-1$ - /** Default source folder name, i.e. "src" */ - public final static String FD_SOURCES = "src"; //$NON-NLS-1$ - /** Default native library folder name inside the project, i.e. "libs" - * While the folder inside the .apk is "lib", we call that one libs because - * that's what we use in ant for both .jar and .so and we need to make the 2 development ways - * compatible. */ - public final static String FD_NATIVE_LIBS = "libs"; //$NON-NLS-1$ - /** Native lib folder inside the APK: "lib" */ - public final static String FD_APK_NATIVE_LIBS = "lib"; //$NON-NLS-1$ - /** Default bin folder name, i.e. "bin" */ - public final static String FD_BINARIES = "bin"; //$NON-NLS-1$ - /** Default anim resource folder name, i.e. "anim" */ - public final static String FD_ANIM = "anim"; //$NON-NLS-1$ - /** Default color resource folder name, i.e. "color" */ - public final static String FD_COLOR = "color"; //$NON-NLS-1$ - /** Default drawable resource folder name, i.e. "drawable" */ - public final static String FD_DRAWABLE = "drawable"; //$NON-NLS-1$ - /** Default layout resource folder name, i.e. "layout" */ - public final static String FD_LAYOUT = "layout"; //$NON-NLS-1$ - /** Default menu resource folder name, i.e. "menu" */ - public final static String FD_MENU = "menu"; //$NON-NLS-1$ - /** Default values resource folder name, i.e. "values" */ - public final static String FD_VALUES = "values"; //$NON-NLS-1$ - /** Default xml resource folder name, i.e. "xml" */ - public final static String FD_XML = "xml"; //$NON-NLS-1$ - /** Default raw resource folder name, i.e. "raw" */ - public final static String FD_RAW = "raw"; //$NON-NLS-1$ - /** Absolute path of the workspace root, i.e. "/" */ public final static String WS_ROOT = WS_SEP; /** Absolute path of the resource folder, eg "/res".
    This is a workspace path. */ - public final static String WS_RESOURCES = WS_SEP + FD_RESOURCES; + public final static String WS_RESOURCES = WS_SEP + SdkConstants.FD_RESOURCES; /** Absolute path of the resource folder, eg "/assets".
    This is a workspace path. */ - public final static String WS_ASSETS = WS_SEP + FD_ASSETS; + public final static String WS_ASSETS = WS_SEP + SdkConstants.FD_ASSETS; /** Leaf of the javaDoc folder. Does not start with a separator. */ public final static String WS_JAVADOC_FOLDER_LEAF = SdkConstants.FD_DOCS + "/reference"; //$NON-NLS-1$ diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java index 2db9e9b51..cd238d2bf 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/AndroidManifestHelper.java @@ -97,7 +97,7 @@ public class AndroidManifestHelper { */ public String getPackageName() { try { - return getPackageNameInternal(mXPath, getSource()); + return mXPath.evaluate("/manifest/@package", getSource()); //$NON-NLS-1$ } catch (XPathExpressionException e1) { // If the XPath failed to evaluate, we'll return null. } catch (Exception e) { @@ -110,18 +110,40 @@ public class AndroidManifestHelper { return null; } + /** + * Returns the minSdkVersion defined in the manifest file. + * + * @return A String object with the package or null if any error happened. + */ + public String getMinSdkVersion() { + try { + return mXPath.evaluate("/manifest/uses-sdk/@" //$NON-NLS-1$ + + AndroidXPathFactory.DEFAULT_NS_PREFIX + + ":minSdkVersion", getSource()); //$NON-NLS-1$ + } catch (XPathExpressionException e1) { + // If the XPath failed to evaluate, we'll return null. + } catch (Exception e) { + // if this happens this is due to the resource being out of sync. + // so we must refresh it and do it again + + // for any other kind of exception we must return null as well; + } + + return null; + } /** * Returns the i-th activity defined in the manifest file. * - * @param manifest The manifest's IFile object. * @param index The 1-based index of the activity to return. - * @param xpath An optional xpath object. If null is provided a new one will - * be created. * @return A String object with the activity or null if any error happened. */ public String getActivityName(int index) { try { - return getActivityNameInternal(index, mXPath, getSource()); + return mXPath.evaluate("/manifest/application/activity[" //$NON-NLS-1$ + + index + + "]/@" //$NON-NLS-1$ + + AndroidXPathFactory.DEFAULT_NS_PREFIX +":name", //$NON-NLS-1$ + getSource()); } catch (XPathExpressionException e1) { // If the XPath failed to evaluate, we'll return null. } catch (Exception e) { @@ -216,26 +238,4 @@ public class AndroidManifestHelper { return null; } - /** - * Performs the actual XPath evaluation to get the package name. - * Extracted so that we can share it with AndroidManifestFromProject. - */ - private static String getPackageNameInternal(XPath xpath, InputSource source) - throws XPathExpressionException { - return xpath.evaluate("/manifest/@package", source); //$NON-NLS-1$ - } - - /** - * Performs the actual XPath evaluation to get the activity name. - * Extracted so that we can share it with AndroidManifestFromProject. - */ - private static String getActivityNameInternal(int index, XPath xpath, InputSource source) - throws XPathExpressionException { - return xpath.evaluate("/manifest/application/activity[" //$NON-NLS-1$ - + index - + "]/@" //$NON-NLS-1$ - + AndroidXPathFactory.DEFAULT_NS_PREFIX +":name", //$NON-NLS-1$ - source); - } - } 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 cb98525f1..2866ce21f 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 @@ -319,7 +319,7 @@ public class AndroidManifestParser { * @see org.xml.sax.helpers.DefaultHandler#error(org.xml.sax.SAXParseException) */ @Override - public void error(SAXParseException e) throws SAXException { + public void error(SAXParseException e) { if (mMarkErrors) { handleError(e, e.getLineNumber()); } @@ -329,7 +329,7 @@ public class AndroidManifestParser { * @see org.xml.sax.helpers.DefaultHandler#fatalError(org.xml.sax.SAXParseException) */ @Override - public void fatalError(SAXParseException e) throws SAXException { + public void fatalError(SAXParseException e) { if (mMarkErrors) { handleError(e, e.getLineNumber()); } @@ -348,7 +348,6 @@ public class AndroidManifestParser { /** * Processes the activity node. * @param attributes the attributes for the activity node. - * @throws CoreException */ private void processActivityNode(Attributes attributes) { // lets get the activity name, and add it to the list @@ -381,7 +380,6 @@ public class AndroidManifestParser { * @param attributes the attributes for the activity node. * @param superClassName the fully qualified name of the super class that this * node is representing - * @throws CoreException */ private void processNode(Attributes attributes, String superClassName) { // lets get the class name, and check it if required. @@ -567,12 +565,11 @@ public class AndroidManifestParser { /** * Parses the manifest file, collects data, and checks for errors. * @param javaProject The java project. Required. - * @param manifestFile + * @param manifestFile The manifest file to parse. * @param errorListener the {@link XmlErrorListener} object being notified of the presence * of errors. Optional. * @return an {@link AndroidManifestParser} or null if the parsing failed. * @throws CoreException - * @see {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)} */ public static AndroidManifestParser parseForError(IJavaProject javaProject, IFile manifestFile, XmlErrorListener errorListener) throws CoreException { @@ -581,12 +578,9 @@ public class AndroidManifestParser { /** * Parses the manifest file, and collects data. - * @param manifestFile - * @param errorListener the {@link XmlErrorListener} object being notified of the presence - * of errors. Optional. + * @param manifestFile The manifest file to parse. * @return an {@link AndroidManifestParser} or null if the parsing failed. * @throws CoreException - * @see {@link #parse(IJavaProject, IFile, XmlErrorListener, boolean, boolean)} */ public static AndroidManifestParser parseForData(IFile manifestFile) throws CoreException { return parse(null /* javaProject */, manifestFile, null /* errorListener */, 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 530c89e57..8544b25ff 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 @@ -39,7 +39,7 @@ public class AndroidXPathFactory { /** * Construct the context with the prefix associated with the android namespace. - * @param prefix the Prefix + * @param androidPrefix the Prefix */ public AndroidNamespaceContext(String androidPrefix) { mAndroidPrefix = androidPrefix; @@ -71,7 +71,7 @@ public class AndroidXPathFactory { /** * Creates a new XPath object, specifying which prefix in the query is used for the * android namespace. - * @param prefix The namespace prefix. + * @param androidPrefix The namespace prefix. */ public static XPath newXPath(String androidPrefix) { XPath xpath = sFactory.newXPath(); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java index c69e875a3..bd8b44420 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/BaseProjectHelper.java @@ -82,11 +82,13 @@ public final class BaseProjectHelper { } /** - * Adds a marker to a file on a specific line + * Adds a marker to a file on a specific line. This methods catches thrown + * {@link CoreException}, and returns null instead. * @param file the file to be marked * @param markerId The id of the marker to add. * @param message the message associated with the mark - * @param lineNumber the line number where to put the mark + * @param lineNumber the line number where to put the mark. If line is < 1, it puts the marker + * on line 1. * @param severity the severity of the marker. * @return the IMarker that was added or null if it failed to add one. */ @@ -96,7 +98,7 @@ public final class BaseProjectHelper { IMarker marker = file.createMarker(markerId); marker.setAttribute(IMarker.MESSAGE, message); marker.setAttribute(IMarker.SEVERITY, severity); - if (lineNumber == -1) { + if (lineNumber < 1) { lineNumber = 1; } marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); @@ -108,7 +110,7 @@ public final class BaseProjectHelper { return marker; } catch (CoreException e) { - AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'", + AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'", //$NON-NLS-1$ markerId, file.getFullPath()); } @@ -116,7 +118,8 @@ public final class BaseProjectHelper { } /** - * Adds a marker to a resource. + * Adds a marker to a resource. This methods catches thrown {@link CoreException}, + * and returns null instead. * @param resource the file to be marked * @param markerId The id of the marker to add. * @param message the message associated with the mark @@ -129,7 +132,7 @@ public final class BaseProjectHelper { IMarker marker = resource.createMarker(markerId); marker.setAttribute(IMarker.MESSAGE, message); marker.setAttribute(IMarker.SEVERITY, severity); - + // on Windows, when adding a marker to a project, it takes a refresh for the marker // to show. In order to fix this we're forcing a refresh of elements receiving // markers (and only the element, not its children), to force the marker display. @@ -137,13 +140,43 @@ public final class BaseProjectHelper { return marker; } catch (CoreException e) { - AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'", + AdtPlugin.log(e, "Failed to add marker '%1$s' to '%2$s'", //$NON-NLS-1$ markerId, resource.getFullPath()); } return null; } - + + /** + * Adds a marker to a resource. This method does not catch {@link CoreException} and instead + * throw them. + * @param resource the file to be marked + * @param markerId The id of the marker to add. + * @param message the message associated with the mark + * @param lineNumber the line number where to put the mark if != -1. + * @param severity the severity of the marker. + * @param priority the priority of the marker + * @return the IMarker that was added. + * @throws CoreException + */ + public final static IMarker addMarker(IResource resource, String markerId, + String message, int lineNumber, int severity, int priority) throws CoreException { + IMarker marker = resource.createMarker(markerId); + marker.setAttribute(IMarker.MESSAGE, message); + marker.setAttribute(IMarker.SEVERITY, severity); + if (lineNumber != -1) { + marker.setAttribute(IMarker.LINE_NUMBER, lineNumber); + } + marker.setAttribute(IMarker.PRIORITY, priority); + + // on Windows, when adding a marker to a project, it takes a refresh for the marker + // to show. In order to fix this we're forcing a refresh of elements receiving + // markers (and only the element, not its children), to force the marker display. + resource.refreshLocal(IResource.DEPTH_ZERO, new NullProgressMonitor()); + + return marker; + } + /** * Tests that a class name is valid for usage in the manifest. *

    diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java index 26fbf42c7..fda55c450 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/project/XmlErrorHandler.java @@ -62,6 +62,7 @@ public class XmlErrorHandler extends DefaultHandler { /** * Xml Error call back * @param exception the parsing exception + * @throws SAXException */ @Override public void error(SAXParseException exception) throws SAXException { @@ -71,6 +72,7 @@ public class XmlErrorHandler extends DefaultHandler { /** * Xml Fatal Error call back * @param exception the parsing exception + * @throws SAXException */ @Override public void fatalError(SAXParseException exception) throws SAXException { @@ -80,6 +82,7 @@ public class XmlErrorHandler extends DefaultHandler { /** * Xml Warning call back * @param exception the parsing exception + * @throws SAXException */ @Override public void warning(SAXParseException exception) throws SAXException { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java index 3176c8e29..3875e81f5 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/AttrsXmlParser.java @@ -20,6 +20,7 @@ import com.android.ide.eclipse.adt.AdtPlugin; import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo; import com.android.ide.eclipse.common.resources.DeclareStyleableInfo.AttributeInfo.Format; import com.android.ide.eclipse.common.resources.ViewClassInfo.LayoutParamsInfo; +import com.android.ide.eclipse.editors.descriptors.DescriptorsUtils; import org.eclipse.core.runtime.IStatus; import org.w3c.dom.Document; @@ -228,7 +229,7 @@ public final class AttrsXmlParser { } mStyleMap.put(name, style); if (lastComment != null) { - style.setJavaDoc(formatJavadoc(lastComment.getNodeValue())); + style.setJavaDoc(parseJavadoc(lastComment.getNodeValue())); } } } @@ -263,14 +264,15 @@ public final class AttrsXmlParser { } if (info != null) { if (lastComment != null) { - info.setJavaDoc(formatJavadoc(lastComment.getNodeValue())); + info.setJavaDoc(parseJavadoc(lastComment.getNodeValue())); + info.setDeprecatedDoc(parseDeprecatedDoc(lastComment.getNodeValue())); } } } } return info; } - + /** * Finds all the attributes for a particular style node, * e.g. a declare-styleable of name "TextView" or "LinearLayout_Layout". @@ -431,16 +433,23 @@ public final class AttrsXmlParser { } /** - * Formats the javadoc. + * Parses the javadoc comment. * Only keeps the first sentence. - * Removes and simplifies links and references. + *

    + * This does not remove nor simplify links and references. Such a transformation + * is done later at "display" time in {@link DescriptorsUtils#formatTooltip(String)} and co. */ - private String formatJavadoc(String comment) { + private String parseJavadoc(String comment) { if (comment == null) { return null; } + // sanitize & collapse whitespace comment = comment.replaceAll("\\s+", " "); //$NON-NLS-1$ //$NON-NLS-2$ + + // Explicitly remove any @deprecated tags since they are handled separately. + comment = comment.replaceAll("(?:\\{@deprecated[^}]*\\}|@deprecated[^@}]*)", ""); + // take everything up to the first dot that is followed by a space or the end of the line. // I love regexps :-). For the curious, the regexp is: // - start of line @@ -456,6 +465,41 @@ public final class AttrsXmlParser { // - followed by a space (?= non-capturing zero-width positive look-ahead) // - anything else is ignored comment = comment.replaceFirst("^\\s*(.*?(?:$|(?= 0) { + comment = comment.substring(pos + 12 /* len of {@deprecated */); + comment = comment.replaceFirst("^([^}]*).*", "$1"); + } else if ((pos = comment.indexOf("@deprecated")) >= 0) { + comment = comment.substring(pos + 11 /* len of @deprecated */); + comment = comment.replaceFirst("^(.*?)(?:@.*|$)", "$1"); + } else { + return null; + } + + return comment.trim(); + } } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java index 6cff62c5e..efa5981b5 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/common/resources/DeclareStyleableInfo.java @@ -55,8 +55,10 @@ public class DeclareStyleableInfo { private String[] mEnumValues; /** Values for flag. null for other types. */ private String[] mFlagValues; - /** Short javadoc */ + /** Short javadoc (i.e. the first sentence). */ private String mJavaDoc; + /** Documentation for deprecated attributes. Null if not deprecated. */ + private String mDeprecatedDoc; /** * @param name The XML Name of the attribute @@ -74,6 +76,7 @@ public class DeclareStyleableInfo { mEnumValues = info.mEnumValues; mFlagValues = info.mFlagValues; mJavaDoc = info.mJavaDoc; + mDeprecatedDoc = info.mDeprecatedDoc; } /** Returns the XML Name of the attribute */ @@ -93,10 +96,14 @@ public class DeclareStyleableInfo { public String[] getFlagValues() { return mFlagValues; } - /** Returns a short javadoc */ + /** Returns a short javadoc, .i.e. the first sentence. */ public String getJavaDoc() { return mJavaDoc; } + /** Returns the documentation for deprecated attributes. Null if not deprecated. */ + public String getDeprecatedDoc() { + return mDeprecatedDoc; + } /** Sets the values for enums. null for other types. */ public void setEnumValues(String[] values) { @@ -106,10 +113,14 @@ public class DeclareStyleableInfo { public void setFlagValues(String[] values) { mFlagValues = values; } - /** Sets a short javadoc */ + /** Sets a short javadoc, .i.e. the first sentence. */ public void setJavaDoc(String javaDoc) { mJavaDoc = javaDoc; } + /** Sets the documentation for deprecated attributes. Null if not deprecated. */ + public void setDeprecatedDoc(String deprecatedDoc) { + mDeprecatedDoc = deprecatedDoc; + } } 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 d1b4547b7..50d3d2856 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 @@ -91,7 +91,12 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { /** * Constructor for AndroidContentAssist - * @param rootElementDescriptors The valid root elements of the XML hierarchy + * @param descriptorId An id for {@link AndroidTargetData#getDescriptorProvider(int)}. + * The Id can be one of {@link AndroidTargetData#DESCRIPTOR_MANIFEST}, + * {@link AndroidTargetData#DESCRIPTOR_LAYOUT}, + * {@link AndroidTargetData#DESCRIPTOR_MENU}, + * or {@link AndroidTargetData#DESCRIPTOR_XML}. + * All other values will throw an {@link IllegalArgumentException} later at runtime. */ public AndroidContentAssist(int descriptorId) { mDescriptorId = descriptorId; @@ -723,7 +728,6 @@ public abstract class AndroidContentAssist implements IContentAssistProcessor { /** * Computes (if needed) and returns the root descriptor. - * @return */ private ElementDescriptor getRootDescriptor() { if (mRootDescriptor == null) { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java index 78e04019f..dca7db09e 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/AndroidEditor.java @@ -722,7 +722,7 @@ public abstract class AndroidEditor extends FormEditor implements IResourceChang } /** - * Returns the {@link PlatformData} for the edited file. + * Returns the {@link AndroidTargetData} for the edited file. */ public AndroidTargetData getTargetData() { IProject project = getProject(); 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 2c779b278..70d03a19b 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 @@ -38,6 +38,7 @@ public abstract class AttributeDescriptor { private String mXmlLocalName; private ElementDescriptor mParent; private final String mNsUri; + private boolean mDeprecated; /** * Creates a new {@link AttributeDescriptor} @@ -70,6 +71,14 @@ public abstract class AttributeDescriptor { return mParent; } + public void setDeprecated(boolean isDeprecated) { + mDeprecated = isDeprecated; + } + + public boolean isDeprecated() { + return mDeprecated; + } + /** * Returns an optional icon for the attribute. *

    diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java index 05ae922b2..2729565b6 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/descriptors/AttributeDescriptorLabelProvider.java @@ -16,6 +16,7 @@ package com.android.ide.eclipse.editors.descriptors; +import com.android.ide.eclipse.editors.IconFactory; import com.android.ide.eclipse.editors.uimodel.UiAbstractTextAttributeNode; import org.eclipse.jface.viewers.ILabelProvider; @@ -35,6 +36,17 @@ public class AttributeDescriptorLabelProvider implements ILabelProvider { } public Image getImage(Object element) { + if (element instanceof UiAbstractTextAttributeNode) { + UiAbstractTextAttributeNode node = (UiAbstractTextAttributeNode) element; + if (node.getDescriptor().isDeprecated()) { + String v = node.getCurrentValue(); + if (v != null && v.length() > 0) { + IconFactory factory = IconFactory.getInstance(); + return factory.getIcon("warning"); //$NON-NLS-1$ + } + } + } + return null; } 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 c84bf5786..09f147833 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 @@ -92,8 +92,9 @@ public final class DescriptorsUtils { * @param nsUri The URI of the attribute. Can be null if attribute has no namespace. * See {@link AndroidConstants#NS_RESOURCES} for a common value. * @param infos The array of {@link AttributeInfo} to read and append to attributes - * @param requiredAttributes An optional list of attributes to mark as "required" (i.e. append - * a "*" to their UI name as a hint for the user.) + * @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 + * entries in the form "elem-name/attr-name". Elem-name can be "*". * @param overrides A map [attribute name => TextAttributeDescriptor creator]. A creator * can either by a Class or an instance of * {@link ITextAttributeCreator} that instantiates the right TextAttributeDescriptor. @@ -101,16 +102,15 @@ public final class DescriptorsUtils { public static void appendAttributes(ArrayList attributes, String elementXmlName, String nsUri, AttributeInfo[] infos, - String[] requiredAttributes, + Set requiredAttributes, Map overrides) { for (AttributeInfo info : infos) { boolean required = false; if (requiredAttributes != null) { - for(String attr_name : requiredAttributes) { - if (attr_name.equals(info.getName())) { - required = true; - break; - } + String attr_name = info.getName(); + if (requiredAttributes.contains("*/" + attr_name) || + requiredAttributes.contains(elementXmlName + "/" + attr_name)) { + required = true; } } appendAttribute(attributes, elementXmlName, nsUri, info, required, overrides); @@ -144,7 +144,26 @@ public final class DescriptorsUtils { if (required) { uiName += "*"; //$NON-NLS-1$ } - String tooltip = formatTooltip(info.getJavaDoc()); // tooltip + + String tooltip = null; + String rawTooltip = info.getJavaDoc(); + if (rawTooltip == null) { + rawTooltip = ""; + } + + String deprecated = info.getDeprecatedDoc(); + if (deprecated != null) { + if (rawTooltip.length() > 0) { + rawTooltip += "@@"; //$NON-NLS-1$ insert a break + } + rawTooltip += "* Deprecated"; + if (deprecated.length() != 0) { + rawTooltip += ": " + deprecated; //$NON-NLS-1$ + } + if (deprecated.length() == 0 || !deprecated.endsWith(".")) { //$NON-NLS-1$ + rawTooltip += "."; //$NON-NLS-1$ + } + } // Add the known types to the tooltip Format[] formats_list = info.getFormats(); @@ -154,11 +173,14 @@ public final class DescriptorsUtils { HashSet formats_set = new HashSet(); StringBuilder sb = new StringBuilder(); - if (tooltip != null) { - sb.append(tooltip); - sb.append(" "); //$NON-NLS-1$ + if (rawTooltip != null && rawTooltip.length() > 0) { + sb.append(rawTooltip); + sb.append(" "); //$NON-NLS-1$ } - sb.append("["); //$NON-NLS-1$ + if (sb.length() > 0) { + sb.append("@@"); //$NON-NLS-1$ @@ inserts a break before the types + } + sb.append("["); //$NON-NLS-1$ for (int i = 0; i < flen; i++) { Format f = formats_list[i]; formats_set.add(f); @@ -172,19 +194,21 @@ public final class DescriptorsUtils { sb.append("]"); //$NON-NLS-1$ if (required) { - sb.append(". Required."); + sb.append(".@@* "); //$NON-NLS-1$ @@ inserts a break. + sb.append("Required."); } // The extra space at the end makes the tooltip more readable on Windows. sb.append(" "); //$NON-NLS-1$ - tooltip = sb.toString(); + rawTooltip = sb.toString(); + tooltip = formatTooltip(rawTooltip); // Create a specialized attribute if we can if (overrides != null) { for (Entry entry: overrides.entrySet()) { String key = entry.getKey(); - String elements[] = key.split("/"); + String elements[] = key.split("/"); //$NON-NLS-1$ String overrideAttrLocalName = null; if (elements.length < 1) { continue; @@ -193,7 +217,7 @@ public final class DescriptorsUtils { elements = null; } else { overrideAttrLocalName = elements[elements.length - 1]; - elements = elements[0].split(","); + elements = elements[0].split(","); //$NON-NLS-1$ } if (overrideAttrLocalName == null || @@ -204,7 +228,8 @@ public final class DescriptorsUtils { boolean ok_element = elements.length < 1; if (!ok_element) { for (String element : elements) { - if (element.equals("*") || element.equals(elementXmlName)) { + if (element.equals("*") //$NON-NLS-1$ + || element.equals(elementXmlName)) { ok_element = true; break; } @@ -271,8 +296,12 @@ public final class DescriptorsUtils { // By default a simple text field is used if (attr == null) { + if (tooltip == null) { + tooltip = formatTooltip(rawTooltip); + } attr = new TextAttributeDescriptor(xmlLocalName, uiName, nsUri, tooltip); } + attr.setDeprecated(info.getDeprecatedDoc() != null); attributes.add(attr); } @@ -582,6 +611,8 @@ public final class DescriptorsUtils { Pattern p_code = Pattern.compile("(.+?)(.*)"); //$NON-NLS-1$ // Detects @blah@, used in hard-coded tooltip descriptors Pattern p_elem = Pattern.compile("@([\\w -]+)@(.*)"); //$NON-NLS-1$ + // Detects a buffer that starts by @@ (request for a break) + Pattern p_break = Pattern.compile("@@(.*)"); //$NON-NLS-1$ // Detects a buffer that starts by @ < or { (one that was not matched above) Pattern p_open = Pattern.compile("([@<\\{])(.*)"); //$NON-NLS-1$ // Detects everything till the next potential separator, i.e. @ < or { @@ -616,6 +647,10 @@ public final class DescriptorsUtils { if (text != null) { currentLength += text.length() - 2; } + } else if ((m = p_break.matcher(javadoc)).matches()) { + spans.add(BREAK); + currentLength = 0; + javadoc = m.group(1); } else if ((m = p_open.matcher(javadoc)).matches()) { s = m.group(1); javadoc = m.group(2); 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 632471dfa..a9d2b2e65 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 @@ -95,6 +95,10 @@ public class TextAttributeDescriptor extends AttributeDescriptor implements IPro } public String getCategory() { + if (isDeprecated()) { + return "Deprecated"; + } + ElementDescriptor parent = getParent(); if (parent != null) { return parent.getUiName(); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java index c5126255c..381539be4 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/layout/BasePullParser.java @@ -20,7 +20,6 @@ import com.android.layoutlib.api.IXmlPullParser; import org.xmlpull.v1.XmlPullParserException; -import java.io.IOException; import java.io.InputStream; import java.io.Reader; @@ -178,7 +177,7 @@ public abstract class BasePullParser implements IXmlPullParser { return mParsingState; } - public int nextTag() throws XmlPullParserException, IOException { + public int nextTag() throws XmlPullParserException { int eventType = next(); if (eventType != START_TAG && eventType != END_TAG) { throw new XmlPullParserException("expected start or end tag", this, null); @@ -186,7 +185,7 @@ public abstract class BasePullParser implements IXmlPullParser { return eventType; } - public String nextText() throws XmlPullParserException, IOException { + public String nextText() throws XmlPullParserException { if (getEventType() != START_TAG) { throw new XmlPullParserException("parser must be on START_TAG to read next text", this, null); @@ -208,7 +207,7 @@ public abstract class BasePullParser implements IXmlPullParser { } } - public int nextToken() throws XmlPullParserException, IOException { + public int nextToken() throws XmlPullParserException { return next(); } 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 87a14ad55..a0b30ecab 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 @@ -33,8 +33,10 @@ import org.eclipse.core.runtime.IStatus; import java.util.ArrayList; import java.util.HashMap; +import java.util.HashSet; import java.util.Iterator; import java.util.Map; +import java.util.Set; import java.util.TreeSet; import java.util.Map.Entry; @@ -166,7 +168,13 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { "android", //$NON-NLS-1$ AndroidConstants.NS_RESOURCES); + // -- setup the required attributes overrides -- + + Set required = new HashSet(); + required.add("provider/authorities"); //$NON-NLS-1$ + // -- setup the various attribute format overrides -- + // The key for each override is "element1,element2,.../attr-xml-local-name" or // "*/attr-xml-local-name" to match the attribute in any element. @@ -181,7 +189,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { tooltip); } }); - + overrides.put("*/theme", ThemeAttributeDescriptor.class); //$NON-NLS-1$ overrides.put("*/permission", ListAttributeDescriptor.class); //$NON-NLS-1$ overrides.put("*/targetPackage", PackageAttributeDescriptor.class); //$NON-NLS-1$ @@ -212,8 +220,12 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { // -- - inflateElement(manifestMap, overrides, elementDescs, - MANIFEST_ELEMENT, "AndroidManifest"); //$NON-NLS-1$ + inflateElement(manifestMap, + overrides, + required, + elementDescs, + MANIFEST_ELEMENT, + "AndroidManifest"); //$NON-NLS-1$ insertAttribute(MANIFEST_ELEMENT, PACKAGE_ATTR_DESC); sanityCheck(manifestMap, MANIFEST_ELEMENT); @@ -312,16 +324,17 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { * "Inflates" the properties of an {@link ElementDescriptor} from the styleable declaration. *

    * This first creates all the attributes for the given ElementDescriptor. - * It then find all children of the descriptor, inflate them recursively and set them + * It then finds all children of the descriptor, inflate them recursively and set them * as child to this ElementDescriptor. * - * @param styleMap The input styleable map for manifest elements & attributes + * @param styleMap The input styleable map for manifest elements & attributes. * @param overrides A list of attribute overrides (to customize the type of the attribute - * descriptors) + * descriptors). + * @param requiredAttributes Set of attributes to be marked as required. * @param existingElementDescs A map of already created element descriptors, keyed by * XML local name. This is used to use the static elements created initially by this * class, which are referenced directly by editors (so that reloading an SDK won't - * break these references) + * break these references). * @param elemDesc The current {@link ElementDescriptor} to inflate. * @param styleName The name of the {@link ElementDescriptor} to inflate. Its XML local name * will be guessed automatically from the style name. @@ -329,6 +342,7 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { private void inflateElement( Map styleMap, Map overrides, + Set requiredAttributes, HashMap existingElementDescs, ElementDescriptor elemDesc, String styleName) { @@ -342,7 +356,9 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { DescriptorsUtils.appendAttributes(attrDescs, elemDesc.getXmlLocalName(), AndroidConstants.NS_RESOURCES, - style.getAttributes(), null, overrides); + style.getAttributes(), + requiredAttributes, + overrides); elemDesc.setTooltip(style.getJavaDoc()); elemDesc.setAttributes(attrDescs.toArray(new AttributeDescriptor[attrDescs.size()])); } @@ -373,7 +389,12 @@ public final class AndroidManifestDescriptors implements IDescriptorProvider { } children.add(child); - inflateElement(styleMap, overrides, existingElementDescs, child, childStyleName); + inflateElement(styleMap, + overrides, + requiredAttributes, + existingElementDescs, + child, + childStyleName); } } elemDesc.setChildren(children.toArray(new ElementDescriptor[children.size()])); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java index 1d01260cf..9a61d1781 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/CountryCodeQualifier.java @@ -66,7 +66,7 @@ public final class CountryCodeQualifier extends ResourceQualifier { /** * Returns the folder name segment for the given value. This is equivalent to calling * {@link #toString()} on a {@link CountryCodeQualifier} object. - * @param value the value of the qualifier, as returned by {@link #getCode()}. + * @param code the value of the qualifier, as returned by {@link #getCode()}. */ public static String getFolderSegment(int code) { if (code != DEFAULT_CODE && code >= 100 && code <=999) { // code is 3 digit.) { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java index ce527a43d..7e30901fd 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/NetworkCodeQualifier.java @@ -66,7 +66,7 @@ public final class NetworkCodeQualifier extends ResourceQualifier { /** * Returns the folder name segment for the given value. This is equivalent to calling * {@link #toString()} on a {@link NetworkCodeQualifier} object. - * @param value the value of the qualifier, as returned by {@link #getCode()}. + * @param code the value of the qualifier, as returned by {@link #getCode()}. */ public static String getFolderSegment(int code) { if (code != DEFAULT_CODE && code >= 1 && code <= 999) { // code is 1-3 digit. diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java index 0fd05bf6a..c47bb83fb 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/configurations/PixelDensityQualifier.java @@ -39,7 +39,7 @@ public final class PixelDensityQualifier extends ResourceQualifier { /** * Creates and returns a qualifier from the given folder segment. If the segment is incorrect, * null is returned. - * @param segment the folder segment from which to create a qualifier. + * @param folderSegment the folder segment from which to create a qualifier. * @return a new {@link CountryCodeQualifier} object or null */ public static PixelDensityQualifier getQualifier(String folderSegment) { @@ -66,7 +66,7 @@ public final class PixelDensityQualifier extends ResourceQualifier { /** * Returns the folder name segment for the given value. This is equivalent to calling * {@link #toString()} on a {@link NetworkCodeQualifier} object. - * @param value the value of the qualifier, as returned by {@link #getCode()}. + * @param value the value of the qualifier, as returned by {@link #getValue()}. */ public static String getFolderSegment(int value) { if (value != DEFAULT_DENSITY) { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java index 72438a64f..381279120 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/MultiResourceFile.java @@ -132,7 +132,7 @@ public final class MultiResourceFile extends ResourceFile implements IValueResou /** * Adds a resource item to the list * @param resType The type of the resource - * @param name The name of the resource. + * @param value The value of the resource. */ public void addResourceValue(String resType, ResourceValue value) { ResourceType type = ResourceType.getEnum(resType); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java index 183af2768..8b6c3c1f0 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectClassLoader.java @@ -107,7 +107,6 @@ public final class ProjectClassLoader extends ClassLoader { * @param parent the root of the file. * @param segments the segments containing the path of the file * @param index the offset at which to start looking into segments. - * @return * @throws FileNotFoundException */ private File getFile(File parent, String[] segments, int index) @@ -168,8 +167,6 @@ public final class ProjectClassLoader extends ClassLoader { /** * Loads a class from the 3rd party jar present in the project - * @param name - * @return * @throws ClassNotFoundException */ private Class loadClassFromJar(String name) throws ClassNotFoundException { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java index b0881fa45..40e4e3b45 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ProjectResources.java @@ -393,8 +393,6 @@ public class ProjectResources implements IResourceRepository { /** * Resolves a compiled resource id of type int[] into the resource name. - * @param id - * @return */ public String resolveResourceValue(int[] id) { if (mStyleableValueToNameMap != null) { @@ -407,9 +405,6 @@ public class ProjectResources implements IResourceRepository { /** * Returns the value of a resource by its type and name. - * @param type - * @param name - * @return */ public Integer getResourceValue(String type, String name) { if (mResourceValueMap != null) { @@ -444,8 +439,7 @@ public class ProjectResources implements IResourceRepository { /** * Returns the list of regions used in the resources with the given language. - * @param currentLanguage the current language the region must be associated with - * @return + * @param currentLanguage the current language the region must be associated with. */ public Set getRegions(String currentLanguage) { Set set = new HashSet(); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java index 6db0d9424..98f5b39b4 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolder.java @@ -185,7 +185,7 @@ public final class ResourceFolder extends Resource { /** * Returns the {@link ResourceFile} matching a given name. - * @param file The name of the file to return. + * @param filename The name of the file to return. * @return the {@link ResourceFile} or null if no match was found. */ public ResourceFile getFile(String filename) { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java index bd9330186..5fc7393be 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceFolderType.java @@ -16,21 +16,21 @@ package com.android.ide.eclipse.editors.resources.manager; -import com.android.ide.eclipse.common.AndroidConstants; import com.android.ide.eclipse.editors.resources.configurations.FolderConfiguration; +import com.android.sdklib.SdkConstants; /** * Enum representing a type of resource folder. */ public enum ResourceFolderType { - ANIM(AndroidConstants.FD_ANIM), - COLOR(AndroidConstants.FD_COLOR), - DRAWABLE(AndroidConstants.FD_DRAWABLE), - LAYOUT(AndroidConstants.FD_LAYOUT), - MENU(AndroidConstants.FD_MENU), - RAW(AndroidConstants.FD_RAW), - VALUES(AndroidConstants.FD_VALUES), - XML(AndroidConstants.FD_XML); + ANIM(SdkConstants.FD_ANIM), + COLOR(SdkConstants.FD_COLOR), + DRAWABLE(SdkConstants.FD_DRAWABLE), + LAYOUT(SdkConstants.FD_LAYOUT), + MENU(SdkConstants.FD_MENU), + RAW(SdkConstants.FD_RAW), + VALUES(SdkConstants.FD_VALUES), + XML(SdkConstants.FD_XML); private final String mName; diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java index 9c5f0fc09..6099008d7 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/ResourceManager.java @@ -30,6 +30,7 @@ import com.android.ide.eclipse.editors.resources.manager.files.IAbstractFolder; import com.android.ide.eclipse.editors.resources.manager.files.IFileWrapper; import com.android.ide.eclipse.editors.resources.manager.files.IFolderWrapper; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; import org.eclipse.core.resources.IContainer; import org.eclipse.core.resources.IFile; @@ -269,8 +270,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener, /** * Loads and returns the resources for a given {@link IAndroidTarget} - * @param osFilePath the path to the folder containing all the versions of the framework - * resources + * @param androidTarget the target from which to load the framework resources */ public ProjectResources loadFrameworkResources(IAndroidTarget androidTarget) { String osResourcesPath = androidTarget.getPath(IAndroidTarget.RESOURCES); @@ -329,7 +329,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener, return; } - IFolder resourceFolder = project.getFolder(AndroidConstants.FD_RESOURCES); + IFolder resourceFolder = project.getFolder(SdkConstants.FD_RESOURCES); ProjectResources projectResources = mMap.get(project); if (projectResources == null) { @@ -478,7 +478,7 @@ public final class ResourceManager implements IProjectListener, IFolderListener, * @return true if the path is under /project res/ */ private boolean isInResFolder(IPath path) { - return AndroidConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1)); + return SdkConstants.FD_RESOURCES.equalsIgnoreCase(path.segment(1)); } /** diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java index 121123611..32b110760 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/SingleResourceFile.java @@ -115,8 +115,6 @@ public class SingleResourceFile extends ResourceFile { /** * Returns the name of the resources. - * @param type - * @return */ private String getResourceName(ResourceType type) { // get the name from the filename. diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java index 0a14214d7..d99cb13a8 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FileWrapper.java @@ -17,7 +17,6 @@ package com.android.ide.eclipse.editors.resources.manager.files; import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; import java.io.File; import java.io.FileInputStream; @@ -45,7 +44,7 @@ public class FileWrapper implements IAbstractFile { mFile = file; } - public InputStream getContents() throws CoreException { + public InputStream getContents() { try { return new FileInputStream(mFile); } catch (FileNotFoundException e) { @@ -74,7 +73,7 @@ public class FileWrapper implements IAbstractFile { } if (obj instanceof File) { - return mFile.equals((File)obj); + return mFile.equals(obj); } return super.equals(obj); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java index 8afea3364..9ad74601d 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/FolderWrapper.java @@ -59,7 +59,7 @@ public class FolderWrapper implements IAbstractFolder { } if (obj instanceof File) { - return mFolder.equals((File)obj); + return mFolder.equals(obj); } return super.equals(obj); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java index 441c65bb8..f0f5f2d53 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFileWrapper.java @@ -55,7 +55,7 @@ public class IFileWrapper implements IAbstractFile { } if (obj instanceof IFile) { - return mFile.equals((IFile)obj); + return mFile.equals(obj); } return super.equals(obj); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java index 92b5c07e4..b1fa3efc8 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/resources/manager/files/IFolderWrapper.java @@ -61,7 +61,7 @@ public class IFolderWrapper implements IAbstractFolder { } if (obj instanceof IFolder) { - return mFolder.equals((IFolder)obj); + return mFolder.equals(obj); } return super.equals(obj); diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java index 772fb5257..07298810f 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/ui/tree/NewItemSelectionDialog.java @@ -17,7 +17,6 @@ package com.android.ide.eclipse.editors.ui.tree; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.common.AndroidConstants; import com.android.ide.eclipse.editors.descriptors.ElementDescriptor; import com.android.ide.eclipse.editors.layout.descriptors.ViewElementDescriptor; import com.android.ide.eclipse.editors.uimodel.UiElementNode; diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java index b7dffddf5..4a05b1ee5 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ConfigurationSelector.java @@ -79,8 +79,7 @@ import java.util.HashMap; * To use this, instantiate somewhere in the UI and then: *

      *
    • Use {@link #setConfiguration(String)} or {@link #setConfiguration(FolderConfiguration)}. - *
    • Retrieve the configuration using {@link #getConfiguration(FolderConfiguration)} and - * test it using {@link FolderConfiguration#isValid()}. + *
    • Retrieve the configuration using {@link #getConfiguration(FolderConfiguration)}. *
    */ public class ConfigurationSelector extends Composite { 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 b27dd4f42..cc643be49 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 @@ -30,6 +30,7 @@ import com.android.ide.eclipse.editors.resources.descriptors.ResourcesDescriptor import com.android.ide.eclipse.editors.resources.manager.ResourceFolderType; import com.android.ide.eclipse.editors.wizards.ConfigurationSelector.ConfigurationState; import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.SdkConstants; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; @@ -243,7 +244,7 @@ class NewXmlFileCreationPage extends WizardPage { /** Absolute destination folder root, e.g. "/res/" */ private static String sResFolderAbs = AndroidConstants.WS_RESOURCES + AndroidConstants.WS_SEP; /** Relative destination folder root, e.g. "res/" */ - private static String sResFolderRel = AndroidConstants.FD_RESOURCES + AndroidConstants.WS_SEP; + private static String sResFolderRel = SdkConstants.FD_RESOURCES + AndroidConstants.WS_SEP; private IProject mProject; private Text mProjectTextField; @@ -629,7 +630,7 @@ class NewXmlFileCreationPage extends WizardPage { // Disregard this folder selection if it doesn't point to /res/something if (wsFolderPath != null && wsFolderPath.segmentCount() > 1 && - AndroidConstants.FD_RESOURCES.equals(wsFolderPath.segment(0))) { + SdkConstants.FD_RESOURCES.equals(wsFolderPath.segment(0))) { score += 2; } else { wsFolderPath = null; @@ -1002,7 +1003,7 @@ class NewXmlFileCreationPage extends WizardPage { String fileName = getFileName(); if (fileName == null || fileName.length() == 0) { error = "A destination file name is required."; - } else if (fileName != null && !fileName.endsWith(AndroidConstants.DOT_XML)) { + } else if (!fileName.endsWith(AndroidConstants.DOT_XML)) { error = String.format("The filename must end with %1$s.", AndroidConstants.DOT_XML); } } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java index d3ff334ad..6913ce07d 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/editors/wizards/ReferenceChooserDialog.java @@ -17,7 +17,6 @@ package com.android.ide.eclipse.editors.wizards; import com.android.ide.eclipse.adt.AdtPlugin; -import com.android.ide.eclipse.common.AndroidConstants; import com.android.ide.eclipse.common.resources.IResourceRepository; import com.android.ide.eclipse.common.resources.ResourceItem; import com.android.ide.eclipse.common.resources.ResourceType; diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template index b4faae667..b43e75f2b 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/AndroidManifest.template @@ -6,4 +6,5 @@ ACTIVITIES +USES-SDK diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template new file mode 100644 index 000000000..8adae717a --- /dev/null +++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/templates/uses-sdk.template @@ -0,0 +1 @@ + diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class1.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java similarity index 100% rename from tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class1.java rename to tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class1.java diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class2.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java similarity index 100% rename from tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/jar/example/Class2.java rename to tools/eclipse/plugins/com.android.ide.eclipse.tests/not_source_folder/jar/example/Class2.java diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java index 47008212f..5a89d0154 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/project/ProjectHelperTest.java @@ -60,8 +60,9 @@ public class ProjectHelperTest extends TestCase { ProjectHelper.fixProjectClasspathEntries(javaProject); IClasspathEntry[] fixedEntries = javaProject.getRawClasspath(); - assertEquals(2, fixedEntries.length); + assertEquals(3, fixedEntries.length); assertEquals("Project/src", fixedEntries[0].getPath().toString()); - assertEquals(CONTAINER_ID, fixedEntries[1].getPath().toString()); + assertEquals(OLD_CONTAINER_ID, fixedEntries[1].getPath().toString()); + assertEquals(CONTAINER_ID, fixedEntries[2].getPath().toString()); } } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java index f3d9b7902..872938bc6 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/adt/sdk/AndroidJarLoaderTest.java @@ -45,6 +45,8 @@ public class AndroidJarLoaderTest extends TestCase { @Override public void tearDown() throws Exception { + mFrameworkClassLoader = null; + System.gc(); } /** Preloads classes. They should load just fine. */ @@ -74,8 +76,9 @@ public class AndroidJarLoaderTest extends TestCase { Class c = _findClass(mFrameworkClassLoader, "jar.example.Class2"); //$NON-NLS-1$ assertEquals("jar.example.Class2", c.getName()); //$NON-NLS-1$ HashMap> map = getPrivateClassCache(); + assertTrue(map.containsKey("jar.example.Class1")); //$NON-NLS-1$ assertTrue(map.containsKey("jar.example.Class2")); //$NON-NLS-1$ - assertEquals(1, map.size()); + assertEquals(2, map.size()); } /** call the protected method findClass */ diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java index 76ebfc310..833845342 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/common/resources/AttrsXmlParserTest.java @@ -94,6 +94,33 @@ public class AttrsXmlParserTest extends TestCase { assertEquals(Integer.valueOf(0), valueMap.get("horizontal")); assertEquals(Integer.valueOf(1), valueMap.get("vertical")); } + + public final void testDeprecated() throws Exception { + mParser.preload(); + + DeclareStyleableInfo dep = mParser.getDeclareStyleableList().get("DeprecatedTest"); + assertNotNull(dep); + + AttributeInfo[] attrs = dep.getAttributes(); + assertEquals(4, attrs.length); + + assertEquals("deprecated-inline", attrs[0].getName()); + assertEquals("In-line deprecated.", attrs[0].getDeprecatedDoc()); + assertEquals("Deprecated comments using delimiters.", attrs[0].getJavaDoc()); + + assertEquals("deprecated-multiline", attrs[1].getName()); + assertEquals("Multi-line version of deprecated that works till the next tag.", + attrs[1].getDeprecatedDoc()); + assertEquals("Deprecated comments on their own line.", attrs[1].getJavaDoc()); + + assertEquals("deprecated-not", attrs[2].getName()); + assertEquals(null, attrs[2].getDeprecatedDoc()); + assertEquals("This attribute is not deprecated.", attrs[2].getJavaDoc()); + + assertEquals("deprecated-no-javadoc", attrs[3].getName()); + assertEquals("There is no other javadoc here.", attrs[3].getDeprecatedDoc()); + assertEquals("", attrs[3].getJavaDoc()); + } //---- access to private methods diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java index 55064592d..69c3ed878 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/descriptors/DescriptorsUtilsTest.java @@ -99,28 +99,26 @@ public class DescriptorsUtilsTest extends TestCase { ElementDescriptor desc = new ElementDescriptor("application"); desc.setSdkUrl(DescriptorsUtils.MANIFEST_SDK_URL + "TagApplication"); String docBaseUrl = "http://base"; - assertEquals("

    ", DescriptorsUtils.formatFormText("", desc, docBaseUrl)); + assertEquals("
  • ", DescriptorsUtils.formatFormText("", desc, docBaseUrl)); - assertEquals("

    application

    ", + assertEquals("
  • application
  • ", DescriptorsUtils.formatFormText( "application", desc, docBaseUrl)); - assertEquals("

    android.content.Intent

    ", + assertEquals("
  • android.content.Intent
  • ", DescriptorsUtils.formatFormText( "{@link android.content.Intent}", desc, docBaseUrl)); - assertEquals("

    AndroidManifestPermission

    ", + assertEquals("
  • AndroidManifestPermission
  • ", DescriptorsUtils.formatFormText( "{@link #AndroidManifestPermission}", desc, docBaseUrl)); - assertEquals("

    \"permission\"

    ", + assertEquals("
  • \"permission\"
  • ", DescriptorsUtils.formatFormText( "{@link #AndroidManifestPermission <permission>}", desc, docBaseUrl)); - } - } diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java index 9e01081e0..28f78711e 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/configurations/TextInputMethodQualifierTest.java @@ -54,11 +54,11 @@ public class TextInputMethodQualifierTest extends TestCase { } public void testNoKey() { - assertEquals(true, timq.checkAndSet("nokey", config)); //$NON-NLS-1$ + assertEquals(true, timq.checkAndSet("nokeys", config)); //$NON-NLS-1$ assertTrue(config.getTextInputMethodQualifier() != null); assertEquals(TextInputMethodQualifier.TextInputMethod.NOKEY, config.getTextInputMethodQualifier().getValue()); - assertEquals("nokey", config.getTextInputMethodQualifier().toString()); //$NON-NLS-1$ + assertEquals("nokeys", config.getTextInputMethodQualifier().toString()); //$NON-NLS-1$ } public void testFailures() { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java index 0c1a508ed..25a86c3b1 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/com/android/ide/eclipse/editors/resources/manager/ConfigMatchTest.java @@ -41,7 +41,7 @@ public class ConfigMatchTest extends TestCase { private static final String MISC2_FILENAME = "bar.xml"; //$NON-NLS-1$ private ProjectResources mResources; - private ArrayList mQualifierList; + private ResourceQualifier[] mQualifierList; private FolderConfiguration config4; private FolderConfiguration config3; private FolderConfiguration config2; @@ -60,7 +60,7 @@ public class ConfigMatchTest extends TestCase { qualifierListField.setAccessible(true); // get the actual list. - mQualifierList = (ArrayList)qualifierListField.get(manager); + mQualifierList = (ResourceQualifier[])qualifierListField.get(manager); // create the project resources. mResources = new ProjectResources(false /* isFrameworkRepository */); @@ -191,10 +191,10 @@ public class ConfigMatchTest extends TestCase { FolderConfiguration config = new FolderConfiguration(); // those must be of the same length - assertEquals(qualifierValues.length, mQualifierList.size()); + assertEquals(qualifierValues.length, mQualifierList.length); int index = 0; - + for (ResourceQualifier qualifier : mQualifierList) { String value = qualifierValues[index++]; if (value != null) { diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml index e51604c6f..aa9a1f737 100644 --- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml +++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/unittests/data/mock_attrs.xml @@ -18,7 +18,7 @@ --> + + + + + + + + + + + + + + + diff --git a/tools/eclipse/scripts/create_test_symlinks.sh b/tools/eclipse/scripts/create_test_symlinks.sh index 1479e0474..931dce885 100755 --- a/tools/eclipse/scripts/create_test_symlinks.sh +++ b/tools/eclipse/scripts/create_test_symlinks.sh @@ -11,32 +11,38 @@ function back() { echo $1 | sed 's@[^/]*@..@g' } +HOST=`uname` +if [ "${HOST:0:6}" == "CYGWIN" ]; then + # We can't use symlinks under Cygwin + function cpdir() { # $1=dest $2=source + rsync -avW --delete-after $2 $1 + } + +else + # For all other systems which support symlinks + function cpdir() { # $1=dest $2=source + ln -svf `back $1`/$2 $1 + } +fi + BASE="development/tools/eclipse/plugins/com.android.ide.eclipse.tests" DEST=$BASE BACK=`back $DEST` - HOST=`uname` if [ "$HOST" == "Linux" ]; then - DIR="ln -svf" ln -svf $BACK/out/host/linux-x86/framework/kxml2-2.3.0.jar "$DEST/" elif [ "$HOST" == "Darwin" ]; then - DIR="ln -svf" ln -svf $BACK/out/host/darwin-x86/framework/kxml2-2.3.0.jar "$DEST/" elif [ "${HOST:0:6}" == "CYGWIN" ]; then - DIR="rsync -avW --delete-after" - JAR="kxml2-2.3.0.jar" - if [ ! -f "$DEST/$JAR" ]; then - # Get the jar from ADT if we can, otherwise download it. - if [ -f "$DEST/../com.android.ide.eclipse.adt/$JAR" ]; then - cp "$DEST/../com.android.ide.eclipse.adt/$JAR" "$DEST/$JAR" - else - wget -O "$DEST/$JAR" "http://internap.dl.sourceforge.net/sourceforge/kxml/$JAR" - fi - chmod a+rx "$DEST/$JAR" + + if [ ! -f "$DEST/kxml2-2.3.0.jar" ]; then + cp -v "prebuilt/common/kxml2/kxml2-2.3.0.jar" "$DEST/" + chmod -v a+rx "$DEST"/*.jar fi + else echo "Unsupported platform ($HOST). Nothing done." fi @@ -44,5 +50,5 @@ fi # create link to ddmlib tests DEST=$BASE/unittests/com/android BACK=`back $DEST` -$DIR $BACK/development/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib $DEST/ +cpdir $DEST development/tools/ddms/libs/ddmlib/tests/src/com/android/ddmlib diff --git a/tools/findunused/findunusedresources b/tools/findunused/findunusedresources index 85e15b283..963e2f1e6 100755 --- a/tools/findunused/findunusedresources +++ b/tools/findunused/findunusedresources @@ -28,11 +28,21 @@ do if [ -d $app/res ] then appname=$(basename $app) + + # find the R.java file that contains all the generated resource identifiers rDotJava=$(find out/target/common/obj/APPS/${appname}_intermediates/ -name R.java) + + # Simplistically process the content of the file to get the names of all the constants, + # and try to find a reference to each constant. for i in $(cat $rDotJava | grep "\w*=0x\d*" | sed 's/ *public static final int //' | sed 's/=0x.*//') do - echo $i $(grep -Rw R\\..*\\.$i\\\|@style/$i\\\|@drawable/$i\\\|@anim/$i\\\|@color/$i\\\|@xml/$i\\\|@layout/$i\\\|@menu/$i\\\|@+id/$i\\\|@array/$i\\\|@string/$i $app | wc -l) + # Since periods in the names get translated to underscores in R.java, and you can actually + # refer to such constants from java by using an underscore instead of a period, we also + # replace all underscores with a pattern that will match periods and underscores. + p=$(echo $i | sed 's/_/[\\._]/g') + echo $i $(grep -Rw R\\..*\\.$i\\\|@style/$p\\\|@drawable/$p\\\|@anim/$p\\\|@color/$p\\\|@xml/$p\\\|@layout/$p\\\|@menu/$p\\\|@+id/$p\\\|@array/$p\\\|@string/$p $app | wc -l) done | grep " 0$" | { + # this block gets as its input a list of constants which no references were found, one per line if [ "$showall" == "yes" ] then echo $app diff --git a/tools/scripts/android_rules.xml b/tools/scripts/android_rules.xml index bed5f2433..1331696fc 100644 --- a/tools/scripts/android_rules.xml +++ b/tools/scripts/android_rules.xml @@ -1,112 +1,73 @@ - - - - - - - - + - - - - - - + + + + + - - - + - - - + - - - - - - - + + + + + + - + - - + + - - - - + + - - - - + + - - - - + + - - - - - - - - - - - - - - - + + - + + + + + + + Creating output directories if needed... - - + + @@ -116,13 +77,13 @@ - + - + - + - + @@ -130,9 +91,9 @@ Compiling aidl files into Java classes... - - - + + + @@ -141,113 +102,102 @@ - + - Converting compiled files and external libraries into ${outdir}/${dex-file}... + Converting compiled files and external libraries into ${out-folder}/${dex-file}... - - + + - + Packaging resources and assets... - + - + - + - + - - + + Packaging resources... - + - + - + - + - - - - - - - - - + Packaging ${out-debug-package}, and signing it with a debug key... - + - + - + - + - + - + - + Packaging ${out-unsigned-package} for release... - + - + - + - + - + - + - It will need to be signed with jarsigner before being published. + It will need to be signed with jarsigner before it is published. @@ -255,7 +205,7 @@ Installing ${out-debug-package} onto default emulator... - + @@ -264,7 +214,7 @@ - + @@ -273,8 +223,25 @@ Uninstalling ${application-package} from the default emulator... - + - + + + + Android Ant Build. Available targets: + help: Displays this help. + debug: Builds the application and sign it with a debug key. + release: Builds the application. The generated apk file must be + signed before it is published. + install: Installs the debug package onto a running emulator or + device. This can only be used if the application has + not yet been installed. + reinstall: Installs the debug package on a running emulator or + device that already has the application. + The signatures must match. + uninstall: uninstall the application from a running emulator or + device. + diff --git a/tools/scripts/build.template b/tools/scripts/build.template index f4d6ab848..c1afef80d 100644 --- a/tools/scripts/build.template +++ b/tools/scripts/build.template @@ -1,31 +1,51 @@ - + + + + + by the 'android' tool. This is the place to change some of the default property values + used by the Ant rules. + Here are some properties you may want to change/update: + + application-package + the name of your application package as defined in the manifest. Used by the + 'uninstall' rule. + source-folder + the name of the source folder. Default is 'src'. + out-folder + the name of the output folder. Default is 'bin'. + + Properties related to the SDK location or the project target should be updated + using the 'android' tool with the 'update' action. + + This file is an integral part of the build system for your application and + should be checked in in Version Control Systems. + + --> - + - - - - - - - - - - - - + + + + + + + - - + + diff --git a/tools/scripts/default.properties.template b/tools/scripts/default.properties.template deleted file mode 100644 index 63df494fe..000000000 --- a/tools/scripts/default.properties.template +++ /dev/null @@ -1,18 +0,0 @@ -# This file is automatically generated by activitycreator. -# Do not modify this file -- YOUR CHANGES WILL BE ERASED! -# Instead customize values in a "build.properties" file. - -# location of the SDK -sdk-folder=ANDROID_SDK_FOLDER - -# target mode. Value can be "platform" or "add-on" -target-mode=TARGET_MODE - -# target API level. -target-api=TARGET_API - -# target name, if target-mode=add-on -target-name=TARGET_NAME - -# target platform. This is either the target itself or the platform the add-on is based on. -target-folder=TARGET_FOLDER diff --git a/tools/sdkmanager/app/.classpath b/tools/sdkmanager/app/.classpath index 45c59d37c..cbd9d3775 100644 --- a/tools/sdkmanager/app/.classpath +++ b/tools/sdkmanager/app/.classpath @@ -1,9 +1,11 @@ + + diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java new file mode 100644 index 000000000..ef3d0eec8 --- /dev/null +++ b/tools/sdkmanager/app/src/com/android/sdkmanager/CommandLineProcessor.java @@ -0,0 +1,580 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.sdkmanager; + +import java.util.HashMap; +import java.util.Map.Entry; + +/** + * Parses the command-line and stores flags needed or requested. + *

    + * This is a base class. To be useful you want to: + *

      + *
    • override it. + *
    • pass an action array to the constructor. + *
    • define flags for your actions. + *
    + *

    + * To use, call {@link #parseArgs(String[])} and then call {@link #getValue(String, String)}. + */ +public class CommandLineProcessor { + + /** Internal action name for all global flags. */ + public final static String GLOBAL_FLAG = "global"; + /** Internal action name for internally hidden flags. + * This is currently used to store the requested action name. */ + public final static String INTERNAL_FLAG = "internal"; + + /** The global help flag. */ + public static final String KEY_HELP = "help"; + /** The global verbose flag. */ + public static final String KEY_VERBOSE = "verbose"; + /** The internal action flag. */ + public static final String KEY_ACTION = "action"; + + /** List of available actions. + *

    + * Each entry must be a 2-string array with first the action name and then + * a description. + */ + private final String[][] mActions; + /** The hash of all defined arguments. + *

    + * The key is a string "action/longName". + */ + private final HashMap mArguments = new HashMap(); + + public CommandLineProcessor(String[][] actions) { + 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); + } + + //------------------ + // Helpers to get flags values + + /** Helper that returns true if --verbose was requested. */ + public boolean isVerbose() { + return ((Boolean) getValue(GLOBAL_FLAG, KEY_VERBOSE)).booleanValue(); + } + + /** Helper that returns true if --help was requested. */ + public boolean isHelpRequested() { + return ((Boolean) getValue(GLOBAL_FLAG, KEY_HELP)).booleanValue(); + } + + /** Helper that returns the requested action name. */ + public String getActionRequested() { + return (String) getValue(INTERNAL_FLAG, KEY_ACTION); + } + + //------------------ + + /** + * Raw access to parsed parameter values. + * @param action The action name, including {@link #GLOBAL_FLAG} and {@link #INTERNAL_FLAG} + * @param longFlagName The long flag name for the given action. + * @return The current value object stored in the parameter, which depends on the argument mode. + */ + public Object getValue(String action, String longFlagName) { + String key = action + "/" + longFlagName; + Arg arg = mArguments.get(key); + return arg.getCurrentValue(); + } + + /** + * Internal setter for raw parameter value. + * @param action The action name, including {@link #GLOBAL_FLAG} and {@link #INTERNAL_FLAG} + * @param longFlagName The long flag name for the given action. + * @param value The new current value object stored in the parameter, which depends on the + * argument mode. + */ + protected void setValue(String action, String longFlagName, Object value) { + String key = action + "/" + longFlagName; + Arg arg = mArguments.get(key); + arg.setCurrentValue(value); + } + + /** + * Parses the command-line arguments. + *

    + * This method will exit and not return if a parsing error arise. + * + * @param args The arguments typically received by a main method. + */ + public void parseArgs(String[] args) { + String needsHelp = null; + String action = null; + + int n = args.length; + for (int i = 0; i < n; i++) { + Arg arg = null; + String a = args[i]; + if (a.startsWith("--")) { + arg = findLongArg(action, a.substring(2)); + } else if (a.startsWith("-")) { + arg = findShortArg(action, a.substring(1)); + } + + // Not a keyword and we don't have an action yet, this should be an action + if (arg == null && action == null) { + + if (a.startsWith("-")) { + // Got a keyword but not valid for global flags + needsHelp = String.format( + "Flag '%1$s' is not a valid global flag. Did you mean to specify it after the action name?", + a, action); + break; + } + + for (String[] actionDesc : mActions) { + if (actionDesc[0].equals(a)) { + action = a; + break; + } + } + + if (action == null) { + needsHelp = String.format( + "Expected action name after global parameters but found %1$s instead.", + a); + break; + } + } else if (arg == null && action != null) { + // Got a keyword but not valid for the current action + needsHelp = String.format( + "Flag '%1$s' is not valid for action '%2$s'.", + a, action); + break; + + } else if (arg != null) { + // Process keyword + String error = null; + if (arg.getMode().needsExtra()) { + if (++i >= n) { + needsHelp = String.format("Missing argument for flag %1$s.", a); + break; + } + + error = arg.getMode().process(arg, args[i]); + } else { + error = arg.getMode().process(arg, null); + + // If we just toggled help, we want to exit now without printing any error. + // We do this test here only when a Boolean flag is toggled since booleans + // are the only flags that don't take parameters and help is a boolean. + if (isHelpRequested()) { + printHelpAndExit(null); + // The call above should terminate however in unit tests we override + // it so we still need to return here. + return; + } + } + + if (error != null) { + needsHelp = String.format("Invalid usage for flag %1$s: %2$s.", a, error); + break; + } + } + } + + if (needsHelp == null) { + if (action == null) { + needsHelp = "Missing action name."; + } else { + // Validate that all mandatory arguments are non-null for this action + for (Entry 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; + } + } + } + + setValue(INTERNAL_FLAG, KEY_ACTION, action); + } + } + + if (needsHelp != null) { + printHelpAndExitForAction(action, needsHelp); + } + } + + /** + * Finds an {@link Arg} given an action name and a long flag name. + * @return The {@link Arg} found or null. + */ + protected Arg findLongArg(String action, String longName) { + if (action == null) { + action = GLOBAL_FLAG; + } + String key = action + "/" + longName; + return mArguments.get(key); + } + + /** + * Finds an {@link Arg} given an action name and a short flag name. + * @return The {@link Arg} found or null. + */ + protected Arg findShortArg(String action, String shortName) { + if (action == null) { + action = GLOBAL_FLAG; + } + + for (Entry entry : mArguments.entrySet()) { + Arg arg = entry.getValue(); + if (arg.getAction().equals(action)) { + if (shortName.equals(arg.getShortArg())) { + return arg; + } + } + } + + return null; + } + + /** + * 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 + */ + public void printHelpAndExit(String errorFormat, Object... args) { + printHelpAndExitForAction(null /*actionFilter*/, errorFormat, args); + } + + /** + * Prints the help/usage and exits. + * + * @param actionFilter If null, displays help for all actions. If not null, display help only + * for that specific action. In all cases also display general usage and action list. + * @param errorFormat Optional error message to print prior to usage using String.format + * @param args Arguments for String.format + */ + public void printHelpAndExitForAction(String actionFilter, String errorFormat, Object... args) { + if (errorFormat != null) { + stderr(errorFormat, args); + } + + /* + * usage should fit in 80 columns + * 12345678901234567890123456789012345678901234567890123456789012345678901234567890 + */ + stdout("\n" + + "Usage:\n" + + " android [global options] action [action options]\n" + + "\n" + + "Global options:"); + listOptions(GLOBAL_FLAG); + + stdout("\nValid actions:"); + for (String[] action : mActions) { + String filler = ""; + int len = action[0].length(); + if (len < 10) { + filler = " ".substring(len); + } + + stdout("- %1$s:%2$s %3$s", action[0], filler, action[1]); + } + + for (String[] action : mActions) { + if (actionFilter == null || actionFilter.equals(action[0])) { + stdout("\nAction \"%1$s\":", action[0]); + stdout(" %1$s", action[1]); + stdout("Options:"); + listOptions(action[0]); + } + } + + exit(); + } + + /** + * Internal helper to print all the option flags for a given action name. + */ + protected void listOptions(String action) { + int numOptions = 0; + for (Entry entry : mArguments.entrySet()) { + Arg arg = entry.getValue(); + if (arg.getAction().equals(action)) { + + String value = null; + if (arg.getDefaultValue() instanceof String[]) { + value = ""; + for (String v : (String[]) arg.getDefaultValue()) { + if (value.length() > 0) { + value += "|"; + } + value += v; + } + } else if (arg.getDefaultValue() != null) { + value = arg.getDefaultValue().toString(); + } + + stdout(" -%1$s %2$-10s %3$s%4$s", + arg.getShortArg(), + "--" + arg.getLongArg(), + arg.getDescription(), + value == null ? "" : " (" + value + ")"); + numOptions++; + } + } + + if (numOptions == 0) { + stdout(" No options"); + } + } + + //---- + + /** + * The mode of an argument specifies the type of variable it represents, + * whether an extra parameter is required after the flag and how to parse it. + */ + static enum MODE { + /** Argument value is a Boolean. Default value is a Boolean. */ + BOOLEAN { + @Override + public boolean needsExtra() { + return false; + } + @Override + public String process(Arg arg, String extra) { + // Toggle the current value + arg.setCurrentValue(! ((Boolean) arg.getCurrentValue()).booleanValue()); + return null; + } + }, + + /** Argument value is an Integer. Default value is an Integer. */ + INTEGER { + @Override + public boolean needsExtra() { + return true; + } + @Override + public String process(Arg arg, String extra) { + try { + arg.setCurrentValue(Integer.parseInt(extra)); + return null; + } catch (NumberFormatException e) { + return String.format("Failed to parse '%1$s' as an integer: %2%s", + extra, e.getMessage()); + } + } + }, + + /** Argument value is a String. Default value is a String[]. */ + ENUM { + @Override + public boolean needsExtra() { + return true; + } + @Override + public String process(Arg arg, String extra) { + StringBuilder desc = new StringBuilder(); + String[] values = (String[]) arg.getDefaultValue(); + for (String value : values) { + if (value.equals(extra)) { + arg.setCurrentValue(extra); + return null; + } + + if (desc.length() != 0) { + desc.append(", "); + } + desc.append(value); + } + + return String.format("'%1$s' is not one of %2$s", extra, desc.toString()); + } + }, + + /** Argument value is a String. Default value is a null. */ + STRING { + @Override + public boolean needsExtra() { + return true; + } + @Override + public String process(Arg arg, String extra) { + arg.setCurrentValue(extra); + return null; + } + }; + + /** + * Returns true if this mode requires an extra parameter. + */ + public abstract boolean needsExtra(); + + /** + * Processes the flag for this argument. + * + * @param arg The argument being processed. + * @param extra The extra parameter. Null if {@link #needsExtra()} returned false. + * @return An error string or null if there's no error. + */ + public abstract String process(Arg arg, String extra); + } + + /** + * An argument accepted by the command-line, also called "a flag". + * Arguments must have a short version (one letter), a long version name and a description. + * They can have a default value, or it can be null. + * Depending on the {@link MODE}, the default value can be a Boolean, an Integer, a String + * or a String array (in which case the first item is the current by default.) + */ + static class Arg { + private final String mAction; + private final String mShortName; + private final String mLongName; + private final String mDescription; + private final Object mDefaultValue; + private Object mCurrentValue; + private final MODE mMode; + private final boolean mMandatory; + + /** + * Creates a new argument flag description. + * + * @param mode The {@link MODE} for the argument. + * @param mandatory True if this argument is mandatory for this action. + * @param action The action name. Can be #GLOBAL_FLAG or #INTERNAL_FLAG. + * @param shortName The one-letter short argument name. Cannot be empty nor null. + * @param longName The long argument name. Cannot be empty nor null. + * @param description The description. Cannot be null. + * @param defaultValue The default value (or values), which depends on the selected {@link MODE}. + */ + public Arg(MODE mode, + boolean mandatory, + String action, + String shortName, + String longName, + String description, + Object defaultValue) { + mMode = mode; + mMandatory = mandatory; + mAction = action; + mShortName = shortName; + mLongName = longName; + mDescription = description; + mDefaultValue = defaultValue; + if (defaultValue instanceof String[]) { + mCurrentValue = ((String[])defaultValue)[0]; + } else { + mCurrentValue = mDefaultValue; + } + } + + public boolean isMandatory() { + return mMandatory; + } + + public String getShortArg() { + return mShortName; + } + + public String getLongArg() { + return mLongName; + } + + public String getDescription() { + return mDescription; + } + + public String getAction() { + return mAction; + } + + public Object getDefaultValue() { + return mDefaultValue; + } + + public Object getCurrentValue() { + return mCurrentValue; + } + + public void setCurrentValue(Object currentValue) { + mCurrentValue = currentValue; + } + + public MODE getMode() { + return mMode; + } + } + + /** + * Internal helper to define a new argument for a give action. + * + * @param mode The {@link MODE} for the argument. + * @param action The action name. Can be #GLOBAL_FLAG or #INTERNAL_FLAG. + * @param shortName The one-letter short argument name. Cannot be empty nor null. + * @param longName The long argument name. Cannot be empty nor null. + * @param description The description. Cannot be null. + * @param defaultValue The default value (or values), which depends on the selected {@link MODE}. + */ + protected void define(MODE mode, + boolean mandatory, + String action, + String shortName, String longName, + String description, Object defaultValue) { + assert(mandatory || mode == MODE.BOOLEAN); // a boolean mode cannot be mandatory + + String key = action + "/" + longName; + mArguments.put(key, new Arg(mode, mandatory, + action, shortName, longName, description, defaultValue)); + } + + /** + * Exits in case of error. + * This is protected so that it can be overridden in unit tests. + */ + protected void exit() { + System.exit(1); + } + + /** + * Prints a line to stdout. + * This is protected so that it can be overridden in unit tests. + * + * @param format The string to be formatted. Cannot be null. + * @param args Format arguments. + */ + protected void stdout(String format, Object...args) { + System.out.println(String.format(format, args)); + } + + /** + * Prints a line to stderr. + * This is protected so that it can be overridden in unit tests. + * + * @param format The string to be formatted. Cannot be null. + * @param args Format arguments. + */ + protected void stderr(String format, Object...args) { + System.err.println(String.format(format, args)); + } +} diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java index 72bd2aa17..3bcb9a317 100644 --- a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java +++ b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java @@ -23,6 +23,8 @@ import com.android.sdklib.ISdkLog; import com.android.sdklib.SdkConstants; import com.android.sdklib.SdkManager; import com.android.sdklib.IAndroidTarget.IOptionalLibrary; +import com.android.sdklib.project.ProjectCreator; +import com.android.sdklib.project.ProjectCreator.OutputLevel; import com.android.sdklib.vm.HardwareProperties; import com.android.sdklib.vm.VmManager; import com.android.sdklib.vm.HardwareProperties.HardwareProperty; @@ -35,31 +37,20 @@ import java.util.List; import java.util.Map; /** - * Main class for the 'android' application - * + * Main class for the 'android' application. */ class Main { private final static String TOOLSDIR = "com.android.sdkmanager.toolsdir"; - private final static String ARG_LIST_TARGET = "target"; - private final static String ARG_LIST_VM = "vm"; - private final static String[] BOOLEAN_YES_REPLIES = new String[] { "yes", "y" }; private final static String[] BOOLEAN_NO_REPLIES = new String[] { "no", "n" }; private String mSdkFolder; + private ISdkLog mSdkLog; private SdkManager mSdkManager; private VmManager mVmManager; - - /* --list parameters */ - private String mListObject; - - /* --create parameters */ - private boolean mCreateVm; - private int mCreateTargetId; - private IAndroidTarget mCreateTarget; - private String mCreateName; + private SdkCommandLine mSdkCommandLine; public static void main(String[] args) { new Main().run(args); @@ -71,7 +62,7 @@ class Main { */ private void run(String[] args) { init(); - parseArgs(args); + mSdkCommandLine.parseArgs(args); parseSdk(); doAction(); } @@ -81,70 +72,41 @@ class Main { * doing basic parsing of the SDK. */ private void init() { + mSdkCommandLine = new SdkCommandLine(); + /* We get passed a property for the tools dir */ String toolsDirProp = System.getProperty(TOOLSDIR); if (toolsDirProp == null) { // for debugging, it's easier to override using the process environment toolsDirProp = System.getenv(TOOLSDIR); } - if (toolsDirProp == null) { - printHelpAndExit("ERROR: The tools directory property is not set, please make sure you are executing android or android.bat"); - } - - // got back a level for the SDK folder - File tools = new File(toolsDirProp); - mSdkFolder = tools.getParent(); - - } - /** - * 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("-l") || arg.equals("--list")) { - mListObject = args[++argPos]; - } else if (arg.equals("-c") || arg.equals("--create")) { - mCreateVm = true; - parseCreateArgs(args, ++argPos); + if (toolsDirProp != null) { + // got back a level for the SDK folder + File tools; + if (toolsDirProp.length() > 0) { + tools = new File(toolsDirProp); + mSdkFolder = tools.getParent(); + } else { + try { + tools = new File(".").getCanonicalFile(); + mSdkFolder = tools.getParent(); + } catch (IOException e) { + // Will print an error below since mSdkFolder is not defined } } - } catch (ArrayIndexOutOfBoundsException e) { - /* Any OOB triggers help */ - printHelpAndExit("ERROR: Not enough arguments."); } - } - private void parseCreateArgs(String[] args, int argPos) { - final int numArgs = args.length; - - try { - for (; argPos < numArgs; argPos++) { - final String arg = args[argPos]; - if (arg.equals("-t") || arg.equals("--target")) { - String targetId = args[++argPos]; - try { - // get the target id - mCreateTargetId = Integer.parseInt(targetId); - } catch (NumberFormatException e) { - printHelpAndExit("ERROR: Target Id is not a number"); - } - } else if (arg.equals("-n") || arg.equals("--name")) { - mCreateName = args[++argPos]; - } else { - printHelpAndExit("ERROR: '%s' unknown argument for --create mode", - args[argPos]); - } + if (mSdkFolder == null) { + String os = System.getProperty("os.name"); + String cmd = "android"; + if (os.startsWith("Windows")) { + cmd += ".bat"; } - } catch (ArrayIndexOutOfBoundsException e) { - /* Any OOB triggers help */ - printHelpAndExit("ERROR: Not enough arguments for --create"); + + mSdkCommandLine.printHelpAndExit( + "ERROR: The tools directory property is not set, please make sure you are executing %1$s", + cmd); } } @@ -152,10 +114,15 @@ class Main { * Does the basic SDK parsing required for all actions */ private void parseSdk() { - mSdkManager = SdkManager.createManager(mSdkFolder, new ISdkLog() { - public void error(String errorFormat, Object... args) { - System.err.printf("Error: " + errorFormat, args); - System.err.println(""); + mSdkLog = new ISdkLog() { + public void error(Throwable t, String errorFormat, Object... args) { + if (errorFormat != null) { + System.err.printf("Error: " + errorFormat, args); + System.err.println(""); + } + if (t != null) { + System.err.print("Error: " + t.getMessage()); + } } public void warning(String warningFormat, Object... args) { @@ -165,10 +132,15 @@ class Main { System.out.println(""); } } - }); + + public void printf(String msgFormat, Object... args) { + System.out.printf(msgFormat, args); + } + }; + mSdkManager = SdkManager.createManager(mSdkFolder, mSdkLog); if (mSdkManager == null) { - printHelpAndExit("ERROR: Unable to parse SDK content."); + mSdkCommandLine.printHelpAndExit("ERROR: Unable to parse SDK content."); } } @@ -176,19 +148,37 @@ class Main { * Actually do an action... */ private void doAction() { - if (mListObject != null) { + String action = mSdkCommandLine.getActionRequested(); + + if (SdkCommandLine.ACTION_LIST.equals(action)) { // list action. - if (ARG_LIST_TARGET.equals(mListObject)) { + if (SdkCommandLine.ARG_TARGET.equals(mSdkCommandLine.getListFilter())) { displayTargetList(); - } else if (ARG_LIST_VM.equals(mListObject)) { + } else if (SdkCommandLine.ARG_VM.equals(mSdkCommandLine.getListFilter())) { displayVmList(); } else { - printHelpAndExit("'%s' is not a valid --list option", mListObject); + displayTargetList(); + displayVmList(); } - } else if (mCreateVm) { + } else if (SdkCommandLine.ACTION_NEW_VM.equals(action)) { createVm(); + } else if (SdkCommandLine.ACTION_NEW_PROJECT.equals(action)) { + // get the target and try to resolve it. + int targetId = mSdkCommandLine.getNewProjectTargetId(); + IAndroidTarget[] targets = mSdkManager.getTargets(); + if (targetId < 1 || targetId > targets.length) { + mSdkCommandLine.printHelpAndExit("ERROR: Wrong target id."); + } + IAndroidTarget target = targets[targetId - 1]; + + ProjectCreator creator = new ProjectCreator(mSdkFolder, + OutputLevel.NORMAL, mSdkLog); + + creator.createProject(mSdkCommandLine.getNewProjectLocation(), + mSdkCommandLine.getNewProjectName(), mSdkCommandLine.getNewProjectPackage(), + mSdkCommandLine.getNewProjectActivity(), target, true); } else { - printHelpAndExit(null); + mSdkCommandLine.printHelpAndExit(null); } } @@ -274,7 +264,7 @@ class Main { index++; } } catch (AndroidLocationException e) { - printHelpAndExit(e.getMessage()); + mSdkCommandLine.printHelpAndExit(e.getMessage()); } } @@ -283,11 +273,14 @@ class Main { */ private void createVm() { // find a matching target - if (mCreateTargetId >= 1 && mCreateTargetId <= mSdkManager.getTargets().length) { - mCreateTarget = mSdkManager.getTargets()[mCreateTargetId-1]; // target it is 1-based + int targetId = mSdkCommandLine.getNewVmTargetId(); + IAndroidTarget target = null; + + if (targetId >= 1 && targetId <= mSdkManager.getTargets().length) { + target = mSdkManager.getTargets()[targetId-1]; // target it is 1-based } else { - printHelpAndExit( - "ERROR: Target Id is not a valid Id. Check android --list target for the list of targets."); + mSdkCommandLine.printHelpAndExit( + "ERROR: Target Id is not a valid Id. Check 'android list target' for the list of targets."); } try { @@ -295,19 +288,24 @@ class Main { String vmRoot = AndroidLocation.getFolder() + AndroidLocation.FOLDER_VMS; Map hardwareConfig = null; - if (mCreateTarget.isPlatform()) { + if (target.isPlatform()) { try { - hardwareConfig = promptForHardware(mCreateTarget); + hardwareConfig = promptForHardware(target); } catch (IOException e) { - printHelpAndExit(e.getMessage()); + mSdkCommandLine.printHelpAndExit(e.getMessage()); } } - VmManager.createVm(vmRoot, mCreateName, mCreateTarget, null /*skinName*/, - null /*sdcardPath*/, 0 /*sdcardSize*/, hardwareConfig, + VmManager.createVm(vmRoot, + mSdkCommandLine.getNewVmName(), + target, + null /*skinName*/, + null /*sdcardPath*/, + 0 /*sdcardSize*/, + hardwareConfig, null /* sdklog */); } catch (AndroidLocationException e) { - printHelpAndExit(e.getMessage()); + mSdkCommandLine.printHelpAndExit(e.getMessage()); } } @@ -325,7 +323,7 @@ class Main { System.out.print(String.format("Do you which to create a custom hardware profile [%s]", defaultAnswer)); - result = readLine(readLineBuffer); + result = readLine(readLineBuffer).trim(); // handle default: if (result.length() == 0) { result = defaultAnswer; @@ -391,8 +389,7 @@ class Main { break; case INTEGER: try { - @SuppressWarnings("unused") - int value = Integer.parseInt(result); + Integer.parseInt(result); map.put(property.getName(), result); i++; // valid reply, move to next property } catch (NumberFormatException e) { @@ -414,9 +411,8 @@ class Main { } /** - * Read the line from the input stream. + * Reads the line from the input stream. * @param buffer - * @return * @throws IOException */ private String readLine(byte[] buffer) throws IOException { @@ -434,7 +430,12 @@ class Main { return new String(buffer, 0, count) + secondHalf; } - return new String(buffer, 0, count - 1); // -1 to not include the carriage return + // ignore end whitespace + while (count > 0 && (buffer[count-1] == '\r' || buffer[count-1] == '\n')) { + count--; + } + + return new String(buffer, 0, count); } /** @@ -442,6 +443,7 @@ class Main { * @throws IOException If the value is not a boolean string. */ private boolean getBooleanReply(String reply) throws IOException { + for (String valid : BOOLEAN_YES_REPLIES) { if (valid.equalsIgnoreCase(reply)) { return true; @@ -456,32 +458,4 @@ class Main { throw new IOException(String.format("%s is not a valid reply", reply)); } - - /** - * 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" + - "Usage:\n" + - " android --list [target|vm]\n" + - " android --create --target --name \n" + - "\n" + - "Options:\n" + - " -l [target|vm], --list [target|vm]\n" + - " Outputs the available targets or Virtual Machines and their Ids.\n" + - "\n"; - - System.out.println(usage); - System.exit(1); - } } \ No newline at end of file diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java new file mode 100644 index 000000000..918c534d9 --- /dev/null +++ b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java @@ -0,0 +1,152 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.sdkmanager; + +import com.android.sdklib.SdkManager; + + +/** + * Specific command-line flags for the {@link SdkManager}. + */ +public class SdkCommandLine extends CommandLineProcessor { + + public static final String ARG_ALIAS = "alias"; + public static final String ARG_ACTIVITY = "activity"; + public static final String ARG_VM = "vm"; + 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"; + public static final String KEY_TARGET_ID = ARG_TARGET; + public static final String KEY_NAME = "name"; + public static final String KEY_OUT = "out"; + public static final String KEY_FILTER = "filter"; + + public final static String ACTION_LIST = "list"; + public final static String ACTION_NEW_VM = ARG_VM; + public final static String ACTION_NEW_PROJECT = "project"; + public final static String ACTION_UPDATE_PROJECT = "update"; + + private final static String[][] ACTIONS = { + { ACTION_LIST, + "Lists existing targets or VMs." }, + { ACTION_NEW_VM, + "Creates a new VM." }, + { ACTION_NEW_PROJECT, + "Creates a new project using a template." }, + { ACTION_UPDATE_PROJECT, + "Updates a new project from existing source (must have an AndroidManifest.xml)." }, + }; + + public SdkCommandLine() { + super(ACTIONS); + + define(MODE.ENUM, false, ACTION_LIST, "f", KEY_FILTER, + "List filter", new String[] { ARG_ALL, ARG_TARGET, ARG_VM }); + + define(MODE.STRING, false, ACTION_NEW_VM, "o", KEY_OUT, + "Location path of new VM", null); + define(MODE.STRING, true, ACTION_NEW_VM, "n", KEY_NAME, + "Name of the new VM", null); + define(MODE.INTEGER, true, ACTION_NEW_VM, "t", KEY_TARGET_ID, + "Target id of 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, + "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); + } + + // -- some helpers for list action flags + + /** Helper to retrieve the --filter for the list action. */ + public String getListFilter() { + return ((String) getValue(ACTION_LIST, KEY_FILTER)); + } + + // -- some helpers for vm action flags + + /** Helper to retrieve the --out location for the new vm action. */ + public String getNewVmLocation() { + return ((String) getValue(ACTION_NEW_VM, KEY_OUT)); + } + + /** Helper to retrieve the --target id for the new vm action. */ + public int getNewVmTargetId() { + return ((Integer) getValue(ACTION_NEW_VM, KEY_TARGET_ID)).intValue(); + } + + /** Helper to retrieve the --name for the new vm action. */ + public String getNewVmName() { + return ((String) getValue(ACTION_NEW_VM, KEY_NAME)); + } + + // -- some helpers for project action flags + + /** Helper to retrieve the --out location for the new project action. */ + public String getNewProjectLocation() { + return ((String) getValue(ACTION_NEW_PROJECT, KEY_OUT)); + } + + /** Helper to retrieve the --target id for the new project action. */ + public int getNewProjectTargetId() { + return ((Integer) getValue(ACTION_NEW_PROJECT, KEY_TARGET_ID)).intValue(); + } + + /** Helper to retrieve the --name for the new project action. */ + public String getNewProjectName() { + return ((String) getValue(ACTION_NEW_PROJECT, KEY_NAME)); + } + + /** Helper to retrieve the --package for the new project action. */ + public String getNewProjectPackage() { + return ((String) getValue(ACTION_NEW_PROJECT, KEY_PACKAGE)); + } + + /** Helper to retrieve the --activity for the new project action. */ + public String getNewProjectActivity() { + return ((String) getValue(ACTION_NEW_PROJECT, KEY_ACTIVITY)); + } + + // -- some helpers for update action flags + + /** Helper to retrieve the --out location for the update project action. */ + public String getUpdateProjectLocation() { + return ((String) getValue(ACTION_UPDATE_PROJECT, KEY_OUT)); + } + + /** Helper to retrieve the --target id for the update project action. */ + public int getUpdateProjectTargetId() { + return ((Integer) getValue(ACTION_UPDATE_PROJECT, KEY_TARGET_ID)).intValue(); + } +} diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java new file mode 100644 index 000000000..e74cdbd62 --- /dev/null +++ b/tools/sdkmanager/app/tests/com/android/sdkmanager/CommandLineProcessorTest.java @@ -0,0 +1,180 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.sdkmanager; + +import junit.framework.TestCase; + + +public class CommandLineProcessorTest extends TestCase { + + /** + * A mock version of the {@link CommandLineProcessor} class that does not + * exits and captures its stdout/stderr output. + */ + public static class MockCommandLineProcessor extends CommandLineProcessor { + private boolean mExitCalled; + private boolean mHelpCalled; + private String mStdOut = ""; + private String mStdErr = ""; + + public MockCommandLineProcessor() { + super(new String[][] { + { "action1", "Some action" }, + { "action2", "Another action" }, + }); + define(MODE.STRING, false /*mandatory*/, + "action1", "1", "first", "non-mandatory flag", null); + define(MODE.STRING, true /*mandatory*/, + "action1", "2", "second", "mandatory flag", null); + } + + @Override + public void printHelpAndExitForAction(String actionFilter, + String errorFormat, Object... args) { + mHelpCalled = true; + super.printHelpAndExitForAction(actionFilter, errorFormat, args); + } + + @Override + protected void exit() { + mExitCalled = true; + } + + @Override + protected void stdout(String format, Object... args) { + String s = String.format(format, args); + mStdOut += s + "\n"; + // don't call super to avoid printing stuff + } + + @Override + protected void stderr(String format, Object... args) { + String s = String.format(format, args); + mStdErr += s + "\n"; + // don't call super to avoid printing stuff + } + + public boolean wasHelpCalled() { + return mHelpCalled; + } + + public boolean wasExitCalled() { + return mExitCalled; + } + + public String getStdOut() { + return mStdOut; + } + + public String getStdErr() { + return mStdErr; + } + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + public final void testPrintHelpAndExit() { + MockCommandLineProcessor c = new MockCommandLineProcessor(); + assertFalse(c.wasExitCalled()); + assertFalse(c.wasHelpCalled()); + assertTrue(c.getStdOut().equals("")); + assertTrue(c.getStdErr().equals("")); + c.printHelpAndExit(null); + assertTrue(c.getStdOut().indexOf("-v") != -1); + assertTrue(c.getStdOut().indexOf("--verbose") != -1); + assertTrue(c.getStdErr().equals("")); + assertTrue(c.wasExitCalled()); + + c = new MockCommandLineProcessor(); + assertFalse(c.wasExitCalled()); + assertTrue(c.getStdOut().equals("")); + assertTrue(c.getStdErr().indexOf("Missing parameter") == -1); + + c.printHelpAndExit("Missing %s", "parameter"); + assertTrue(c.wasExitCalled()); + assertFalse(c.getStdOut().equals("")); + assertTrue(c.getStdErr().indexOf("Missing parameter") != -1); + } + + public final void testVerbose() { + MockCommandLineProcessor c = new MockCommandLineProcessor(); + + assertFalse(c.isVerbose()); + c.parseArgs(new String[] { "-v" }); + assertTrue(c.isVerbose()); + assertTrue(c.wasExitCalled()); + assertTrue(c.wasHelpCalled()); + assertTrue(c.getStdErr().indexOf("Missing action name.") != -1); + + c = new MockCommandLineProcessor(); + c.parseArgs(new String[] { "--verbose" }); + assertTrue(c.isVerbose()); + assertTrue(c.wasExitCalled()); + assertTrue(c.wasHelpCalled()); + assertTrue(c.getStdErr().indexOf("Missing action name.") != -1); + } + + public final void testHelp() { + MockCommandLineProcessor c = new MockCommandLineProcessor(); + + c.parseArgs(new String[] { "-h" }); + assertTrue(c.wasExitCalled()); + assertTrue(c.wasHelpCalled()); + assertTrue(c.getStdErr().indexOf("Missing action name.") == -1); + + c = new MockCommandLineProcessor(); + c.parseArgs(new String[] { "--help" }); + assertTrue(c.wasExitCalled()); + assertTrue(c.wasHelpCalled()); + assertTrue(c.getStdErr().indexOf("Missing action name.") == -1); + } + + public final void testMandatory() { + MockCommandLineProcessor c = new MockCommandLineProcessor(); + + c.parseArgs(new String[] { "action1", "-1", "value1", "-2", "value2" }); + assertFalse(c.wasExitCalled()); + assertFalse(c.wasHelpCalled()); + assertEquals("", c.getStdErr()); + assertEquals("value1", c.getValue("action1", "first")); + assertEquals("value2", c.getValue("action1", "second")); + + c = new MockCommandLineProcessor(); + c.parseArgs(new String[] { "action1", "-2", "value2" }); + assertFalse(c.wasExitCalled()); + assertFalse(c.wasHelpCalled()); + assertEquals("", c.getStdErr()); + assertEquals(null, c.getValue("action1", "first")); + assertEquals("value2", c.getValue("action1", "second")); + + c = new MockCommandLineProcessor(); + c.parseArgs(new String[] { "action1" }); + assertTrue(c.wasExitCalled()); + assertTrue(c.wasHelpCalled()); + assertTrue(c.getStdErr().indexOf("must be defined") != -1); + assertEquals(null, c.getValue("action1", "first")); + assertEquals(null, c.getValue("action1", "second")); + } +} diff --git a/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java b/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java new file mode 100644 index 000000000..b943b98a8 --- /dev/null +++ b/tools/sdkmanager/app/tests/com/android/sdkmanager/SdkCommandLineTest.java @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.sdkmanager; + +import junit.framework.TestCase; + +public class SdkCommandLineTest extends TestCase { + + /** + * A mock version of the {@link SdkCommandLine} class that does not + * exits and discards its stdout/stderr output. + */ + public static class MockSdkCommandLine extends SdkCommandLine { + private boolean mExitCalled; + private boolean mHelpCalled; + + public MockSdkCommandLine() { + } + + @Override + public void printHelpAndExitForAction(String actionFilter, + String errorFormat, Object... args) { + mHelpCalled = true; + super.printHelpAndExitForAction(actionFilter, errorFormat, args); + } + + @Override + protected void exit() { + mExitCalled = true; + } + + @Override + protected void stdout(String format, Object... args) { + // discard + } + + @Override + protected void stderr(String format, Object... args) { + // discard + } + + public boolean wasExitCalled() { + return mExitCalled; + } + + public boolean wasHelpCalled() { + return mHelpCalled; + } + } + + @Override + protected void setUp() throws Exception { + super.setUp(); + } + + @Override + protected void tearDown() throws Exception { + super.tearDown(); + } + + /** Test list with long name and verbose */ + public final void testList_Long_Verbose() { + MockSdkCommandLine c = new MockSdkCommandLine(); + assertEquals("all", c.getListFilter()); + c.parseArgs(new String[] { "-v", "list", "--filter", "vm" }); + assertFalse(c.wasHelpCalled()); + assertFalse(c.wasExitCalled()); + assertEquals("vm", c.getListFilter()); + assertTrue(c.isVerbose()); + } + + /** Test list with short name and no verbose */ + public final void testList_Short() { + MockSdkCommandLine c = new MockSdkCommandLine(); + assertEquals("all", c.getListFilter()); + c.parseArgs(new String[] { "list", "-f", "vm" }); + assertFalse(c.wasHelpCalled()); + assertFalse(c.wasExitCalled()); + assertEquals("vm", c.getListFilter()); + } + + /** Test list with long name and missing parameter */ + public final void testList_Long_MissingParam() { + MockSdkCommandLine c = new MockSdkCommandLine(); + assertEquals("all", c.getListFilter()); + c.parseArgs(new String[] { "list", "--filter" }); + assertTrue(c.wasHelpCalled()); + assertTrue(c.wasExitCalled()); + assertEquals("all", c.getListFilter()); + } +} diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java index 57596138a..2a2efe7dd 100644 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/AddOnTarget.java @@ -95,6 +95,10 @@ final class AddOnTarget implements IAndroidTarget { } } + public String getLocation() { + return mLocation; + } + public String getName() { return mName; } @@ -103,6 +107,10 @@ final class AddOnTarget implements IAndroidTarget { return mVendor; } + public String getFullName() { + return String.format("%1$s (%2$s)", mName, mVendor); + } + public String getDescription() { return mDescription; } @@ -140,6 +148,28 @@ final class AddOnTarget implements IAndroidTarget { return mLibraries; } + public boolean isCompatibleBaseFor(IAndroidTarget target) { + // basic test + if (target == this) { + return true; + } + + // if the receiver has no optional library, then anything with api version number >= to + // the receiver is compatible. + if (mLibraries.length == 0) { + return target.getApiVersionNumber() >= getApiVersionNumber(); + } + + // Otherwise, target is only compatible if the vendor and name are equals with the api + // number greater or equal (ie target is a newer version of this add-on). + if (target.isPlatform() == false) { + return (mVendor.equals(target.getVendor()) && mName.equals(target.getName()) && + target.getApiVersionNumber() >= getApiVersionNumber()); + } + + return false; + } + public String hashString() { return String.format(ADD_ON_FORMAT, mVendor, mName, mBasePlatform.getApiVersionNumber()); } diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java index e5d45b200..0e2b10991 100644 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/IAndroidTarget.java @@ -22,23 +22,41 @@ package com.android.sdklib; */ public interface IAndroidTarget extends Comparable { + /** OS Path to the "android.jar" file. */ public static int ANDROID_JAR = 1; + /** OS Path to the "framework.aidl" file. */ public static int ANDROID_AIDL = 2; + /** OS Path to "images" folder which contains the emulator system images. */ public static int IMAGES = 3; + /** OS Path to the "samples" folder which contains sample projects. */ public static int SAMPLES = 4; + /** OS Path to the "skins" folder which contains the emulator skins. */ public static int SKINS = 5; + /** OS Path to the "templates" folder which contains the templates for new projects. */ public static int TEMPLATES = 6; + /** OS Path to the "data" folder which contains data & libraries for the SDK tools. */ public static int DATA = 7; + /** OS Path to the "attrs.xml" file. */ public static int ATTRIBUTES = 8; + /** OS Path to the "attrs_manifest.xml" file. */ public static int MANIFEST_ATTRIBUTES = 9; + /** OS Path to the "data/layoutlib.jar" library. */ public static int LAYOUT_LIB = 10; + /** OS Path to the "data/res" folder. */ public static int RESOURCES = 11; + /** OS Path to the "data/fonts" folder. */ public static int FONTS = 12; + /** OS Path to the "data/widgets.txt" file. */ public static int WIDGETS = 13; + /** OS Path to the "data/activity_actions.txt" file. */ public static int ACTIONS_ACTIVITY = 14; + /** OS Path to the "data/broadcast_actions.txt" file. */ public static int ACTIONS_BROADCAST = 15; + /** OS Path to the "data/service_actions.txt" file. */ public static int ACTIONS_SERVICE = 16; + /** OS Path to the "data/categories.txt" file. */ public static int CATEGORIES = 17; + /** OS Path to the "sources" folder. */ public static int SOURCES = 18; public interface IOptionalLibrary { @@ -47,6 +65,11 @@ public interface IAndroidTarget extends Comparable { String getJarPath(); } + /** + * Returns the target location. + */ + String getLocation(); + /** * Returns the name of the vendor of the target. */ @@ -57,6 +80,12 @@ public interface IAndroidTarget extends Comparable { */ String getName(); + /** + * Returns the full name of the target, possibly including vendor name. + * @return + */ + String getFullName(); + /** * Returns the description of the target. */ @@ -80,7 +109,7 @@ public interface IAndroidTarget extends Comparable { /** * Returns the path of a platform component. * @param pathId the id representing the path to return. Any of the constants defined in the - * {@link ITargetDataProvider} interface can be used. + * {@link IAndroidTarget} interface can be used. */ String getPath(int pathId); @@ -95,6 +124,15 @@ public interface IAndroidTarget extends Comparable { */ IOptionalLibrary[] getOptionalLibraries(); + /** + * Returns whether the given target is compatible with the receiver. + *

    A target is considered compatible if applications developed for the receiver can run on + * the given target. + * + * @param target the IAndroidTarget to test. + */ + boolean isCompatibleBaseFor(IAndroidTarget target); + /** * Returns a string able to uniquely identify a target. * Typically the target will encode information such as api level, whether it's a platform diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java index 3eda37f4c..8cbe44a7e 100644 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/ISdkLog.java @@ -21,5 +21,6 @@ package com.android.sdklib; */ public interface ISdkLog { void warning(String warningFormat, Object... args); - void error(String errorFormat, Object... args); + void error(Throwable t, String errorFormat, Object... args); + void printf(String msgFormat, Object... args); } diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java index f5a1f6d35..59fa81c85 100644 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/PlatformTarget.java @@ -95,6 +95,10 @@ final class PlatformTarget implements IAndroidTarget { public String getName() { return mName; } + + public String getFullName() { + return mName; + } /* * (non-Javadoc) @@ -136,7 +140,17 @@ final class PlatformTarget implements IAndroidTarget { public IOptionalLibrary[] getOptionalLibraries() { return null; } + + public boolean isCompatibleBaseFor(IAndroidTarget target) { + // basic test + if (target == this) { + return true; + } + // target is compatible wit the receiver as long as its api version number is greater or + // equal. + return target.getApiVersionNumber() >= mApiVersionNumber; + } public String hashString() { return String.format(PLATFORM_HASH, mApiVersionNumber); 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 78d1fda9f..ede0d86bc 100644 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkConstants.java @@ -64,6 +64,40 @@ public final class SdkConstants { /** Skin layout file */ public final static String FN_SKIN_LAYOUT = "layout";//$NON-NLS-1$ + /* Folder Names for Android Projects . */ + + /** Resources folder name, i.e. "res". */ + public final static String FD_RESOURCES = "res"; //$NON-NLS-1$ + /** Assets folder name, i.e. "assets" */ + public final static String FD_ASSETS = "assets"; //$NON-NLS-1$ + /** Default source folder name, i.e. "src" */ + public final static String FD_SOURCES = "src"; //$NON-NLS-1$ + /** Default native library folder name inside the project, i.e. "libs" + * While the folder inside the .apk is "lib", we call that one libs because + * that's what we use in ant for both .jar and .so and we need to make the 2 development ways + * compatible. */ + public final static String FD_NATIVE_LIBS = "libs"; //$NON-NLS-1$ + /** Native lib folder inside the APK: "lib" */ + public final static String FD_APK_NATIVE_LIBS = "lib"; //$NON-NLS-1$ + /** Default output folder name, i.e. "bin" */ + public final static String FD_OUTPUT = "bin"; //$NON-NLS-1$ + /** Default anim resource folder name, i.e. "anim" */ + public final static String FD_ANIM = "anim"; //$NON-NLS-1$ + /** Default color resource folder name, i.e. "color" */ + public final static String FD_COLOR = "color"; //$NON-NLS-1$ + /** Default drawable resource folder name, i.e. "drawable" */ + public final static String FD_DRAWABLE = "drawable"; //$NON-NLS-1$ + /** Default layout resource folder name, i.e. "layout" */ + public final static String FD_LAYOUT = "layout"; //$NON-NLS-1$ + /** Default menu resource folder name, i.e. "menu" */ + public final static String FD_MENU = "menu"; //$NON-NLS-1$ + /** Default values resource folder name, i.e. "values" */ + public final static String FD_VALUES = "values"; //$NON-NLS-1$ + /** Default xml resource folder name, i.e. "xml" */ + public final static String FD_XML = "xml"; //$NON-NLS-1$ + /** Default raw resource folder name, i.e. "raw" */ + public final static String FD_RAW = "raw"; //$NON-NLS-1$ + /* Folder Names for the Android SDK */ /** Name of the SDK platforms folder. */ @@ -90,13 +124,12 @@ public final class SdkConstants { public final static String FD_RES = "res"; /** Name of the SDK font folder, i.e. "fonts" */ public final static String FD_FONTS = "fonts"; - /** Default values resource folder name, i.e. "values" */ - public final static String FD_VALUES = "values"; /** Name of the android sources directory */ public static final String FD_ANDROID_SOURCES = "sources"; /** Name of the addon libs folder. */ public final static String FD_ADDON_LIBS = "libs"; + /* 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. */ diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java index 67b8499cd..b4de51aa0 100644 --- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/SdkManager.java @@ -36,8 +36,8 @@ import java.util.regex.Pattern; */ public final class SdkManager { - private final static String PROP_VERSION_SDK = "ro.build.version.sdk"; - private final static String PROP_VERSION_RELEASE = "ro.build.version.release"; + public final static String PROP_VERSION_SDK = "ro.build.version.sdk"; + public final static String PROP_VERSION_RELEASE = "ro.build.version.release"; private final static String ADDON_NAME = "name"; private final static String ADDON_VENDOR = "vendor"; @@ -73,7 +73,7 @@ public final class SdkManager { return manager; } catch (IllegalArgumentException e) { if (log != null) { - log.error(e.getMessage()); + log.error(e, "Error parsing the sdk."); } } @@ -188,13 +188,14 @@ public final class SdkManager { // looks like apiNumber does not parse to a number. // Ignore this platform. if (log != null) { - log.error("Ignoring platform '%1$s': %2$s is not a valid number in %3$s.", + log.error(null, + "Ignoring platform '%1$s': %2$s is not a valid number in %3$s.", platform.getName(), PROP_VERSION_SDK, SdkConstants.FN_BUILD_PROP); } } } } else if (log != null) { - log.error("Ignoring platform '%1$s': %2$s is missing.", platform.getName(), + log.error(null, "Ignoring platform '%1$s': %2$s is missing.", platform.getName(), SdkConstants.FN_BUILD_PROP); } @@ -281,7 +282,7 @@ public final class SdkManager { if (baseTarget == null) { if (log != null) { - log.error( + log.error(null, "Ignoring add-on '%1$s': Unable to find base platform with API level %2$d", addon.getName(), apiValue); } @@ -292,7 +293,7 @@ public final class SdkManager { // looks like apiNumber does not parse to a number. // Ignore this add-on. if (log != null) { - log.error( + log.error(null, "Ignoring add-on '%1$s': %2$s is not a valid number in %3$s.", addon.getName(), ADDON_API, SdkConstants.FN_BUILD_PROP); } @@ -331,7 +332,7 @@ public final class SdkManager { return target; } } else if (log != null) { - log.error("Ignoring add-on '%1$s': %2$s is missing.", addon.getName(), + log.error(null, "Ignoring add-on '%1$s': %2$s is missing.", addon.getName(), SdkConstants.FN_MANIFEST_INI); } @@ -340,7 +341,7 @@ public final class SdkManager { private void displayAddonManifestError(ISdkLog log, String addonName, String valueName) { if (log != null) { - log.error("Ignoring add-on '%1$s': '%2$s' is missing from %3$s.", + log.error(null, "Ignoring add-on '%1$s': '%2$s' is missing from %3$s.", addonName, valueName, SdkConstants.FN_MANIFEST_INI); } } 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 new file mode 100644 index 000000000..1184fc29b --- /dev/null +++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/project/ProjectCreator.java @@ -0,0 +1,346 @@ +/* + * 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.sdklib.project; + +import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.ISdkLog; +import com.android.sdklib.SdkConstants; +import com.android.sdklib.project.ProjectProperties.PropertyType; + +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.HashMap; +import java.util.Map; + +/** + * Creates the basic files needed to get an Android project up and running. Also + * allows creation of IntelliJ project files. + * + * @hide + */ +public class ProjectCreator { + + private final static String PH_JAVA_FOLDER = "PACKAGE_PATH"; + private final static String PH_PACKAGE = "PACKAGE"; + private final static String PH_ACTIVITY_NAME = "ACTIVITY_NAME"; + + private final static String FOLDER_TESTS = "tests"; + + public enum OutputLevel { + SILENT, NORMAL, VERBOSE; + } + + private static class ProjectCreateException extends Exception { + /** default UID. This will not be serialized anyway. */ + private static final long serialVersionUID = 1L; + + ProjectCreateException(String message) { + super(message); + } + + ProjectCreateException(Throwable t, String format, Object... args) { + super(format != null ? String.format(format, args) : format, t); + } + + ProjectCreateException(String format, Object... args) { + super(String.format(format, args)); + } + } + + private final OutputLevel mLevel; + + private final ISdkLog mLog; + private final String mSdkFolder; + + public ProjectCreator(String sdkFolder, OutputLevel level, ISdkLog log) { + mSdkFolder = sdkFolder; + mLevel = level; + mLog = log; + } + + /** + * Creates a new project. + * @param folderPath the folder of the project to create. This folder must exist. + * @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. + * @param target the project target. + * @param isTestProject whether the project to create is a test project. + */ + public void createProject(String folderPath, String projectName, + String packageName, String activityName, IAndroidTarget target, + boolean isTestProject) { + + // check project folder exists. + File projectFolder = new File(folderPath); + if (projectFolder.isDirectory() == false) { + mLog.error(null, "Folder '%s' does not exist. Aborting...", folderPath); + return; + } + + try { + // first create the project properties. + + // location of the SDK goes in localProperty + ProjectProperties localProperties = ProjectProperties.create(folderPath, + PropertyType.LOCAL); + localProperties.setProperty(ProjectProperties.PROPERTY_SDK, mSdkFolder); + localProperties.save(); + + // target goes in default properties + ProjectProperties defaultProperties = ProjectProperties.create(folderPath, + PropertyType.DEFAULT); + defaultProperties.setAndroidTarget(target); + defaultProperties.save(); + + // create the map for place-holders of values to replace in the templates + final HashMap keywords = new HashMap(); + + // create the required folders. + // compute src folder path + final String packagePath = + stripString(packageName.replace(".", File.separator), + File.separatorChar); + + // put this path in the place-holder map for project files that needs to list + // files manually. + keywords.put(PH_JAVA_FOLDER, packagePath); + + keywords.put(PH_PACKAGE, packageName); + if (activityName != null) { + keywords.put(PH_ACTIVITY_NAME, activityName); + } + + // create the source folder and the java package folders. + final String srcFolderPath = SdkConstants.FD_SOURCES + File.separator + packagePath; + File sourceFolder = createDirs(projectFolder, srcFolderPath); + String javaTemplate = "java_file.template"; + String activityFileName = activityName + ".java"; + if (isTestProject) { + javaTemplate = "java_tests_file.template"; + activityFileName = activityName + "Test.java"; + } + installTemplate(javaTemplate, new File(sourceFolder, activityFileName), + keywords, target); + + // create other useful folders + File resourceFodler = createDirs(projectFolder, SdkConstants.FD_RESOURCES); + createDirs(projectFolder, SdkConstants.FD_OUTPUT); + createDirs(projectFolder, SdkConstants.FD_NATIVE_LIBS); + + if (isTestProject == false) { + /* Make res files only for non test projects */ + File valueFolder = createDirs(resourceFodler, SdkConstants.FD_VALUES); + installTemplate("strings.template", new File(valueFolder, "strings.xml"), + keywords, target); + + File layoutFolder = createDirs(resourceFodler, SdkConstants.FD_LAYOUT); + installTemplate("layout.template", new File(layoutFolder, "main.xml"), + keywords, target); + } + + /* Make AndroidManifest.xml and build.xml files */ + String manifestTemplate = "AndroidManifest.template"; + if (isTestProject) { + manifestTemplate = "AndroidManifest.tests.template"; + } + + installTemplate(manifestTemplate, new File(projectFolder, "AndroidManifest.xml"), + keywords, target); + + installTemplate("build.template", new File(projectFolder, "build.xml"), keywords); + + // if this is not a test project, then we create one. + if (isTestProject == false) { + // create the test project folder. + createDirs(projectFolder, FOLDER_TESTS); + File testProjectFolder = new File(folderPath, FOLDER_TESTS); + + createProject(testProjectFolder.getAbsolutePath(), projectName, packageName, + activityName, target, true /*isTestProject*/); + } + } catch (ProjectCreateException e) { + mLog.error(e, null); + } catch (IOException e) { + mLog.error(e, null); + } + } + + /** + * 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. + * + * @param templateName the name of to the template file + * @param dest the path to the destination file, relative to the project + * @param placeholderMap a map of (place-holder, value) to create the file from the template. + * @param target the Target of the project that will be providing the template. + * @throws ProjectCreateException + */ + private void installTemplate(String templateName, File destFile, + Map placeholderMap, IAndroidTarget target) + throws ProjectCreateException { + // query the target for its template directory + String templateFolder = target.getPath(IAndroidTarget.TEMPLATES); + final String sourcePath = templateFolder + File.separator + templateName; + + installFullPathTemplate(sourcePath, destFile, placeholderMap); + } + + /** + * Installs a new file that is based on a template file provided by the tools folder. + * Each match of each key from the place-holder map in the template will be replaced with its + * corresponding value in the created file. + * + * @param templateName the name of to the template file + * @param dest the path to the destination file, relative to the project + * @param placeholderMap a map of (place-holder, value) to create the file from the template. + * @throws ProjectCreateException + */ + private void installTemplate(String templateName, File destFile, + Map placeholderMap) + throws ProjectCreateException { + // query the target for its template directory + String templateFolder = mSdkFolder + File.separator + SdkConstants.OS_SDK_TOOLS_LIB_FOLDER; + final String sourcePath = templateFolder + File.separator + templateName; + + installFullPathTemplate(sourcePath, destFile, placeholderMap); + } + + /** + * Installs a new file that is based on a template. + * Each match of each key from the place-holder map in the template will be replaced with its + * corresponding value in the created file. + * + * @param sourcePath the full path to the source template file + * @param destFile the destination file + * @param placeholderMap a map of (place-holder, value) to create the file from the template. + * @throws ProjectCreateException + */ + private void installFullPathTemplate(String sourcePath, File destFile, + Map placeholderMap) throws ProjectCreateException { + try { + BufferedWriter out = new BufferedWriter(new FileWriter(destFile)); + BufferedReader in = new BufferedReader(new FileReader(sourcePath)); + String line; + + while ((line = in.readLine()) != null) { + for (String key : placeholderMap.keySet()) { + line = line.replace(key, placeholderMap.get(key)); + } + + out.write(line); + out.newLine(); + } + + out.close(); + in.close(); + } catch (Exception e) { + throw new ProjectCreateException(e, "Could not access %1$s: %2$s", + destFile, e.getMessage()); + } + + println("Added file %1$s", destFile); + } + + + /** + * Prints a message unless silence is enabled. + * @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)); + } + } + + /** + * Creates a new folder, along with any parent folders that do not exists. + * + * @param parent the parent folder + * @param name the name of the directory to create. + * @throws ProjectCreateException + */ + private File createDirs(File parent, String name) throws ProjectCreateException { + final File newFolder = new File(parent, name); + boolean existedBefore = true; + + if (!newFolder.exists()) { + if (!newFolder.mkdirs()) { + throw new ProjectCreateException("Could not create directory: %1$s", newFolder); + } + existedBefore = false; + } + + if (newFolder.isDirectory()) { + if (!newFolder.canWrite()) { + throw new ProjectCreateException("Path is not writable: %1$s", newFolder); + } + } else { + throw new ProjectCreateException("Path is not a directory: %1$s", newFolder); + } + + if (!existedBefore) { + try { + println("Created directory %1$s", newFolder.getCanonicalPath()); + } catch (IOException e) { + throw new ProjectCreateException( + "Could not determine canonical path of created directory", e); + } + } + + return newFolder; + } + + /** + * 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. + */ + private 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); + } +} 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 c0c1fe342..473f284f4 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 @@ -16,6 +16,7 @@ package com.android.sdklib.project; +import com.android.sdklib.IAndroidTarget; import com.android.sdklib.SdkManager; import java.io.File; @@ -32,38 +33,87 @@ import java.util.Map.Entry; public final class ProjectProperties { /** The property name for the project target */ public final static String PROPERTY_TARGET = "target"; - public final static String PROPERTY_SDK = "sdk-folder"; + public final static String PROPERTY_SDK = "sdk-location"; - private final static String PROPERTIES_FILE = "default.properties"; + public static enum PropertyType { + BUILD("build.properties", BUILD_HEADER), + DEFAULT("default.properties", DEFAULT_HEADER), + LOCAL("local.properties", LOCAL_HEADER); + + private final String mFilename; + private final String mHeader; + + PropertyType(String filename, String header) { + mFilename = filename; + mHeader = header; + } + } - private final static String PROP_HEADER = + private final static String LOCAL_HEADER = +// 1-------10--------20--------30--------40--------50--------60--------70--------80 "# This file is automatically generated by Android Tools.\n" + "# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n" + - "# For customized properties when using Ant, set new values\n" + - "# in a \"build.properties\" file.\n\n"; + "# \n" + + "# This file must *NOT* be checked in Version Control Systems,\n" + + "# as it contains information specific to your local configuration.\n" + + "\n"; + + private final static String DEFAULT_HEADER = +// 1-------10--------20--------30--------40--------50--------60--------70--------80 + "# This file is automatically generated by Android Tools.\n" + + "# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n" + + "# \n" + + "# This file must be checked in Version Control Systems.\n" + + "# \n" + + "# To customize properties used by the Ant build system use,\n" + + "# \"build.properties\", and override values to adapt the script to your" + + "# project structure.\n" + + "\n"; + + private final static String BUILD_HEADER = +// 1-------10--------20--------30--------40--------50--------60--------70--------80 + "# This file is used to override default values used by the Ant build system.\n" + + "# \n" + + "# This file must be checked in Version Control Systems, as it is" + + "# integral to the build system of your project.\n" + + "# \n" + + "# Use this file to change values like:\n" + + "# application-package\n:" + + "# the name of your application package as defined in the manifest.\n" + + "# Used by the 'uninstall' rule.\n"+ + "# source-folder\n:" + + "# the name of the source folder. Default is 'src'.\n" + + "# out-folder\n:" + + "# the name of the output folder. Default is 'bin'\n" + + "\n"; private final static Map COMMENT_MAP = new HashMap(); static { - COMMENT_MAP.put(PROPERTY_TARGET, "# Project target.\n"); - COMMENT_MAP.put(PROPERTY_SDK, "# location of the SDK. Only used by Ant.\n"); +// 1-------10--------20--------30--------40--------50--------60--------70--------80 + COMMENT_MAP.put(PROPERTY_TARGET, + "# Project target.\n"); + COMMENT_MAP.put(PROPERTY_SDK, "# location of the SDK. This is only used by Ant\n" + + "# For customization when using a Version Control System, please read the\n" + + "# header note.\n"); } private final String mProjectFolderOsPath; private final Map mProperties; + private final PropertyType mType; /** * Loads a project properties file and return a {@link ProjectProperties} object * containing the properties * @param projectFolderOsPath the project folder. */ - public static ProjectProperties load(String projectFolderOsPath) { + public static ProjectProperties load(String projectFolderOsPath, PropertyType type) { File projectFolder = new File(projectFolderOsPath); if (projectFolder.isDirectory()) { - File defaultFile = new File(projectFolder, PROPERTIES_FILE); + File defaultFile = new File(projectFolder, type.mFilename); if (defaultFile.isFile()) { Map map = SdkManager.parsePropertyFile(defaultFile, null /* log */); if (map != null) { - return new ProjectProperties(projectFolderOsPath, map); + return new ProjectProperties(projectFolderOsPath, map, type); } } } @@ -71,13 +121,14 @@ public final class ProjectProperties { } /** - * Creates a new project properties file, with no properties. + * Creates a new project properties object, with no properties. *

    The file is not created until {@link #save()} is called. * @param projectFolderOsPath the project folder. + * @param type */ - public static ProjectProperties create(String projectFolderOsPath) { + public static ProjectProperties create(String projectFolderOsPath, PropertyType type) { // create and return a ProjectProperties with an empty map. - return new ProjectProperties(projectFolderOsPath, new HashMap()); + return new ProjectProperties(projectFolderOsPath, new HashMap(), type); } /** @@ -89,6 +140,15 @@ public final class ProjectProperties { mProperties.put(name, value); } + /** + * Sets the target property to the given {@link IAndroidTarget} object. + * @param target the Android target. + */ + public void setAndroidTarget(IAndroidTarget target) { + assert mType == PropertyType.DEFAULT; + mProperties.put(PROPERTY_TARGET, target.hashString()); + } + /** * Returns the value of a property. * @param name the name of the property. @@ -103,12 +163,12 @@ public final class ProjectProperties { * @throws IOException */ public void save() throws IOException { - File toSave = new File(mProjectFolderOsPath, PROPERTIES_FILE); + File toSave = new File(mProjectFolderOsPath, mType.mFilename); FileWriter writer = new FileWriter(toSave); // write the header - writer.write(PROP_HEADER); + writer.write(mType.mHeader); // write the properties. for (Entry entry : mProperties.entrySet()) { @@ -128,9 +188,12 @@ public final class ProjectProperties { * Use {@link #load(String)} or {@link #create(String)} to instantiate. * @param projectFolderOsPath * @param map + * @param type */ - private ProjectProperties(String projectFolderOsPath, Map map) { + private ProjectProperties(String projectFolderOsPath, Map map, + PropertyType type) { mProjectFolderOsPath = projectFolderOsPath; mProperties = map; + mType = type; } } 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 a9f1b1753..a28561d2a 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 @@ -76,9 +76,27 @@ public final class VmManager { buildVmList(sdk); } + /** + * Returns the existing VMs. + * @return a newly allocated arrays containing all the VMs. + */ public VmInfo[] getVms() { return mVmList.toArray(new VmInfo[mVmList.size()]); } + + /** + * Returns the {@link VmInfo} matching the given name. + * @return the matching VmInfo or null if none were found. + */ + public VmInfo getVm(String name) { + for (VmInfo info : mVmList) { + if (info.name.equals(name)) { + return info; + } + } + + return null; + } /** * Creates a new VM. @@ -101,7 +119,7 @@ public final class VmManager { File rootDirectory = new File(parentFolder); if (rootDirectory.isDirectory() == false) { if (log != null) { - log.error("%s does not exists.", parentFolder); + log.error(null, "%s does not exists.", parentFolder); } return; } @@ -109,7 +127,7 @@ public final class VmManager { File vmFolder = new File(parentFolder, name + ".avm"); if (vmFolder.exists()) { if (log != null) { - log.error("%s already exists.", vmFolder.getAbsolutePath()); + log.error(null, "%s already exists.", vmFolder.getAbsolutePath()); } return; } diff --git a/tools/sdkmanager/libs/sdkuilib/.classpath b/tools/sdkmanager/libs/sdkuilib/.classpath new file mode 100644 index 000000000..eb5af7e0f --- /dev/null +++ b/tools/sdkmanager/libs/sdkuilib/.classpath @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/tools/sdkmanager/libs/sdkuilib/.project b/tools/sdkmanager/libs/sdkuilib/.project new file mode 100644 index 000000000..da430c8f5 --- /dev/null +++ b/tools/sdkmanager/libs/sdkuilib/.project @@ -0,0 +1,17 @@ + + + SdkUiLib + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java index ddc492ef9..fc951f278 100644 --- a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/SdkTargetSelector.java @@ -40,6 +40,11 @@ import java.util.ArrayList; /** * The SDK target selector is a table that is added to the given parent composite. + *

    + * To use, create it using {@link #SdkTargetSelector(Composite, IAndroidTarget[], boolean)} then + * call {@link #setSelection(IAndroidTarget)}, {@link #setSelectionListener(SelectionListener)} + * and finally use {@link #getFirstSelected()} or {@link #getAllSelected()} to retrieve the + * selection. */ public class SdkTargetSelector { @@ -49,6 +54,14 @@ public class SdkTargetSelector { private Table mTable; private Label mDescription; + /** + * Creates a new SDK Target Selector. + * + * @param parent The parent composite where the selector will be added. + * @param targets The list of targets. This is not copied, the caller must not modify. + * @param allowMultipleSelection True if more than one SDK target can be selected at the same + * time. + */ public SdkTargetSelector(Composite parent, IAndroidTarget[] targets, boolean allowMultipleSelection) { mTargets = targets; @@ -81,13 +94,24 @@ public class SdkTargetSelector { column1.setText("Vendor"); final TableColumn column2 = new TableColumn(mTable, SWT.NONE); column2.setText("API Level"); + final TableColumn column3 = new TableColumn(mTable, SWT.NONE); + column3.setText("SDK"); - adjustColumnsWidth(mTable, column0, column1, column2); + adjustColumnsWidth(mTable, column0, column1, column2, column3); setupSelectionListener(mTable); fillTable(mTable); setupTooltip(mTable); } + /** + * Returns the list of known targets. + *

    + * This is not a copy. Callers must not modify this array. + */ + public IAndroidTarget[] getTargets() { + return mTargets; + } + /** * Sets a selection listener. Set it to null to remove it. * The listener will be called after this table processed its selection @@ -107,20 +131,33 @@ public class SdkTargetSelector { /** * Sets the current target selection. + *

    + * If the selection is actually changed, this will invoke the selection listener + * (if any) with a null event. + * * @param target the target to be selection * @return true if the target could be selected, false otherwise. */ public boolean setSelection(IAndroidTarget target) { boolean found = false; + boolean modified = false; for (TableItem i : mTable.getItems()) { if ((IAndroidTarget) i.getData() == target) { found = true; - i.setChecked(true); - } else { + if (!i.getChecked()) { + modified = true; + i.setChecked(true); + } + } else if (i.getChecked()) { + modified = true; i.setChecked(false); } } + if (modified && mSelectionListener != null) { + mSelectionListener.widgetSelected(null); + } + return found; } @@ -166,15 +203,17 @@ public class SdkTargetSelector { private void adjustColumnsWidth(final Table table, final TableColumn column0, final TableColumn column1, - final TableColumn column2) { + final TableColumn column2, + final TableColumn column3) { // Add a listener to resize the column to the full width of the table table.addControlListener(new ControlAdapter() { @Override public void controlResized(ControlEvent e) { Rectangle r = table.getClientArea(); - column0.setWidth(r.width * 3 / 10); // 30% - column1.setWidth(r.width * 5 / 10); // 50% - column2.setWidth(r.width * 2 / 10); // 20% + column0.setWidth(r.width * 30 / 100); // 30% + column1.setWidth(r.width * 45 / 100); // 45% + column2.setWidth(r.width * 15 / 100); // 15% + column3.setWidth(r.width * 10 / 100); // 10% } }); } @@ -238,6 +277,7 @@ public class SdkTargetSelector { *

  • column 0: sdk name *
  • column 1: sdk vendor *
  • column 2: sdk api name + *
  • column 3: sdk version *
*/ private void fillTable(final Table table) { @@ -249,6 +289,7 @@ public class SdkTargetSelector { item.setText(0, target.getName()); item.setText(1, target.getVendor()); item.setText(2, target.getApiVersionName()); + item.setText(3, Integer.toString(target.getApiVersionNumber())); } } else { table.setEnabled(false); @@ -257,6 +298,7 @@ public class SdkTargetSelector { item.setText(0, "--"); item.setText(1, "No target available"); item.setText(2, "--"); + item.setText(3, "--"); } } diff --git a/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/VmSelector.java b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/VmSelector.java new file mode 100644 index 000000000..dcc0b9ea1 --- /dev/null +++ b/tools/sdkmanager/libs/sdkuilib/src/com/android/sdkuilib/VmSelector.java @@ -0,0 +1,379 @@ +/* + * 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.sdkuilib; + +import com.android.sdklib.IAndroidTarget; +import com.android.sdklib.vm.VmManager.VmInfo; + +import org.eclipse.swt.SWT; +import org.eclipse.swt.events.ControlAdapter; +import org.eclipse.swt.events.ControlEvent; +import org.eclipse.swt.events.SelectionEvent; +import org.eclipse.swt.events.SelectionListener; +import org.eclipse.swt.graphics.Point; +import org.eclipse.swt.graphics.Rectangle; +import org.eclipse.swt.layout.GridData; +import org.eclipse.swt.layout.GridLayout; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.swt.widgets.Event; +import org.eclipse.swt.widgets.Label; +import org.eclipse.swt.widgets.Listener; +import org.eclipse.swt.widgets.Table; +import org.eclipse.swt.widgets.TableColumn; +import org.eclipse.swt.widgets.TableItem; + +import java.util.ArrayList; + + +/** + * The VM selector is a table that is added to the given parent composite. + *

+ * To use, create it using {@link #VmSelector(Composite, VmInfo[], boolean)} then + * call {@link #setSelection(VmInfo)}, {@link #setSelectionListener(SelectionListener)} + * and finally use {@link #getFirstSelected()} or {@link #getAllSelected()} to retrieve the + * selection. + */ +public final class VmSelector { + + private VmInfo[] mVms; + private final boolean mAllowMultipleSelection; + private SelectionListener mSelectionListener; + private Table mTable; + private Label mDescription; + + /** + * Creates a new SDK Target Selector. + * + * @param parent The parent composite where the selector will be added. + * @param vms The list of vms. This is not copied, the caller must not modify. + * @param allowMultipleSelection True if more than one SDK target can be selected at the same + * time. + */ + public VmSelector(Composite parent, VmInfo[] vms, boolean allowMultipleSelection) { + mVms = vms; + + // Layout has 1 column + Composite group = new Composite(parent, SWT.NONE); + group.setLayout(new GridLayout()); + group.setLayoutData(new GridData(GridData.FILL_BOTH)); + group.setFont(parent.getFont()); + + mAllowMultipleSelection = allowMultipleSelection; + mTable = new Table(group, SWT.CHECK | SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER); + mTable.setHeaderVisible(true); + mTable.setLinesVisible(false); + + GridData data = new GridData(); + data.grabExcessVerticalSpace = true; + data.grabExcessHorizontalSpace = true; + data.horizontalAlignment = GridData.FILL; + data.verticalAlignment = GridData.FILL; + mTable.setLayoutData(data); + + mDescription = new Label(group, SWT.WRAP); + mDescription.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); + + // create the table columns + final TableColumn column0 = new TableColumn(mTable, SWT.NONE); + column0.setText("VM Name"); + final TableColumn column1 = new TableColumn(mTable, SWT.NONE); + column1.setText("Target Name"); + final TableColumn column2 = new TableColumn(mTable, SWT.NONE); + column2.setText("API Level"); + final TableColumn column3 = new TableColumn(mTable, SWT.NONE); + column3.setText("SDK"); + + adjustColumnsWidth(mTable, column0, column1, column2, column3); + setupSelectionListener(mTable); + fillTable(mTable, null /* target filter */); + setupTooltip(mTable); + } + + /** + * Sets a new set of VM, with an optional filter. + *

This must be called from the UI thread. + * + * @param vms The list of vms. This is not copied, the caller must not modify. + * @param filter An IAndroidTarget. If non-null, only VM whose target are compatible with the + * filter target will displayed an available for selection. + */ + public void setVms(VmInfo[] vms, IAndroidTarget filter) { + mVms = vms; + fillTable(mTable, filter); + } + + /** + * Returns the list of known Vms. + *

+ * This is not a copy. Callers must not modify this array. + */ + public VmInfo[] getVms() { + return mVms; + } + + /** + * Sets a selection listener. Set it to null to remove it. + * The listener will be called after this table processed its selection + * events so that the caller can see the updated state. + *

+ * The event's item contains a {@link TableItem}. + * The {@link TableItem#getData()} contains an {@link IAndroidTarget}. + *

+ * It is recommended that the caller uses the {@link #getFirstSelected()} and + * {@link #getAllSelected()} methods instead. + * + * @param selectionListener The new listener or null to remove it. + */ + public void setSelectionListener(SelectionListener selectionListener) { + mSelectionListener = selectionListener; + } + + /** + * Sets the current target selection. + *

+ * If the selection is actually changed, this will invoke the selection listener + * (if any) with a null event. + * + * @param target the target to be selection + * @return true if the target could be selected, false otherwise. + */ + public boolean setSelection(VmInfo target) { + boolean found = false; + boolean modified = false; + for (TableItem i : mTable.getItems()) { + if ((VmInfo) i.getData() == target) { + found = true; + if (!i.getChecked()) { + modified = true; + i.setChecked(true); + } + } else if (i.getChecked()) { + modified = true; + i.setChecked(false); + } + } + + if (modified && mSelectionListener != null) { + mSelectionListener.widgetSelected(null); + } + + return found; + } + + /** + * Returns all selected items. + * This is useful when the table is in multiple-selection mode. + * + * @see #getFirstSelected() + * @return An array of selected items. The list can be empty but not null. + */ + public VmInfo[] getAllSelected() { + ArrayList list = new ArrayList(); + for (TableItem i : mTable.getItems()) { + if (i.getChecked()) { + list.add((IAndroidTarget) i.getData()); + } + } + return list.toArray(new VmInfo[list.size()]); + } + + /** + * Returns the first selected item. + * This is useful when the table is in single-selection mode. + * + * @see #getAllSelected() + * @return The first selected item or null. + */ + public VmInfo getFirstSelected() { + for (TableItem i : mTable.getItems()) { + if (i.getChecked()) { + return (VmInfo) i.getData(); + } + } + return null; + } + + /** + * Adds a listener to adjust the columns width when the parent is resized. + *

+ * If we need something more fancy, we might want to use this: + * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet77.java?view=co + */ + private void adjustColumnsWidth(final Table table, + final TableColumn column0, + final TableColumn column1, + final TableColumn column2, + final TableColumn column3) { + // Add a listener to resize the column to the full width of the table + table.addControlListener(new ControlAdapter() { + @Override + public void controlResized(ControlEvent e) { + Rectangle r = table.getClientArea(); + column0.setWidth(r.width * 30 / 100); // 30% + column1.setWidth(r.width * 45 / 100); // 45% + column2.setWidth(r.width * 15 / 100); // 15% + column3.setWidth(r.width * 10 / 100); // 10% + } + }); + } + + + /** + * Creates a selection listener that will check or uncheck the whole line when + * double-clicked (aka "the default selection"). + */ + private void setupSelectionListener(final Table table) { + // Add a selection listener that will check/uncheck items when they are double-clicked + table.addSelectionListener(new SelectionListener() { + /** Default selection means double-click on "most" platforms */ + public void widgetDefaultSelected(SelectionEvent e) { + if (e.item instanceof TableItem) { + TableItem i = (TableItem) e.item; + i.setChecked(!i.getChecked()); + enforceSingleSelection(i); + updateDescription(i); + } + + if (mSelectionListener != null) { + mSelectionListener.widgetDefaultSelected(e); + } + } + + public void widgetSelected(SelectionEvent e) { + if (e.item instanceof TableItem) { + TableItem i = (TableItem) e.item; + enforceSingleSelection(i); + updateDescription(i); + } + + if (mSelectionListener != null) { + mSelectionListener.widgetSelected(e); + } + } + + /** + * If we're not in multiple selection mode, uncheck all other + * items when this one is selected. + */ + private void enforceSingleSelection(TableItem item) { + if (!mAllowMultipleSelection && item.getChecked()) { + Table parentTable = item.getParent(); + for (TableItem i2 : parentTable.getItems()) { + if (i2 != item && i2.getChecked()) { + i2.setChecked(false); + } + } + } + } + }); + } + + /** + * Fills the table with all VM. + * The table columns are: + *

    + *
  • column 0: sdk name + *
  • column 1: sdk vendor + *
  • column 2: sdk api name + *
  • column 3: sdk version + *
+ */ + private void fillTable(final Table table, IAndroidTarget filter) { + table.removeAll(); + if (mVms != null && mVms.length > 0) { + table.setEnabled(true); + for (VmInfo vm : mVms) { + if (filter == null || filter.isCompatibleBaseFor(vm.getTarget())) { + TableItem item = new TableItem(table, SWT.NONE); + item.setData(vm); + item.setText(0, vm.getName()); + IAndroidTarget target = vm.getTarget(); + item.setText(1, target.getFullName()); + item.setText(2, target.getApiVersionName()); + item.setText(3, Integer.toString(target.getApiVersionNumber())); + } + } + } + + if (table.getItemCount() == 0) { + table.setEnabled(false); + TableItem item = new TableItem(table, SWT.NONE); + item.setData(null); + item.setText(0, "--"); + item.setText(1, "No VM available"); + item.setText(2, "--"); + item.setText(3, "--"); + } + } + + /** + * Sets up a tooltip that displays the current item description. + *

+ * Displaying a tooltip over the table looks kind of odd here. Instead we actually + * display the description in a label under the table. + */ + private void setupTooltip(final Table table) { + /* + * Reference: + * http://dev.eclipse.org/viewcvs/index.cgi/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet125.java?view=markup + */ + + final Listener listener = new Listener() { + public void handleEvent(Event event) { + + switch(event.type) { + case SWT.KeyDown: + case SWT.MouseExit: + case SWT.MouseDown: + return; + + case SWT.MouseHover: + updateDescription(table.getItem(new Point(event.x, event.y))); + break; + + case SWT.Selection: + if (event.item instanceof TableItem) { + updateDescription((TableItem) event.item); + } + break; + + default: + return; + } + + } + }; + + table.addListener(SWT.Dispose, listener); + table.addListener(SWT.KeyDown, listener); + table.addListener(SWT.MouseMove, listener); + table.addListener(SWT.MouseHover, listener); + } + + /** + * Updates the description label with the path of the item's VM, if any. + */ + private void updateDescription(TableItem item) { + if (item != null) { + Object data = item.getData(); + if (data instanceof VmInfo) { + String newTooltip = ((VmInfo) data).getPath(); + mDescription.setText(newTooltip == null ? "" : newTooltip); //$NON-NLS-1$ + } + } + } +}