diff --git a/apps/Fallback/res/values-cs/strings.xml b/apps/Fallback/res/values-cs/strings.xml index b9d34f940..1fc121cf0 100644 --- a/apps/Fallback/res/values-cs/strings.xml +++ b/apps/Fallback/res/values-cs/strings.xml @@ -15,7 +15,7 @@ --> - "Záloha" - "Akce není podporována" - "Tato akce není momentálně podporována." + "Záloha" + "Akce není podporována" + "Tato akce není momentálně podporována." diff --git a/apps/Fallback/res/values-da/strings.xml b/apps/Fallback/res/values-da/strings.xml index b3dfa6313..4584e6130 100644 --- a/apps/Fallback/res/values-da/strings.xml +++ b/apps/Fallback/res/values-da/strings.xml @@ -15,7 +15,7 @@ --> - "Reserve" - "Ikke understøttet handling" - "Handlingen er ikke understøttet i øjeblikket." + "Reserve" + "Ikke understøttet handling" + "Handlingen er ikke understøttet i øjeblikket." diff --git a/apps/Fallback/res/values-de/strings.xml b/apps/Fallback/res/values-de/strings.xml index 8d59ddf39..90bbb165e 100644 --- a/apps/Fallback/res/values-de/strings.xml +++ b/apps/Fallback/res/values-de/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "Nicht unterstützte Aktion" - "Diese Aktion wird zurzeit nicht unterstützt." + "Fallback" + "Nicht unterstützte Aktion" + "Diese Aktion wird zurzeit nicht unterstützt." diff --git a/apps/Fallback/res/values-el/strings.xml b/apps/Fallback/res/values-el/strings.xml index fecaf4af4..b985af7be 100644 --- a/apps/Fallback/res/values-el/strings.xml +++ b/apps/Fallback/res/values-el/strings.xml @@ -15,7 +15,7 @@ --> - "Εναλλακτική" - "Ενέργεια που δεν υποστηρίζεται" - "Αυτή η ενέργεια δεν υποστηρίζεται αυτήν τη στιγμή." + "Εναλλακτική" + "Ενέργεια που δεν υποστηρίζεται" + "Αυτή η ενέργεια δεν υποστηρίζεται αυτήν τη στιγμή." diff --git a/apps/Fallback/res/values-es-rUS/strings.xml b/apps/Fallback/res/values-es-rUS/strings.xml index 0ce57511e..d15a287e4 100644 --- a/apps/Fallback/res/values-es-rUS/strings.xml +++ b/apps/Fallback/res/values-es-rUS/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "Acción no admitida" - "Esa acción no se admite actualmente." + "Fallback" + "Acción no admitida" + "Esa acción no se admite actualmente." diff --git a/apps/Fallback/res/values-es/strings.xml b/apps/Fallback/res/values-es/strings.xml index 0ce57511e..d15a287e4 100644 --- a/apps/Fallback/res/values-es/strings.xml +++ b/apps/Fallback/res/values-es/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "Acción no admitida" - "Esa acción no se admite actualmente." + "Fallback" + "Acción no admitida" + "Esa acción no se admite actualmente." diff --git a/apps/Fallback/res/values-fr/strings.xml b/apps/Fallback/res/values-fr/strings.xml index 024ae4203..df1e299cd 100644 --- a/apps/Fallback/res/values-fr/strings.xml +++ b/apps/Fallback/res/values-fr/strings.xml @@ -15,7 +15,7 @@ --> - "Application de secours" - "Action non prise en charge" - "Cette action n\'est actuellement pas prise en charge." + "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 index d216e59d1..2d08c1bf4 100644 --- a/apps/Fallback/res/values-it/strings.xml +++ b/apps/Fallback/res/values-it/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "Azione non supportata" - "L\'azione non è al momento supportata." + "Fallback" + "Azione non supportata" + "L\'azione non è al momento supportata." diff --git a/apps/Fallback/res/values-ja/strings.xml b/apps/Fallback/res/values-ja/strings.xml index 79aeb42ee..f22090929 100644 --- a/apps/Fallback/res/values-ja/strings.xml +++ b/apps/Fallback/res/values-ja/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "サポートされていない操作" - "現在サポートされていない操作です。" + "Fallback" + "サポートされていない操作" + "現在サポートされていない操作です。" diff --git a/apps/Fallback/res/values-ko/strings.xml b/apps/Fallback/res/values-ko/strings.xml index ec1c33046..2c2973fa9 100644 --- a/apps/Fallback/res/values-ko/strings.xml +++ b/apps/Fallback/res/values-ko/strings.xml @@ -15,7 +15,7 @@ --> - "폴백" - "지원되지 않는 작업" - "이 작업은 현재 지원되지 않습니다." + "폴백" + "지원되지 않는 작업" + "이 작업은 현재 지원되지 않습니다." diff --git a/apps/Fallback/res/values-nb/strings.xml b/apps/Fallback/res/values-nb/strings.xml index 6fed6609a..02814e606 100644 --- a/apps/Fallback/res/values-nb/strings.xml +++ b/apps/Fallback/res/values-nb/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "Ustøttet handling" - "Denne handlingen er ikke støttet nå." + "Fallback" + "Ustøttet handling" + "Denne handlingen er ikke støttet nå." diff --git a/apps/Fallback/res/values-nl/strings.xml b/apps/Fallback/res/values-nl/strings.xml index f347964e4..8989efd80 100644 --- a/apps/Fallback/res/values-nl/strings.xml +++ b/apps/Fallback/res/values-nl/strings.xml @@ -15,7 +15,7 @@ --> - "Reserve" - "Niet-ondersteunde actie" - "Die actie wordt momenteel niet ondersteund." + "Reserve" + "Niet-ondersteunde actie" + "Die actie wordt momenteel niet ondersteund." diff --git a/apps/Fallback/res/values-pl/strings.xml b/apps/Fallback/res/values-pl/strings.xml index 73a176ae2..574049805 100644 --- a/apps/Fallback/res/values-pl/strings.xml +++ b/apps/Fallback/res/values-pl/strings.xml @@ -15,7 +15,7 @@ --> - "Wycofanie" - "Nieobsługiwana czynność" - "Ta czynność nie jest aktualnie obsługiwana." + "Wycofanie" + "Nieobsługiwana czynność" + "Ta czynność nie jest aktualnie obsługiwana." diff --git a/apps/Fallback/res/values-pt-rPT/strings.xml b/apps/Fallback/res/values-pt-rPT/strings.xml index 3c7ec9dcf..b226ea52f 100644 --- a/apps/Fallback/res/values-pt-rPT/strings.xml +++ b/apps/Fallback/res/values-pt-rPT/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "Acção não suportada" - "Esta·acção·ainda·não·é·suportada." + "Fallback" + "Acção não suportada" + "Esta acção ainda não é suportada." diff --git a/apps/Fallback/res/values-pt/strings.xml b/apps/Fallback/res/values-pt/strings.xml index 08a3faaaf..395004cb6 100644 --- a/apps/Fallback/res/values-pt/strings.xml +++ b/apps/Fallback/res/values-pt/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "Ação não suportada" - "Essa ação não é suportada no momento." + "Fallback" + "Ação não suportada" + "Essa ação não é suportada no momento." diff --git a/apps/Fallback/res/values-ru/strings.xml b/apps/Fallback/res/values-ru/strings.xml index 24c3480a2..084c3f3f9 100644 --- a/apps/Fallback/res/values-ru/strings.xml +++ b/apps/Fallback/res/values-ru/strings.xml @@ -15,7 +15,7 @@ --> - "Переход в обходной режим" - "Неподдерживаемое действие" - "В настоящее время это действие не поддерживается." + "Переход в обходной режим" + "Неподдерживаемое действие" + "В настоящее время это действие не поддерживается." diff --git a/apps/Fallback/res/values-sv/strings.xml b/apps/Fallback/res/values-sv/strings.xml index 9dae10ddf..224d946ae 100644 --- a/apps/Fallback/res/values-sv/strings.xml +++ b/apps/Fallback/res/values-sv/strings.xml @@ -15,7 +15,7 @@ --> - "Reserv" - "Åtgärden stöds inte" - "Den här åtgärden stöds inte för närvarande." + "Reserv" + "Åtgärden stöds inte" + "Den här åtgärden stöds inte för närvarande." diff --git a/apps/Fallback/res/values-tr/strings.xml b/apps/Fallback/res/values-tr/strings.xml index 27b860a5e..9c7ed152e 100644 --- a/apps/Fallback/res/values-tr/strings.xml +++ b/apps/Fallback/res/values-tr/strings.xml @@ -15,7 +15,7 @@ --> - "Fallback" - "Desteklenmeyen işlem" - "Bu işlem şu an desteklenmiyor." + "Fallback" + "Desteklenmeyen işlem" + "Bu işlem şu an desteklenmiyor." diff --git a/apps/Fallback/res/values-zh-rCN/strings.xml b/apps/Fallback/res/values-zh-rCN/strings.xml index e6cfde138..5b1fbf8b4 100644 --- a/apps/Fallback/res/values-zh-rCN/strings.xml +++ b/apps/Fallback/res/values-zh-rCN/strings.xml @@ -15,7 +15,7 @@ --> - "后备" - "不支持此操作" - "目前不支持该操作。" + "后备" + "不支持此操作" + "目前不支持该操作。" diff --git a/apps/Fallback/res/values-zh-rTW/strings.xml b/apps/Fallback/res/values-zh-rTW/strings.xml index 52afdbeb6..04d7f4f28 100644 --- a/apps/Fallback/res/values-zh-rTW/strings.xml +++ b/apps/Fallback/res/values-zh-rTW/strings.xml @@ -15,7 +15,7 @@ --> - "備用" - "不支援的操作" - "目前不支援此操作。" + "備用" + "不支援的操作" + "目前不支援此操作。" diff --git a/build/sdk.atree b/build/sdk.atree index 4b7b4a90f..16d65de16 100644 --- a/build/sdk.atree +++ b/build/sdk.atree @@ -31,6 +31,7 @@ bin/sqlite3 tools/sqlite3 bin/dmtracedump tools/dmtracedump bin/hprof-conv tools/hprof-conv bin/mksdcard tools/mksdcard +bin/zipalign tools/zipalign # the uper-jar file that apps link against out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar @@ -39,7 +40,7 @@ out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/ framework/org.eclipse.core.commands_3.4.0.I20080509-2000.jar tools/lib/org.eclipse.core.commands_3.4.0.I20080509-2000.jar framework/org.eclipse.equinox.common_3.4.0.v20080421-2006.jar tools/lib/org.eclipse.equinox.common_3.4.0.v20080421-2006.jar framework/org.eclipse.jface_3.4.2.M20090107-0800.jar tools/lib/org.eclipse.jface_3.4.2.M20090107-0800.jar - +framework/osgi.jar tools/lib/osgi.jar sdk/sdk-build.prop platforms/${PLATFORM_NAME}/build.prop development/tools/scripts/plugin.prop tools/lib/plugin.prop @@ -49,7 +50,6 @@ obj/framework.aidl platforms/${PLATFORM_NAME}/framework.aidl # sdk scripts development/tools/scripts/AndroidManifest.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.template -development/tools/scripts/AndroidManifest.alias.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.alias.template development/tools/scripts/AndroidManifest.tests.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.tests.template development/tools/scripts/iml.template platforms/${PLATFORM_NAME}/templates/iml.template development/tools/scripts/ipr.template platforms/${PLATFORM_NAME}/templates/ipr.template @@ -58,11 +58,8 @@ development/tools/scripts/java_file.template platforms/${PLATFORM_NAME}/template development/tools/scripts/java_tests_file.template platforms/${PLATFORM_NAME}/templates/java_tests_file.template 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 # emacs support development/tools/scripts/android.el tools/lib/android.el @@ -78,6 +75,7 @@ development/samples/SkeletonApp platforms/${PLATFORM_NAME}/samples/SkeletonApp development/samples/Snake platforms/${PLATFORM_NAME}/samples/Snake development/samples/SoftKeyboard platforms/${PLATFORM_NAME}/samples/SoftKeyboard development/samples/JetBoy platforms/${PLATFORM_NAME}/samples/JetBoy +development/samples/SearchableDictionary platforms/${PLATFORM_NAME}/samples/SearchableDictionary # dx bin/dx platforms/${PLATFORM_NAME}/tools/dx @@ -146,9 +144,10 @@ prebuilt/android-arm/kernel/kernel-qemu platforms/${PLATFORM_NAME}/images/kernel external/qemu/android/avd/hardware-properties.ini tools/lib/hardware-properties.ini # emulator skins -development/emulator/skins/HVGA platforms/${PLATFORM_NAME}/skins/HVGA -development/emulator/skins/QVGA platforms/${PLATFORM_NAME}/skins/QVGA -development/emulator/skins/WVGA platforms/${PLATFORM_NAME}/skins/WVGA +development/emulator/skins/HVGA platforms/${PLATFORM_NAME}/skins/HVGA +development/emulator/skins/QVGA platforms/${PLATFORM_NAME}/skins/QVGA +development/emulator/skins/WVGA800 platforms/${PLATFORM_NAME}/skins/WVGA800 +development/emulator/skins/WVGA854 platforms/${PLATFORM_NAME}/skins/WVGA854 # NOTICE files are copied by build/core/Makefile development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/templates/NOTICE.txt diff --git a/build/tools/make_windows_sdk.sh b/build/tools/make_windows_sdk.sh index 52c2f6cfd..d694ea46b 100755 --- a/build/tools/make_windows_sdk.sh +++ b/build/tools/make_windows_sdk.sh @@ -25,25 +25,26 @@ DIST_DIR="$2" TEMP_DIR="$3" [ -z "$TEMP_DIR" ] && TEMP_DIR=${TMP:-/tmp} - function die() { - echo "Error:" $* - echo "Aborting" - exit 1 + echo "Error:" $* + echo "Aborting" + exit 1 } function usage() { - echo "Usage: ${PROG_NAME} linux_or_mac_sdk.zip output_dir [temp_dir]" - echo "If temp_dir is not given, \$TMP is used. If that's missing, /tmp is used." - status - exit 2 + local NAME + NAME=`basename ${PROG_NAME}` + echo "Usage: ${NAME} linux_or_mac_sdk.zip output_dir [temp_dir]" + echo "If temp_dir is not given, \$TMP is used. If that's missing, /tmp is used." + status + exit 2 } function status() { - echo "Current values:" - echo "- Input SDK: ${SDK_ZIP:-missing}" - echo "- Output dir: ${DIST_DIR:-missing}" - echo "- Temp dir: ${TEMP_DIR:-missing}" + echo "Current values:" + echo "- Input SDK: ${SDK_ZIP:-missing}" + echo "- Output dir: ${DIST_DIR:-missing}" + echo "- Temp dir: ${TEMP_DIR:-missing}" } function check() { @@ -92,7 +93,14 @@ function build() { make -j 4 emulator || die "Build failed" # Disable parallel build: it generates "permission denied" issues when # multiple "ar.exe" are running in parallel. - make prebuilt adb fastboot aidl aapt dexdump dmtracedump hprof-conv mksdcard sqlite3 \ + make aapt adb aidl \ + prebuilt \ + dexdump dmtracedump \ + fastboot \ + hprof-conv \ + mksdcard \ + sqlite3 \ + zipalign \ || die "Build failed" } @@ -124,12 +132,16 @@ function package() { "Instead found " $THE_PLATFORM [[ -d "$PLATFORM_TOOLS" ]] || die "Missing folder $PLATFORM_TOOLS." + # Package USB Driver + if type package_usb_driver 2>&1 | grep -q function ; then + package_usb_driver $TEMP_SDK_DIR + fi # Remove obsolete stuff from tools & platform TOOLS="$TEMP_SDK_DIR/tools" LIB="$TEMP_SDK_DIR/tools/lib" rm -v "$TOOLS"/{adb,android,apkbuilder,ddms,dmtracedump,draw9patch,emulator} - rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,mksdcard,sqlite3,traceview} + rm -v "$TOOLS"/{hierarchyviewer,hprof-conv,mksdcard,sqlite3,traceview,zipalign} rm -v "$LIB"/*/swt.jar rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump} @@ -183,8 +195,9 @@ function package() { # Copy or move platform specific tools to the default platform. cp -v dalvik/dx/etc/dx.bat "$PLATFORM_TOOLS"/ - # Note: mgwz.dll must be in same folder than aapt.exe - mv -v "$TOOLS"/{aapt.exe,aidl.exe,dexdump.exe,mgwz.dll} "$PLATFORM_TOOLS"/ + mv -v "$TOOLS"/{aapt.exe,aidl.exe,dexdump.exe} "$PLATFORM_TOOLS"/ + # Note: mgwz.dll must be both in SDK/tools for zipalign and in SDK/platform/XYZ/tools/ for aapt + cp -v "$TOOLS"/mgwz.dll "$PLATFORM_TOOLS"/ # Fix EOL chars to make window users happy - fix all files at the top level only # as well as all batch files including those in platforms//tools/ @@ -200,14 +213,14 @@ function package() { # Now move the final zip from the temp dest to the final dist dir mv -v "$TEMP_DIR/$DEST_NAME_ZIP" "$DIST_DIR/$DEST_NAME_ZIP" + # We want fastboot and adb (and its DLLs) next to the new SDK + for i in fastboot.exe adb.exe AdbWinApi.dll AdbWinUsbApi.dll; do + cp -vf out/host/windows-x86/bin/$i "$DIST_DIR"/$i + done + echo "Done" echo echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP" - - # We want fastboot and adb next to the new SDK - for i in fastboot.exe adb.exe AdbWinApi.dll; do - mv -vf out/host/windows-x86/bin/$i "$DIST_DIR"/$i - done } check diff --git a/cmds/monkey/Android.mk b/cmds/monkey/Android.mk index 6bedc43e8..ba9cf0410 100644 --- a/cmds/monkey/Android.mk +++ b/cmds/monkey/Android.mk @@ -7,6 +7,7 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files) LOCAL_MODULE := monkey include $(BUILD_JAVA_LIBRARY) +################################################################ include $(CLEAR_VARS) ALL_PREBUILT += $(TARGET_OUT)/bin/monkey $(TARGET_OUT)/bin/monkey : $(LOCAL_PATH)/monkey | $(ACP) diff --git a/cmds/monkey/README.NETWORK.txt b/cmds/monkey/README.NETWORK.txt new file mode 100644 index 000000000..4e78b6c8b --- /dev/null +++ b/cmds/monkey/README.NETWORK.txt @@ -0,0 +1,129 @@ +SIMPLE PROTOCOL FOR AUTOMATED NETWORK CONTROL + +The Simple Protocol for Automated Network Control was designed to be a +low-level way to programmability inject KeyEvents and MotionEvents +into the input system. The idea is that a process will run on a host +computer that will support higher-level operations (like conditionals, +etc.) and will talk (via TCP over ADB) to the device in Simple +Protocol for Automated Network Control. For security reasons, the +Monkey only binds to localhost, so you will need to use adb to setup +port forwarding to actually talk to the device. + +INITIAL SETUP + +Setup port forwarding from a local port on your machine to a port on +the device: + +$ adb forward tcp:1080 tcp:1080 + +Start the monkey server + +$ adb shell monkey --port 1080 + +Now you're ready to run commands + +COMMAND LIST + +Individual commands are separated by newlines. The Monkey will +respond to every command with a line starting with OK for commands +that executed without a problem, or a line starting with ERROR for +commands that had problems being run. For commands that return a +value, that value is returned on the same line as the OK or ERROR +response. The value is everything after (but not include) the colon +on that line. For ERROR values, this could be a message indicating +what happened. A possible example: + +key down menu +OK +touch monkey +ERROR: monkey not a number +getvar sdk +OK: donut +getvar foo +ERROR: no such var + +The complete list of commands follows: + +key [down|up] keycode + +This command injects KeyEvent's into the input system. The keycode +parameter refers to the KEYCODE list in the KeyEvent class +(http://developer.android.com/reference/android/view/KeyEvent.html). +The format of that parameter is quite flexible. Using the menu key as +an example, it can be 82 (the integer value of the keycode), +KEYCODE_MENU (the name of the keycode), or just menu (and the Monkey +will add the KEYCODE part). Do note that this last part doesn't work +for things like KEYCODE_1 for obvious reasons. + +Note that sending a full button press requires sending both the down +and the up event for that key + +touch [down|up|move] x y + +This command injects a MotionEvent into the input system that +simulates a user touching the touchscreen (or a pointer event). x and +y specify coordinates on the display (0 0 being the upper left) for +the touch event to happen. Just like key events, touch events at a +single location require both a down and an up. To simulate dragging, +send a "touch down", then a series of "touch move" events (to simulate +the drag), followed by a "touch up" at the final location. + +trackball dx dy + +This command injects a MotionEvent into the input system that +simulates a user using the trackball. dx and dy indicates the amount +of change in the trackball location (as opposed to exact coordinates +that the touch events use) + +flip [open|close] + +This simulates the opening or closing the keyboard (like on dream). + +wake + +This command will wake the device up from sleep and allow user input. + +tap x y +The tap command is a shortcut for the touch command. It will +automatically send both the up and the down event. + +press keycode + +The press command is a shortcut for the key command. The keycode +paramter works just like the key command and will automatically send +both the up and the down event. + +type string + +This command will simulate a user typing the given string on the +keyboard by generating the proper KeyEvents. + +listvar + +This command lists all the vars that the monkey knows about. They are +returned as a whitespace separated list. + +getvar varname + +This command returns the value of the given var. listvar can be used +to find out what vars are supported. + +quit + +Fully quit the monkey and accept no new sessions. + +done + +Close the current session and allow a new session to connect + +OTHER NOTES + +There are some convenience features added to allow running without +needing a host process. + +Lines starting with a # character are considered comments. The Monkey +eats them and returns no indication that it did anything (no ERROR and +no OK). + +You can put the Monkey to sleep by using the "sleep" command with a +single argument, how many ms to sleep. diff --git a/cmds/monkey/example_script.txt b/cmds/monkey/example_script.txt new file mode 100644 index 000000000..5c1c61de2 --- /dev/null +++ b/cmds/monkey/example_script.txt @@ -0,0 +1,57 @@ +# Touch the android +touch down 160 200 +touch up 160 200 +sleep 1000 + +# Hit Next +touch down 300 450 +touch up 300 450 +sleep 1000 + +# Hit Next +touch down 300 450 +touch up 300 450 +sleep 1000 + +# Hit Next +touch down 300 450 +touch up 300 450 +sleep 1000 + +# Go down and select the account username +key down dpad_down +key up dpad_down +key down dpad_down +key up dpad_down +key down dpad_center +key up dpad_center +# account name: bill +key down b +key up b +key down i +key up i +key down l +key up l +key down l +key up l + +# Go down to the password field +key down dpad_down +key up dpad_down + +# password: bill +key down b +key up b +key down i +key up i +key down l +key up l +key down l +key up l + +# Select next +touch down 300 450 +touch up 300 450 + +# quit +quit diff --git a/cmds/monkey/src/com/android/commands/monkey/Monkey.java b/cmds/monkey/src/com/android/commands/monkey/Monkey.java index 7ebd7274f..521de16d6 100644 --- a/cmds/monkey/src/com/android/commands/monkey/Monkey.java +++ b/cmds/monkey/src/com/android/commands/monkey/Monkey.java @@ -47,10 +47,10 @@ import java.util.List; * Application that injects random key events and other actions into the system. */ public class Monkey { - + /** * Monkey Debugging/Dev Support - * + * * All values should be zero when checking in. */ private final static int DEBUG_ALLOW_ANY_STARTS = 0; @@ -74,20 +74,20 @@ public class Monkey { /** Ignore any not responding timeouts while running? */ private boolean mIgnoreTimeouts; - + /** Ignore security exceptions when launching activities */ /** (The activity launch still fails, but we keep pluggin' away) */ private boolean mIgnoreSecurityExceptions; - + /** Monitor /data/tombstones and stop the monkey if new files appear. */ private boolean mMonitorNativeCrashes; - + /** Send no events. Use with long throttle-time to watch user operations */ private boolean mSendNoEvents; /** This is set when we would like to abort the running of the monkey. */ private boolean mAbort; - + /** This is set by the ActivityController thread to request collection of ANR trace files */ private boolean mRequestAnrTraces = false; @@ -96,7 +96,7 @@ public class Monkey { /** Kill the process after a timeout or crash. */ private boolean mKillProcessAfterError; - + /** Generate hprof reports before/after monkey runs */ private boolean mGenerateHprof; @@ -106,16 +106,16 @@ public class Monkey { ArrayList mMainCategories = new ArrayList(); /** Applications we can switch to. */ private ArrayList mMainApps = new ArrayList(); - + /** The delay between event inputs **/ long mThrottle = 0; - + /** The number of iterations **/ int mCount = 1000; - + /** The random number seed **/ long mSeed = 0; - + /** Dropped-event statistics **/ long mDroppedKeyEvents = 0; long mDroppedPointerEvents = 0; @@ -124,14 +124,21 @@ public class Monkey { /** a filename to the script (if any) **/ private String mScriptFileName = null; - + + /** a TCP port to listen on for remote commands. */ + private int mServerPort = -1; + private static final File TOMBSTONES_PATH = new File("/data/tombstones"); private HashSet mTombstones = null; - - float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT]; + + float[] mFactors = new float[MonkeySourceRandom.FACTORZ_COUNT]; MonkeyEventSource mEventSource; private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor(); - + + // information on the current activity. + public static Intent currentIntent; + public static String currentPackage; + /** * Monitor operations happening in the system. */ @@ -142,21 +149,24 @@ public class Monkey { System.out.println(" // " + (allow ? "Allowing" : "Rejecting") + " start of " + intent + " in package " + pkg); } + currentPackage = pkg; + currentIntent = intent; return allow; } - + public boolean activityResuming(String pkg) { System.out.println(" // activityResuming(" + pkg + ")"); boolean allow = checkEnteringPackage(pkg) || (DEBUG_ALLOW_ANY_RESTARTS != 0); if (!allow) { if (mVerbose > 0) { System.out.println(" // " + (allow ? "Allowing" : "Rejecting") - + " resume of package " + pkg); + + " resume of package " + pkg); } } + currentPackage = pkg; return allow; } - + private boolean checkEnteringPackage(String pkg) { if (pkg == null) { return true; @@ -168,7 +178,7 @@ public class Monkey { return mValidPackages.contains(pkg); } } - + public boolean appCrashed(String processName, int pid, String shortMsg, String longMsg, byte[] crashData) { System.err.println("// CRASH: " + processName + " (pid " + pid @@ -223,14 +233,14 @@ public class Monkey { return 1; } } - + /** * Run the procrank tool to insert system status information into the debug report. */ private void reportProcRank() { commandLineReport("procrank", "procrank"); } - + /** * Run "cat /data/anr/traces.txt". Wait about 5 seconds first, to let the asynchronous * report writing complete. @@ -238,21 +248,21 @@ public class Monkey { private void reportAnrTraces() { try { Thread.sleep(5 * 1000); - } catch (InterruptedException e) { + } catch (InterruptedException e) { } commandLineReport("anr traces", "cat /data/anr/traces.txt"); } - + /** * Run "dumpsys meminfo" - * + * * NOTE: You cannot perform a dumpsys call from the ActivityController callback, as it will * deadlock. This should only be called from the main loop of the monkey. */ private void reportDumpsysMemInfo() { commandLineReport("meminfo", "dumpsys meminfo"); } - + /** * Print report from a single command line. * @param reportName Simple tag that will print before the report and in various annotations. @@ -266,7 +276,7 @@ public class Monkey { try { // Process must be fully qualified here because android.os.Process is used elsewhere java.lang.Process p = Runtime.getRuntime().exec(command); - + // pipe everything from process stdout -> System.err InputStream inStream = p.getInputStream(); InputStreamReader inReader = new InputStreamReader(inStream); @@ -275,7 +285,7 @@ public class Monkey { while ((s = inBuffer.readLine()) != null) { System.err.println(s); } - + int status = p.waitFor(); System.err.println("// " + reportName + " status was " + status); } catch (Exception e) { @@ -307,26 +317,26 @@ public class Monkey { Debug.waitForDebugger(); } } - + // Default values for some command-line options mVerbose = 0; mCount = 1000; mSeed = 0; mThrottle = 0; - + // prepare for command-line processing mArgs = args; mNextArg = 0; - + //set a positive value, indicating none of the factors is provided yet for (int i = 0; i < MonkeySourceRandom.FACTORZ_COUNT; i++) { mFactors[i] = 1.0f; } - + if (!processOptions()) { return -1; } - + // now set up additional data in preparation for launch if (mMainCategories.size() == 0) { mMainCategories.add(Intent.CATEGORY_LAUNCHER); @@ -348,11 +358,11 @@ public class Monkey { } } } - + if (!checkInternalConfiguration()) { return -2; } - + if (!getSystemInterfaces()) { return -3; } @@ -360,11 +370,19 @@ public class Monkey { if (!getMainApps()) { return -4; } - + if (mScriptFileName != null) { // script mode, ignore other options mEventSource = new MonkeySourceScript(mScriptFileName, mThrottle); mEventSource.setVerbose(mVerbose); + } else if (mServerPort != -1) { + try { + mEventSource = new MonkeySourceNetwork(mServerPort); + } catch (IOException e) { + System.out.println("Error binding to network socket."); + return -5; + } + mCount = Integer.MAX_VALUE; } else { // random source by default if (mVerbose >= 2) { // check seeding performance @@ -378,7 +396,7 @@ public class Monkey { ((MonkeySourceRandom) mEventSource).setFactors(i, mFactors[i]); } } - + //in random mode, we start with a random activity ((MonkeySourceRandom) mEventSource).generateActivity(); } @@ -387,7 +405,7 @@ public class Monkey { if (!mEventSource.validate()) { return -5; } - + if (mScriptFileName != null) { // in random mode, count is the number of single events // while in script mode, count is the number of repetition @@ -396,12 +414,12 @@ public class Monkey { mCount = mCount * ((MonkeySourceScript) mEventSource) .getOneRoundEventCount(); } - + // If we're profiling, do it immediately before/after the main monkey loop if (mGenerateHprof) { signalPersistentProcesses(); } - + mNetworkMonitor.start(); int crashedAtCycle = runMonkeyCycles(); mNetworkMonitor.stop(); @@ -423,7 +441,7 @@ public class Monkey { System.out.println("// Generated profiling reports in /data/misc"); } } - + try { mAm.setActivityController(null); mNetworkMonitor.unregister(mAm); @@ -434,7 +452,7 @@ public class Monkey { crashedAtCycle = mCount - 1; } } - + // report dropped event stats if (mVerbose > 0) { System.out.print(":Dropped: keys="); @@ -446,7 +464,7 @@ public class Monkey { System.out.print(" flips="); System.out.println(mDroppedFlipEvents); } - + // report network stats mNetworkMonitor.dump(); @@ -461,10 +479,10 @@ public class Monkey { return 0; } } - + /** * Process the command-line options - * + * * @return Returns true if options were parsed with no apparent errors. */ private boolean processOptions() { @@ -498,28 +516,28 @@ public class Monkey { } else if (opt.equals("--hprof")) { mGenerateHprof = true; } else if (opt.equals("--pct-touch")) { - mFactors[MonkeySourceRandom.FACTOR_TOUCH] = + mFactors[MonkeySourceRandom.FACTOR_TOUCH] = -nextOptionLong("touch events percentage"); } else if (opt.equals("--pct-motion")) { - mFactors[MonkeySourceRandom.FACTOR_MOTION] = + mFactors[MonkeySourceRandom.FACTOR_MOTION] = -nextOptionLong("motion events percentage"); } else if (opt.equals("--pct-trackball")) { - mFactors[MonkeySourceRandom.FACTOR_TRACKBALL] = + mFactors[MonkeySourceRandom.FACTOR_TRACKBALL] = -nextOptionLong("trackball events percentage"); } else if (opt.equals("--pct-nav")) { - mFactors[MonkeySourceRandom.FACTOR_NAV] = + mFactors[MonkeySourceRandom.FACTOR_NAV] = -nextOptionLong("nav events percentage"); } else if (opt.equals("--pct-majornav")) { - mFactors[MonkeySourceRandom.FACTOR_MAJORNAV] = + mFactors[MonkeySourceRandom.FACTOR_MAJORNAV] = -nextOptionLong("major nav events percentage"); } else if (opt.equals("--pct-appswitch")) { - mFactors[MonkeySourceRandom.FACTOR_APPSWITCH] = + mFactors[MonkeySourceRandom.FACTOR_APPSWITCH] = -nextOptionLong("app switch events percentage"); } else if (opt.equals("--pct-flip")) { mFactors[MonkeySourceRandom.FACTOR_FLIP] = -nextOptionLong("keyboard flip percentage"); } else if (opt.equals("--pct-anyevent")) { - mFactors[MonkeySourceRandom.FACTOR_ANYTHING] = + mFactors[MonkeySourceRandom.FACTOR_ANYTHING] = -nextOptionLong("any events percentage"); } else if (opt.equals("--throttle")) { mThrottle = nextOptionLong("delay (in milliseconds) to wait between events"); @@ -527,7 +545,9 @@ public class Monkey { // do nothing - it's caught at the very start of run() } else if (opt.equals("--dbg-no-events")) { mSendNoEvents = true; - } else if (opt.equals("-f")) { + } else if (opt.equals("--port")) { + mServerPort = (int) nextOptionLong("Server port to listen on for commands"); + } else if (opt.equals("-f")) { mScriptFileName = nextOptionData(); } else if (opt.equals("-h")) { showUsage(); @@ -544,19 +564,23 @@ public class Monkey { return false; } - String countStr = nextArg(); - if (countStr == null) { - System.err.println("** Error: Count not specified"); - showUsage(); - return false; - } + // If a server port hasn't been specified, we need to specify + // a count + if (mServerPort == -1) { + String countStr = nextArg(); + if (countStr == null) { + System.err.println("** Error: Count not specified"); + showUsage(); + return false; + } - try { - mCount = Integer.parseInt(countStr); - } catch (NumberFormatException e) { - System.err.println("** Error: Count is not a number"); - showUsage(); - return false; + try { + mCount = Integer.parseInt(countStr); + } catch (NumberFormatException e) { + System.err.println("** Error: Count is not a number"); + showUsage(); + return false; + } } return true; @@ -564,7 +588,7 @@ public class Monkey { /** * Check for any internal configuration (primarily build-time) errors. - * + * * @return Returns true if ready to rock. */ private boolean checkInternalConfiguration() { @@ -585,7 +609,7 @@ public class Monkey { /** * Attach to the required system interfaces. - * + * * @return Returns true if all system interfaces were available. */ private boolean getSystemInterfaces() { @@ -621,7 +645,7 @@ public class Monkey { /** * Using the restrictions provided (categories & packages), generate a list of activities * that we can actually switch to. - * + * * @return Returns true if it could successfully build a list of target activities */ private boolean getMainApps() { @@ -644,7 +668,7 @@ public class Monkey { final int NA = mainApps.size(); for (int a = 0; a < NA; a++) { ResolveInfo r = mainApps.get(a); - if (mValidPackages.size() == 0 || + if (mValidPackages.size() == 0 || mValidPackages.contains(r.activityInfo.applicationInfo.packageName)) { if (mVerbose >= 2) { // very verbose System.out.println("// + Using main activity " @@ -676,15 +700,15 @@ public class Monkey { System.out.println("** No activities found to run, monkey aborted."); return false; } - + return true; } /** * Run mCount cycles and see if we hit any crashers. - * + * * TODO: Meta state on keys - * + * * @return Returns the last cycle which executed. If the value == mCount, no errors detected. */ private int runMonkeyCycles() { @@ -749,9 +773,11 @@ public class Monkey { } else if (injectCode == MonkeyEvent.INJECT_ERROR_SECURITY_EXCEPTION) { systemCrashed = !mIgnoreSecurityExceptions; } + } else { + // Event Source has signaled that we have no more events to process + break; } } - // If we got this far, we succeeded! return mCount; } @@ -775,18 +801,18 @@ public class Monkey { /** * Watch for appearance of new tombstone files, which indicate native crashes. - * + * * @return Returns true if new files have appeared in the list */ private boolean checkNativeCrashes() { String[] tombstones = TOMBSTONES_PATH.list(); - + // shortcut path for usually empty directory, so we don't waste even more objects if ((tombstones == null) || (tombstones.length == 0)) { mTombstones = null; return false; } - + // use set logic to look for new files HashSet newStones = new HashSet(); for (String x : tombstones) { @@ -804,14 +830,14 @@ public class Monkey { /** * Return the next command line option. This has a number of special cases which * closely, but not exactly, follow the POSIX command line options patterns: - * + * * -- means to stop processing additional options * -z means option z * -z ARGS means option z with (non-optional) arguments ARGS * -zARGS means option z with (optional) arguments ARGS * --zz means option zz * --zz ARGS means option zz with (non-optional) arguments ARGS - * + * * Note that you cannot combine single letter options; -abc != -a -b -c * * @return Returns the option string, or null if there are no more options. @@ -857,10 +883,10 @@ public class Monkey { mNextArg++; return data; } - + /** * Returns a long converted from the next data argument, with error handling if not available. - * + * * @param opt The name of the option. * @return Returns a long converted from the argument. */ @@ -904,6 +930,7 @@ public class Monkey { System.err.println(" [--pct-appswitch PERCENT] [--pct-flip PERCENT]"); System.err.println(" [--pct-anyevent PERCENT]"); System.err.println(" [--wait-dbg] [--dbg-no-events] [-f scriptfile]"); + System.err.println(" [--port port]"); System.err.println(" [-s SEED] [-v [-v] ...] [--throttle MILLISEC]"); System.err.println(" COUNT"); } diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java index d926be8e4..2783dde21 100644 --- a/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyEvent.java @@ -22,7 +22,7 @@ import android.view.IWindowManager; /** * abstract class for monkey event */ -public abstract class MonkeyEvent { +public abstract class MonkeyEvent { protected int eventType; public static final int EVENT_TYPE_KEY = 0; public static final int EVENT_TYPE_POINTER = 1; @@ -30,41 +30,42 @@ public abstract class MonkeyEvent { public static final int EVENT_TYPE_ACTIVITY = 3; public static final int EVENT_TYPE_FLIP = 4; // Keyboard flip public static final int EVENT_TYPE_THROTTLE = 5; - + public static final int EVENT_TYPE_NOOP = 6; + public static final int INJECT_SUCCESS = 1; public static final int INJECT_FAIL = 0; // error code for remote exception during injection - public static final int INJECT_ERROR_REMOTE_EXCEPTION = -1; + public static final int INJECT_ERROR_REMOTE_EXCEPTION = -1; // error code for security exception during injection public static final int INJECT_ERROR_SECURITY_EXCEPTION = -2; - + public MonkeyEvent(int type) { eventType = type; } - - /** + + /** * @return event type - */ + */ public int getEventType() { return eventType; } - + /** * @return true if it is safe to throttle after this event, and false otherwise. */ public boolean isThrottlable() { return true; } - - + + /** * a method for injecting event * @param iwm wires to current window manager * @param iam wires to current activity manager - * @param verbose a log switch + * @param verbose a log switch * @return INJECT_SUCCESS if it goes through, and INJECT_FAIL if it fails * in the case of exceptions, return its corresponding error code */ - public abstract int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose); + public abstract int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose); } diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java index 877ebb576..d9c68af50 100644 --- a/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyKeyEvent.java @@ -23,7 +23,7 @@ import android.view.KeyEvent; /** * monkey key event */ -public class MonkeyKeyEvent extends MonkeyEvent { +public class MonkeyKeyEvent extends MonkeyEvent { private long mDownTime = -1; private int mMetaState = -1; private int mAction = -1; @@ -32,18 +32,25 @@ public class MonkeyKeyEvent extends MonkeyEvent { private int mRepeatCount = -1; private int mDeviceId = -1; private long mEventTime = -1; - + + private KeyEvent keyEvent = null; + public MonkeyKeyEvent(int action, int keycode) { super(EVENT_TYPE_KEY); mAction = action; mKeyCode = keycode; } - + + public MonkeyKeyEvent(KeyEvent e) { + super(EVENT_TYPE_KEY); + keyEvent = e; + } + public MonkeyKeyEvent(long downTime, long eventTime, int action, int code, int repeat, int metaState, int device, int scancode) { super(EVENT_TYPE_KEY); - + mAction = action; mKeyCode = code; mMetaState = metaState; @@ -53,49 +60,52 @@ public class MonkeyKeyEvent extends MonkeyEvent { mDownTime = downTime; mEventTime = eventTime; } - + public int getKeyCode() { return mKeyCode; } - + public int getAction() { return mAction; } - + public long getDownTime() { return mDownTime; } - + public long getEventTime() { return mEventTime; } - + public void setDownTime(long downTime) { mDownTime = downTime; } - + public void setEventTime(long eventTime) { mEventTime = eventTime; } - - /** + + /** * @return the key event - */ + */ private KeyEvent getEvent() { - if (mDeviceId < 0) { - return new KeyEvent(mAction, mKeyCode); - } - - // for scripts - return new KeyEvent(mDownTime, mEventTime, mAction, - mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode); + if (keyEvent == null) { + if (mDeviceId < 0) { + keyEvent = new KeyEvent(mAction, mKeyCode); + } else { + // for scripts + keyEvent = new KeyEvent(mDownTime, mEventTime, mAction, + mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode); + } + } + return keyEvent; } @Override public boolean isThrottlable() { return (getAction() == KeyEvent.ACTION_UP); } - + @Override public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) { if (verbose > 1) { @@ -124,7 +134,7 @@ public class MonkeyKeyEvent extends MonkeyEvent { } catch (RemoteException ex) { return MonkeyEvent.INJECT_ERROR_REMOTE_EXCEPTION; } - + return MonkeyEvent.INJECT_SUCCESS; } } diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeyNoopEvent.java b/cmds/monkey/src/com/android/commands/monkey/MonkeyNoopEvent.java new file mode 100644 index 000000000..ea9273576 --- /dev/null +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeyNoopEvent.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.commands.monkey; + +import java.util.List; + +import android.app.IActivityManager; +import android.view.IWindowManager; + + +/** + * monkey noop event (don't do anything). + */ +public class MonkeyNoopEvent extends MonkeyEvent { + + public MonkeyNoopEvent() { + super(MonkeyEvent.EVENT_TYPE_NOOP); + } + + @Override + public int injectEvent(IWindowManager iwm, IActivityManager iam, int verbose) { + // No real work to do + if (verbose > 1) { + System.out.println("NOOP"); + } + return MonkeyEvent.INJECT_SUCCESS; + } +} diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java new file mode 100644 index 000000000..a9a1db416 --- /dev/null +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetwork.java @@ -0,0 +1,697 @@ +/* + * Copyright 2009, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.commands.monkey; + +import android.content.Context; +import android.os.IPowerManager; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.os.SystemClock; +import android.util.Log; +import android.view.KeyCharacterMap; +import android.view.KeyEvent; +import android.view.MotionEvent; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.lang.Integer; +import java.lang.NumberFormatException; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; +import java.util.LinkedList; +import java.util.List; +import java.util.Queue; +import java.util.StringTokenizer; + +/** + * An Event source for getting Monkey Network Script commands from + * over the network. + */ +public class MonkeySourceNetwork implements MonkeyEventSource { + private static final String TAG = "MonkeyStub"; + + /** + * ReturnValue from the MonkeyCommand that indicates whether the + * command was sucessful or not. + */ + public static class MonkeyCommandReturn { + private final boolean success; + private final String message; + + public MonkeyCommandReturn(boolean success) { + this.success = success; + this.message = null; + } + + public MonkeyCommandReturn(boolean success, + String message) { + this.success = success; + this.message = message; + } + + boolean hasMessage() { + return message != null; + } + + String getMessage() { + return message; + } + + boolean wasSuccessful() { + return success; + } + } + + public final static MonkeyCommandReturn OK = new MonkeyCommandReturn(true); + public final static MonkeyCommandReturn ERROR = new MonkeyCommandReturn(false); + public final static MonkeyCommandReturn EARG = new MonkeyCommandReturn(false, + "Invalid Argument"); + + /** + * Interface that MonkeyCommands must implement. + */ + public interface MonkeyCommand { + /** + * Translate the command line into a sequence of MonkeyEvents. + * + * @param command the command line. + * @param queue the command queue. + * @returs MonkeyCommandReturn indicating what happened. + */ + MonkeyCommandReturn translateCommand(List command, CommandQueue queue); + } + + /** + * Command to simulate closing and opening the keyboard. + */ + private static class FlipCommand implements MonkeyCommand { + // flip open + // flip closed + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() > 1) { + String direction = command.get(1); + if ("open".equals(direction)) { + queue.enqueueEvent(new MonkeyFlipEvent(true)); + return OK; + } else if ("close".equals(direction)) { + queue.enqueueEvent(new MonkeyFlipEvent(false)); + return OK; + } + } + return EARG; + } + } + + /** + * Command to send touch events to the input system. + */ + private static class TouchCommand implements MonkeyCommand { + // touch [down|up|move] [x] [y] + // touch down 120 120 + // touch move 140 140 + // touch up 140 140 + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() == 4) { + String actionName = command.get(1); + int x = 0; + int y = 0; + try { + x = Integer.parseInt(command.get(2)); + y = Integer.parseInt(command.get(3)); + } catch (NumberFormatException e) { + // Ok, it wasn't a number + Log.e(TAG, "Got something that wasn't a number", e); + return EARG; + } + + // figure out the action + int action = -1; + if ("down".equals(actionName)) { + action = MotionEvent.ACTION_DOWN; + } else if ("up".equals(actionName)) { + action = MotionEvent.ACTION_UP; + } else if ("move".equals(actionName)) { + action = MotionEvent.ACTION_MOVE; + } + if (action == -1) { + Log.e(TAG, "Got a bad action: " + actionName); + return EARG; + } + + queue.enqueueEvent(new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, + -1, action, x, y, 0)); + return OK; + } + return EARG; + } + } + + /** + * Command to send Trackball events to the input system. + */ + private static class TrackballCommand implements MonkeyCommand { + // trackball [dx] [dy] + // trackball 1 0 -- move right + // trackball -1 0 -- move left + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() == 3) { + int dx = 0; + int dy = 0; + try { + dx = Integer.parseInt(command.get(1)); + dy = Integer.parseInt(command.get(2)); + } catch (NumberFormatException e) { + // Ok, it wasn't a number + Log.e(TAG, "Got something that wasn't a number", e); + return EARG; + } + queue.enqueueEvent(new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, -1, + MotionEvent.ACTION_MOVE, dx, dy, 0)); + return OK; + + } + return EARG; + } + } + + /** + * Command to send Key events to the input system. + */ + private static class KeyCommand implements MonkeyCommand { + // key [down|up] [keycode] + // key down 82 + // key up 82 + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() == 3) { + int keyCode = getKeyCode(command.get(2)); + if (keyCode < 0) { + // Ok, you gave us something bad. + Log.e(TAG, "Can't find keyname: " + command.get(2)); + return EARG; + } + Log.d(TAG, "keycode: " + keyCode); + int action = -1; + if ("down".equals(command.get(1))) { + action = KeyEvent.ACTION_DOWN; + } else if ("up".equals(command.get(1))) { + action = KeyEvent.ACTION_UP; + } + if (action == -1) { + Log.e(TAG, "got unknown action."); + return EARG; + } + queue.enqueueEvent(new MonkeyKeyEvent(action, keyCode)); + return OK; + } + return EARG; + } + } + + /** + * Get an integer keycode value from a given keyname. + * + * @param keyName the key name to get the code for + * @returns the integer keycode value, or -1 on error. + */ + private static int getKeyCode(String keyName) { + int keyCode = -1; + try { + keyCode = Integer.parseInt(keyName); + } catch (NumberFormatException e) { + // Ok, it wasn't a number, see if we have a + // keycode name for it + keyCode = MonkeySourceRandom.getKeyCode(keyName); + if (keyCode == -1) { + // OK, one last ditch effort to find a match. + // Build the KEYCODE_STRING from the string + // we've been given and see if that key + // exists. This would allow you to do "key + // down menu", for example. + keyCode = MonkeySourceRandom.getKeyCode("KEYCODE_" + keyName.toUpperCase()); + } + } + return keyCode; + } + + /** + * Command to put the Monkey to sleep. + */ + private static class SleepCommand implements MonkeyCommand { + // sleep 2000 + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() == 2) { + int sleep = -1; + String sleepStr = command.get(1); + try { + sleep = Integer.parseInt(sleepStr); + } catch (NumberFormatException e) { + Log.e(TAG, "Not a number: " + sleepStr, e); + return EARG; + } + queue.enqueueEvent(new MonkeyThrottleEvent(sleep)); + return OK; + } + return EARG; + } + } + + /** + * Command to type a string + */ + private static class TypeCommand implements MonkeyCommand { + // wake + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() == 2) { + String str = command.get(1); + + char[] chars = str.toString().toCharArray(); + + // Convert the string to an array of KeyEvent's for + // the built in keymap. + KeyCharacterMap keyCharacterMap = KeyCharacterMap. + load(KeyCharacterMap.BUILT_IN_KEYBOARD); + KeyEvent[] events = keyCharacterMap.getEvents(chars); + + // enqueue all the events we just got. + for (KeyEvent event : events) { + queue.enqueueEvent(new MonkeyKeyEvent(event)); + } + return OK; + } + return EARG; + } + } + + /** + * Command to wake the device up + */ + private static class WakeCommand implements MonkeyCommand { + // wake + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (!wake()) { + return ERROR; + } + return OK; + } + } + + /** + * Command to "tap" at a location (Sends a down and up touch + * event). + */ + private static class TapCommand implements MonkeyCommand { + // tap x y + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() == 3) { + int x = 0; + int y = 0; + try { + x = Integer.parseInt(command.get(1)); + y = Integer.parseInt(command.get(2)); + } catch (NumberFormatException e) { + // Ok, it wasn't a number + Log.e(TAG, "Got something that wasn't a number", e); + return EARG; + } + + queue.enqueueEvent(new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, + -1, MotionEvent.ACTION_DOWN, + x, y, 0)); + queue.enqueueEvent(new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, + -1, MotionEvent.ACTION_UP, + x, y, 0)); + return OK; + } + return EARG; + } + } + + /** + * Command to "press" a buttons (Sends an up and down key event.) + */ + private static class PressCommand implements MonkeyCommand { + // press keycode + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() == 2) { + int keyCode = getKeyCode(command.get(1)); + if (keyCode < 0) { + // Ok, you gave us something bad. + Log.e(TAG, "Can't find keyname: " + command.get(1)); + return EARG; + } + + queue.enqueueEvent(new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, keyCode)); + queue.enqueueEvent(new MonkeyKeyEvent(KeyEvent.ACTION_UP, keyCode)); + return OK; + + } + return EARG; + } + } + + /** + * Force the device to wake up. + * + * @return true if woken up OK. + */ + private static final boolean wake() { + IPowerManager pm = + IPowerManager.Stub.asInterface(ServiceManager.getService(Context.POWER_SERVICE)); + try { + pm.userActivityWithForce(SystemClock.uptimeMillis(), true, true); + } catch (RemoteException e) { + Log.e(TAG, "Got remote exception", e); + return false; + } + return true; + } + + // This maps from command names to command implementations. + private static final Map COMMAND_MAP = new HashMap(); + + static { + // Add in all the commands we support + COMMAND_MAP.put("flip", new FlipCommand()); + COMMAND_MAP.put("touch", new TouchCommand()); + COMMAND_MAP.put("trackball", new TrackballCommand()); + COMMAND_MAP.put("key", new KeyCommand()); + COMMAND_MAP.put("sleep", new SleepCommand()); + COMMAND_MAP.put("wake", new WakeCommand()); + COMMAND_MAP.put("tap", new TapCommand()); + COMMAND_MAP.put("press", new PressCommand()); + COMMAND_MAP.put("type", new TypeCommand()); + COMMAND_MAP.put("listvar", new MonkeySourceNetworkVars.ListVarCommand()); + COMMAND_MAP.put("getvar", new MonkeySourceNetworkVars.GetVarCommand()); + } + + // QUIT command + private static final String QUIT = "quit"; + // DONE command + private static final String DONE = "done"; + + // command response strings + private static final String OK_STR = "OK"; + private static final String ERROR_STR = "ERROR"; + + public static interface CommandQueue { + /** + * Enqueue an event to be returned later. This allows a + * command to return multiple events. Commands using the + * command queue still have to return a valid event from their + * translateCommand method. The returned command will be + * executed before anything put into the queue. + * + * @param e the event to be enqueued. + */ + public void enqueueEvent(MonkeyEvent e); + }; + + // Queue of Events to be processed. This allows commands to push + // multiple events into the queue to be processed. + private static class CommandQueueImpl implements CommandQueue{ + private final Queue queuedEvents = new LinkedList(); + + public void enqueueEvent(MonkeyEvent e) { + queuedEvents.offer(e); + } + + /** + * Get the next queued event to excecute. + * + * @returns the next event, or null if there aren't any more. + */ + public MonkeyEvent getNextQueuedEvent() { + return queuedEvents.poll(); + } + }; + + private final CommandQueueImpl commandQueue = new CommandQueueImpl(); + + private BufferedReader input; + private PrintWriter output; + private boolean started = false; + + private ServerSocket serverSocket; + private Socket clientSocket; + + public MonkeySourceNetwork(int port) throws IOException { + // Only bind this to local host. This means that you can only + // talk to the monkey locally, or though adb port forwarding. + serverSocket = new ServerSocket(port, + 0, // default backlog + InetAddress.getLocalHost()); + } + + /** + * Start a network server listening on the specified port. The + * network protocol is a line oriented protocol, where each line + * is a different command that can be run. + * + * @param port the port to listen on + */ + private void startServer() throws IOException { + clientSocket = serverSocket.accept(); + // At this point, we have a client connected. Wake the device + // up in preparation for doing some commands. + wake(); + + input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + // auto-flush + output = new PrintWriter(clientSocket.getOutputStream(), true); + } + + /** + * Stop the server from running so it can reconnect a new client. + */ + private void stopServer() throws IOException { + clientSocket.close(); + input.close(); + output.close(); + started = false; + } + + /** + * Helper function for commandLineSplit that replaces quoted + * charaters with their real values. + * + * @param input the string to do replacement on. + * @returns the results with the characters replaced. + */ + private static String replaceQuotedChars(String input) { + return input.replace("\\\"", "\""); + } + + /** + * This function splits the given line into String parts. It obey's quoted + * strings and returns them as a single part. + * + * "This is a test" -> returns only one element + * This is a test -> returns four elements + * + * @param line the line to parse + * @return the List of elements + */ + private static List commandLineSplit(String line) { + ArrayList result = new ArrayList(); + StringTokenizer tok = new StringTokenizer(line); + + boolean insideQuote = false; + StringBuffer quotedWord = new StringBuffer(); + while (tok.hasMoreTokens()) { + String cur = tok.nextToken(); + if (!insideQuote && cur.startsWith("\"")) { + // begin quote + quotedWord.append(replaceQuotedChars(cur)); + insideQuote = true; + } else if (insideQuote) { + // end quote + if (cur.endsWith("\"")) { + insideQuote = false; + quotedWord.append(" ").append(replaceQuotedChars(cur)); + String word = quotedWord.toString(); + + // trim off the quotes + result.add(word.substring(1, word.length() - 1)); + } else { + quotedWord.append(" ").append(replaceQuotedChars(cur)); + } + } else { + result.add(replaceQuotedChars(cur)); + } + } + return result; + } + + /** + * Translate the given command line into a MonkeyEvent. + * + * @param commandLine the full command line given. + */ + private void translateCommand(String commandLine) { + Log.d(TAG, "translateCommand: " + commandLine); + List parts = commandLineSplit(commandLine); + if (parts.size() > 0) { + MonkeyCommand command = COMMAND_MAP.get(parts.get(0)); + if (command != null) { + MonkeyCommandReturn ret = command.translateCommand(parts, + commandQueue); + if (ret.wasSuccessful()) { + if (ret.hasMessage()) { + returnOk(ret.getMessage()); + } else { + returnOk(); + } + } else { + if (ret.hasMessage()) { + returnError(ret.getMessage()); + } else { + returnError(); + } + } + } + } + } + + public MonkeyEvent getNextEvent() { + if (!started) { + try { + startServer(); + } catch (IOException e) { + Log.e(TAG, "Got IOException from server", e); + return null; + } + started = true; + } + + // Now, get the next command. This call may block, but that's OK + try { + while (true) { + // Check to see if we have any events queued up. If + // we do, use those until we have no more. Then get + // more input from the user. + MonkeyEvent queuedEvent = commandQueue.getNextQueuedEvent(); + if (queuedEvent != null) { + // dispatch the event + return queuedEvent; + } + + String command = input.readLine(); + if (command == null) { + Log.d(TAG, "Connection dropped."); + // Treat this exactly the same as if the user had + // ended the session cleanly with a done commant. + command = DONE; + } + + if (DONE.equals(command)) { + // stop the server so it can accept new connections + try { + stopServer(); + } catch (IOException e) { + Log.e(TAG, "Got IOException shutting down!", e); + return null; + } + // return a noop event so we keep executing the main + // loop + return new MonkeyNoopEvent(); + } + + // Do quit checking here + if (QUIT.equals(command)) { + // then we're done + Log.d(TAG, "Quit requested"); + // let the host know the command ran OK + returnOk(); + return null; + } + + // Do comment checking here. Comments aren't a + // command, so we don't echo anything back to the + // user. + if (command.startsWith("#")) { + // keep going + continue; + } + + // Translate the command line. This will handle returning error/ok to the user + translateCommand(command); + } + } catch (IOException e) { + Log.e(TAG, "Exception: ", e); + return null; + } + } + + /** + * Returns ERROR to the user. + */ + private void returnError() { + output.println(ERROR_STR); + } + + /** + * Returns ERROR to the user. + * + * @param msg the error message to include + */ + private void returnError(String msg) { + output.print(ERROR_STR); + output.print(":"); + output.println(msg); + } + + /** + * Returns OK to the user. + */ + private void returnOk() { + output.println(OK_STR); + } + + /** + * Returns OK to the user. + * + * @param returnValue the value to return from this command. + */ + private void returnOk(String returnValue) { + output.print(OK_STR); + output.print(":"); + output.println(returnValue); + } + + public void setVerbose(int verbose) { + // We're not particualy verbose + } + + public boolean validate() { + // we have no pre-conditions to validate + return true; + } +} diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkVars.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkVars.java new file mode 100644 index 000000000..e9890ad2b --- /dev/null +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceNetworkVars.java @@ -0,0 +1,197 @@ +/* + * Copyright 2009, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.android.commands.monkey; + +import android.os.Build; +import android.os.SystemClock; +import android.view.Display; +import android.view.WindowManagerImpl; +import android.util.DisplayMetrics; + +import com.android.commands.monkey.MonkeySourceNetwork.CommandQueue; +import com.android.commands.monkey.MonkeySourceNetwork.MonkeyCommand; +import com.android.commands.monkey.MonkeySourceNetwork.MonkeyCommandReturn; + +import java.lang.Integer; +import java.lang.Float; +import java.lang.Long; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeMap; + +public class MonkeySourceNetworkVars { + /** + * Interface to get the value of a var. + */ + private static interface VarGetter { + /** + * Get the value of the var. + * @returns the value of the var. + */ + public String get(); + } + + private static class StaticVarGetter implements VarGetter { + private final String value; + + public StaticVarGetter(String value) { + this.value = value; + } + + public String get() { + return value; + } + } + + // Use a TreeMap to keep the keys sorted so they get displayed nicely in listvar + private static final Map VAR_MAP = new TreeMap(); + + static { + VAR_MAP.put("build.board", new StaticVarGetter(Build.BOARD)); + VAR_MAP.put("build.brand", new StaticVarGetter(Build.BRAND)); + VAR_MAP.put("build.device", new StaticVarGetter(Build.DEVICE)); + VAR_MAP.put("build.display", new StaticVarGetter(Build.DISPLAY)); + VAR_MAP.put("build.fingerprint", new StaticVarGetter(Build.FINGERPRINT)); + VAR_MAP.put("build.host", new StaticVarGetter(Build.HOST)); + VAR_MAP.put("build.id", new StaticVarGetter(Build.ID)); + VAR_MAP.put("build.model", new StaticVarGetter(Build.MODEL)); + VAR_MAP.put("build.product", new StaticVarGetter(Build.PRODUCT)); + VAR_MAP.put("build.tags", new StaticVarGetter(Build.TAGS)); + VAR_MAP.put("build.brand", new StaticVarGetter(Long.toString(Build.TIME))); + VAR_MAP.put("build.type", new StaticVarGetter(Build.TYPE)); + VAR_MAP.put("build.user", new StaticVarGetter(Build.USER)); + VAR_MAP.put("build.cpu_abi", new StaticVarGetter(Build.CPU_ABI)); + VAR_MAP.put("build.manufacturer", new StaticVarGetter(Build.MANUFACTURER)); + VAR_MAP.put("build.version.incremental", new StaticVarGetter(Build.VERSION.INCREMENTAL)); + VAR_MAP.put("build.version.release", new StaticVarGetter(Build.VERSION.RELEASE)); + VAR_MAP.put("build.version.sdk", new StaticVarGetter(Integer.toString(Build.VERSION.SDK_INT))); + VAR_MAP.put("build.version.codename", new StaticVarGetter(Build.VERSION.CODENAME)); + + // Display + Display display = WindowManagerImpl.getDefault().getDefaultDisplay(); + VAR_MAP.put("display.width", new StaticVarGetter(Integer.toString(display.getWidth()))); + VAR_MAP.put("display.height", new StaticVarGetter(Integer.toString(display.getHeight()))); + + DisplayMetrics dm = new DisplayMetrics(); + display.getMetrics(dm); + VAR_MAP.put("display.density", new StaticVarGetter(Float.toString(dm.density))); + + // am. note that the current activity information isn't valid + // until the first activity gets launched after the monkey has + // been started. + VAR_MAP.put("am.current.package", new VarGetter() { + public String get() { + return Monkey.currentPackage; + } + }); + VAR_MAP.put("am.current.action", new VarGetter() { + public String get() { + if (Monkey.currentIntent == null) { + return null; + } + return Monkey.currentIntent.getAction(); + } + }); + VAR_MAP.put("am.current.comp.class", new VarGetter() { + public String get() { + if (Monkey.currentIntent == null) { + return null; + } + return Monkey.currentIntent.getComponent().getClassName(); + } + }); + VAR_MAP.put("am.current.comp.package", new VarGetter() { + public String get() { + if (Monkey.currentIntent == null) { + return null; + } + return Monkey.currentIntent.getComponent().getPackageName(); + } + }); + VAR_MAP.put("am.current.data", new VarGetter() { + public String get() { + if (Monkey.currentIntent == null) { + return null; + } + return Monkey.currentIntent.getDataString(); + } + }); + VAR_MAP.put("am.current.categories", new VarGetter() { + public String get() { + if (Monkey.currentIntent == null) { + return null; + } + StringBuffer sb = new StringBuffer(); + for (String cat : Monkey.currentIntent.getCategories()) { + sb.append(cat).append(" "); + } + return sb.toString(); + } + }); + + // clock + VAR_MAP.put("clock.realtime", new VarGetter() { + public String get() { + return Long.toString(SystemClock.elapsedRealtime()); + } + }); + VAR_MAP.put("clock.uptime", new VarGetter() { + public String get() { + return Long.toString(SystemClock.uptimeMillis()); + } + }); + VAR_MAP.put("clock.millis", new VarGetter() { + public String get() { + return Long.toString(System.currentTimeMillis()); + } + }); + } + + /** + * Command to list the "vars" that the monkey knows about. + */ + public static class ListVarCommand implements MonkeySourceNetwork.MonkeyCommand { + // listvar + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + Set keys = VAR_MAP.keySet(); + StringBuffer sb = new StringBuffer(); + for (String key : keys) { + sb.append(key).append(" "); + } + return new MonkeyCommandReturn(true, sb.toString()); + } + } + + /** + * Command to get the value of a var. + */ + public static class GetVarCommand implements MonkeyCommand { + // getvar varname + public MonkeyCommandReturn translateCommand(List command, + CommandQueue queue) { + if (command.size() == 2) { + VarGetter getter = VAR_MAP.get(command.get(1)); + if (getter == null) { + return new MonkeyCommandReturn(false, "unknown var"); + } + return new MonkeyCommandReturn(true, getter.get()); + } + return MonkeySourceNetwork.EARG; + } + } +} diff --git a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java index 5f9c10f03..27c8a5171 100644 --- a/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java +++ b/cmds/monkey/src/com/android/commands/monkey/MonkeySourceRandom.java @@ -31,7 +31,7 @@ import java.util.Random; /** * monkey event queue */ -public class MonkeySourceRandom implements MonkeyEventSource { +public class MonkeySourceRandom implements MonkeyEventSource { /** Key events that move around the UI. */ private static final int[] NAV_KEYS = { KeyEvent.KEYCODE_DPAD_UP, KeyEvent.KEYCODE_DPAD_DOWN, @@ -55,7 +55,7 @@ public class MonkeySourceRandom implements MonkeyEventSource { /** Nice names for all key events. */ private static final String[] KEY_NAMES = { "KEYCODE_UNKNOWN", - "KEYCODE_MENU", + "KEYCODE_SOFT_LEFT", "KEYCODE_SOFT_RIGHT", "KEYCODE_HOME", "KEYCODE_BACK", @@ -146,7 +146,7 @@ public class MonkeySourceRandom implements MonkeyEventSource { "KEYCODE_REWIND", "KEYCODE_FORWARD", "KEYCODE_MUTE", - + "TAG_LAST_KEYCODE" // EOL. used to keep the lists in sync }; @@ -158,34 +158,50 @@ public class MonkeySourceRandom implements MonkeyEventSource { public static final int FACTOR_SYSOPS = 5; public static final int FACTOR_APPSWITCH = 6; public static final int FACTOR_FLIP = 7; - public static final int FACTOR_ANYTHING = 8; + public static final int FACTOR_ANYTHING = 8; public static final int FACTORZ_COUNT = 9; // should be last+1 - - + + /** percentages for each type of event. These will be remapped to working * values after we read any optional values. - **/ + **/ private float[] mFactors = new float[FACTORZ_COUNT]; private ArrayList mMainApps; private int mEventCount = 0; //total number of events generated so far private MonkeyEventQueue mQ; - private Random mRandom; + private Random mRandom; private int mVerbose = 0; private long mThrottle = 0; private boolean mKeyboardOpen = false; - /** + /** * @return the last name in the key list */ public static String getLastKeyName() { return KEY_NAMES[KeyEvent.getMaxKeyCode() + 1]; } - + public static String getKeyName(int keycode) { return KEY_NAMES[keycode]; } - + + /** + * Looks up the keyCode from a given KEYCODE_NAME. NOTE: This may + * be an expensive operation. + * + * @param keyName the name of the KEYCODE_VALUE to lookup. + * @returns the intenger keyCode value, or -1 if not found + */ + public static int getKeyCode(String keyName) { + for (int x = 0; x < KEY_NAMES.length; x++) { + if (KEY_NAMES[x].equals(keyName)) { + return x; + } + } + return -1; + } + public MonkeySourceRandom(long seed, ArrayList MainApps, long throttle) { // default values for random distributions // note, these are straight percentages, to match user input (cmd line args) @@ -199,7 +215,7 @@ public class MonkeySourceRandom implements MonkeyEventSource { mFactors[FACTOR_APPSWITCH] = 2.0f; mFactors[FACTOR_FLIP] = 1.0f; mFactors[FACTOR_ANYTHING] = 15.0f; - + mRandom = new SecureRandom(); mRandom.setSeed((seed == 0) ? -1 : seed); mMainApps = MainApps; @@ -220,25 +236,25 @@ public class MonkeySourceRandom implements MonkeyEventSource { } else { defaultSum += mFactors[i]; ++defaultCount; - } + } } - + // if the user request was > 100%, reject it if (userSum > 100.0f) { System.err.println("** Event weights > 100%"); return false; } - + // if the user specified all of the weights, then they need to be 100% if (defaultCount == 0 && (userSum < 99.9f || userSum > 100.1f)) { System.err.println("** Event weights != 100%"); return false; } - + // compute the adjustment necessary float defaultsTarget = (100.0f - userSum); float defaultsAdjustment = defaultsTarget / defaultSum; - + // fix all values, by adjusting defaults, or flipping user values back to >0 for (int i = 0; i < FACTORZ_COUNT; ++i) { if (mFactors[i] <= 0.0f) { // user values are zero or negative @@ -247,46 +263,46 @@ public class MonkeySourceRandom implements MonkeyEventSource { mFactors[i] *= defaultsAdjustment; } } - + // if verbose, show factors - + if (mVerbose > 0) { System.out.println("// Event percentages:"); for (int i = 0; i < FACTORZ_COUNT; ++i) { System.out.println("// " + i + ": " + mFactors[i] + "%"); } - } - + } + // finally, normalize and convert to running sum float sum = 0.0f; for (int i = 0; i < FACTORZ_COUNT; ++i) { sum += mFactors[i] / 100.0f; mFactors[i] = sum; - } + } return true; } - + /** * set the factors - * + * * @param factors: percentages for each type of event */ public void setFactors(float factors[]) { int c = FACTORZ_COUNT; if (factors.length < c) { c = factors.length; - } + } for (int i = 0; i < c; i++) mFactors[i] = factors[i]; } - + public void setFactors(int index, float v) { mFactors[index] = v; } - + /** * Generates a random motion event. This method counts a down, move, and up as multiple events. - * + * * TODO: Test & fix the selectors when non-zero percentages * TODO: Longpress. * TODO: Fling. @@ -294,13 +310,13 @@ public class MonkeySourceRandom implements MonkeyEventSource { * TODO: More useful than the random walk here would be to pick a single random direction * and distance, and divvy it up into a random number of segments. (This would serve to * generate fling gestures, which are important). - * + * * @param random Random number source for positioning - * @param motionEvent If false, touch/release. If true, touch/move/release. - * + * @param motionEvent If false, touch/release. If true, touch/move/release. + * */ private void generateMotionEvent(Random random, boolean motionEvent){ - + Display display = WindowManagerImpl.getDefault().getDefaultDisplay(); float x = Math.abs(random.nextInt() % display.getWidth()); @@ -310,12 +326,12 @@ public class MonkeySourceRandom implements MonkeyEventSource { if (downAt == -1) { downAt = eventTime; } - - MonkeyMotionEvent e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, - downAt, MotionEvent.ACTION_DOWN, x, y, 0); - e.setIntermediateNote(false); + + MonkeyMotionEvent e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, + downAt, MotionEvent.ACTION_DOWN, x, y, 0); + e.setIntermediateNote(false); mQ.addLast(e); - + // sometimes we'll move during the touch if (motionEvent) { int count = random.nextInt(10); @@ -323,34 +339,34 @@ public class MonkeySourceRandom implements MonkeyEventSource { // generate some slop in the up event x = (x + (random.nextInt() % 10)) % display.getWidth(); y = (y + (random.nextInt() % 10)) % display.getHeight(); - - e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, - downAt, MotionEvent.ACTION_MOVE, x, y, 0); - e.setIntermediateNote(true); + + e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, + downAt, MotionEvent.ACTION_MOVE, x, y, 0); + e.setIntermediateNote(true); mQ.addLast(e); } } // TODO generate some slop in the up event - e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, - downAt, MotionEvent.ACTION_UP, x, y, 0); - e.setIntermediateNote(false); + e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_POINTER, + downAt, MotionEvent.ACTION_UP, x, y, 0); + e.setIntermediateNote(false); mQ.addLast(e); } - + /** * Generates a random trackball event. This consists of a sequence of small moves, followed by * an optional single click. - * + * * TODO: Longpress. * TODO: Meta state * TODO: Parameterize the % clicked * TODO: More useful than the random walk here would be to pick a single random direction * and distance, and divvy it up into a random number of segments. (This would serve to * generate fling gestures, which are important). - * + * * @param random Random number source for positioning - * + * */ private void generateTrackballEvent(Random random) { Display display = WindowManagerImpl.getDefault().getDefaultDisplay(); @@ -362,47 +378,47 @@ public class MonkeySourceRandom implements MonkeyEventSource { // generate a small random step int dX = random.nextInt(10) - 5; int dY = random.nextInt(10) - 5; - - - e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, -1, - MotionEvent.ACTION_MOVE, dX, dY, 0); - e.setIntermediateNote(i > 0); + + + e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, -1, + MotionEvent.ACTION_MOVE, dX, dY, 0); + e.setIntermediateNote(i > 0); mQ.addLast(e); } - + // 10% of trackball moves end with a click if (0 == random.nextInt(10)) { long downAt = SystemClock.uptimeMillis(); - - - e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt, - MotionEvent.ACTION_DOWN, 0, 0, 0); - e.setIntermediateNote(true); + + + e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt, + MotionEvent.ACTION_DOWN, 0, 0, 0); + e.setIntermediateNote(true); mQ.addLast(e); - - - e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt, - MotionEvent.ACTION_UP, 0, 0, 0); - e.setIntermediateNote(false); + + + e = new MonkeyMotionEvent(MonkeyEvent.EVENT_TYPE_TRACKBALL, downAt, + MotionEvent.ACTION_UP, 0, 0, 0); + e.setIntermediateNote(false); mQ.addLast(e); - } + } } - - /** + + /** * generate a random event based on mFactor */ - private void generateEvents() { + private void generateEvents() { float cls = mRandom.nextFloat(); int lastKey = 0; boolean touchEvent = cls < mFactors[FACTOR_TOUCH]; boolean motionEvent = !touchEvent && (cls < mFactors[FACTOR_MOTION]); - if (touchEvent || motionEvent) { + if (touchEvent || motionEvent) { generateMotionEvent(mRandom, motionEvent); return; } - - if (cls < mFactors[FACTOR_TRACKBALL]) { + + if (cls < mFactors[FACTOR_TRACKBALL]) { generateTrackballEvent(mRandom); return; } @@ -427,23 +443,23 @@ public class MonkeySourceRandom implements MonkeyEventSource { } else { lastKey = 1 + mRandom.nextInt(KeyEvent.getMaxKeyCode() - 1); } - + MonkeyKeyEvent e = new MonkeyKeyEvent(KeyEvent.ACTION_DOWN, lastKey); mQ.addLast(e); - + e = new MonkeyKeyEvent(KeyEvent.ACTION_UP, lastKey); mQ.addLast(e); } - + public boolean validate() { //check factors return adjustEventFactors(); } - + public void setVerbose(int verbose) { mVerbose = verbose; } - + /** * generate an activity event */ @@ -452,18 +468,18 @@ public class MonkeySourceRandom implements MonkeyEventSource { mRandom.nextInt(mMainApps.size()))); mQ.addLast(e); } - + /** * if the queue is empty, we generate events first - * @return the first event in the queue + * @return the first event in the queue */ public MonkeyEvent getNextEvent() { if (mQ.isEmpty()) { generateEvents(); - } - mEventCount++; - MonkeyEvent e = mQ.getFirst(); - mQ.removeFirst(); + } + mEventCount++; + MonkeyEvent e = mQ.getFirst(); + mQ.removeFirst(); return e; } } diff --git a/docs/SDK_RELEASE_NOTES b/docs/SDK_RELEASE_NOTES index e117528e3..381c5da66 100644 --- a/docs/SDK_RELEASE_NOTES +++ b/docs/SDK_RELEASE_NOTES @@ -1,8 +1,8 @@ - + -click here if you are not redirected +click here if you are not redirected - \ No newline at end of file + diff --git a/emulator/skins/HVGA/arrow_down.png b/emulator/skins/HVGA/arrow_down.png index 19b3764e8..b9fde223d 100644 Binary files a/emulator/skins/HVGA/arrow_down.png and b/emulator/skins/HVGA/arrow_down.png differ diff --git a/emulator/skins/HVGA/arrow_left.png b/emulator/skins/HVGA/arrow_left.png index 113e58427..281b1923a 100644 Binary files a/emulator/skins/HVGA/arrow_left.png and b/emulator/skins/HVGA/arrow_left.png differ diff --git a/emulator/skins/HVGA/arrow_right.png b/emulator/skins/HVGA/arrow_right.png index ffe3356c0..4cbc65d33 100644 Binary files a/emulator/skins/HVGA/arrow_right.png and b/emulator/skins/HVGA/arrow_right.png differ diff --git a/emulator/skins/HVGA/arrow_up.png b/emulator/skins/HVGA/arrow_up.png index 81c54df51..29c712151 100644 Binary files a/emulator/skins/HVGA/arrow_up.png and b/emulator/skins/HVGA/arrow_up.png differ diff --git a/emulator/skins/HVGA/back.png b/emulator/skins/HVGA/back.png deleted file mode 100644 index 41034d910..000000000 Binary files a/emulator/skins/HVGA/back.png and /dev/null differ diff --git a/emulator/skins/HVGA/background_land.png b/emulator/skins/HVGA/background_land.png new file mode 100644 index 000000000..09c857be6 Binary files /dev/null and b/emulator/skins/HVGA/background_land.png differ diff --git a/emulator/skins/HVGA/background_port.png b/emulator/skins/HVGA/background_port.png new file mode 100644 index 000000000..a452934c9 Binary files /dev/null and b/emulator/skins/HVGA/background_port.png differ diff --git a/emulator/skins/HVGA/button.png b/emulator/skins/HVGA/button.png new file mode 100644 index 000000000..8281d20fb Binary files /dev/null and b/emulator/skins/HVGA/button.png differ diff --git a/emulator/skins/HVGA/controls.png b/emulator/skins/HVGA/controls.png new file mode 100644 index 000000000..04b85e2ba Binary files /dev/null and b/emulator/skins/HVGA/controls.png differ diff --git a/emulator/skins/HVGA/device.png b/emulator/skins/HVGA/device.png deleted file mode 100644 index 465eb029d..000000000 Binary files a/emulator/skins/HVGA/device.png and /dev/null differ diff --git a/emulator/skins/HVGA/end.png b/emulator/skins/HVGA/end.png deleted file mode 100644 index 6830a603b..000000000 Binary files a/emulator/skins/HVGA/end.png and /dev/null differ diff --git a/emulator/skins/HVGA/home.png b/emulator/skins/HVGA/home.png deleted file mode 100644 index 7d021369b..000000000 Binary files a/emulator/skins/HVGA/home.png and /dev/null differ diff --git a/emulator/skins/HVGA/key.png b/emulator/skins/HVGA/key.png index 7a3f563bd..40b03bf3f 100644 Binary files a/emulator/skins/HVGA/key.png and b/emulator/skins/HVGA/key.png differ diff --git a/emulator/skins/HVGA/keyboard.png b/emulator/skins/HVGA/keyboard.png index bb076d315..ca49dcf85 100644 Binary files a/emulator/skins/HVGA/keyboard.png and b/emulator/skins/HVGA/keyboard.png differ diff --git a/emulator/skins/HVGA/layout b/emulator/skins/HVGA/layout index 4c3d76420..7117824d2 100644 --- a/emulator/skins/HVGA/layout +++ b/emulator/skins/HVGA/layout @@ -1,84 +1,104 @@ parts { - device { + portrait { background { - image device.png + image background_port.png } + } + landscape { + background { + image background_land.png + } + } + + device { display { width 320 height 480 - x 31 - y 72 + x 0 + y 0 + } + } + + controls { + background { + image controls.png } - buttons { soft-left { - image menu.png - x 147 - y 555 + image button.png + x 56 + y 142 } home { - image home.png - x 48 - y 590 + image button.png + x 0 + y 142 } back { - image back.png - x 286 - y 590 + image button.png + x 112 + y 142 } dpad-up { image arrow_up.png - x 140 - y 595 + x 77 + y 53 } dpad-down { image arrow_down.png - x 140 - y 656 + x 77 + y 106 } dpad-left { image arrow_left.png - x 111 - y 598 + x 53 + y 53 } dpad-right { image arrow_right.png - x 222 - y 598 + x 123 + y 53 } dpad-center { image select.png - x 142 - y 626 + x 77 + y 81 } phone-dial { - image send.png - x 48 - y 646 + image button.png + x 0 + y 71 } phone-hangup { - image end.png - x 286 - y 646 + image button.png + x 168 + y 71 } power { - image power.png - x -38 - y 52 + image button.png + x 168 + y 0 } volume-up { - image volume_up.png - x 362 - y 260 + image button.png + x 112 + y 0 } volume-down { - image volume_down.png - x 362 - y 310 + image button.png + x 56 + y 0 } + + search { + image button.png + x 168 + y 142 + } + } } @@ -89,242 +109,242 @@ parts { buttons { 1 { image key.png - x 0 - y 0 + x 5 + y 5 } 2 { image key.png - x 37 - y 0 + x 42 + y 5 } 3 { image key.png - x 74 - y 0 + x 79 + y 5 } 4 { image key.png - x 111 - y 0 + x 116 + y 5 } 5 { image key.png - x 148 - y 0 + x 153 + y 5 } 6 { image key.png - x 185 - y 0 + x 190 + y 5 } 7 { image key.png - x 222 - y 0 + x 227 + y 5 } 8 { image key.png - x 259 - y 0 + x 264 + y 5 } 9 { image key.png - x 296 - y 0 + x 301 + y 5 } 0 { image key.png - x 333 - y 0 + x 338 + y 5 } q { image key.png - x 0 - y 36 + x 5 + y 41 } w { image key.png - x 37 - y 36 + x 42 + y 41 } e { image key.png - x 74 - y 36 + x 79 + y 41 } r { image key.png - x 111 - y 36 + x 116 + y 41 } t { image key.png - x 148 - y 36 + x 153 + y 41 } y { image key.png - x 185 - y 36 + x 190 + y 41 } u { image key.png - x 222 - y 36 + x 227 + y 41 } i { image key.png - x 259 - y 36 + x 264 + y 41 } o { image key.png - x 296 - y 36 + x 301 + y 41 } p { image key.png - x 333 - y 36 + x 338 + y 41 } a { image key.png - x 0 - y 72 + x 5 + y 77 } s { image key.png - x 37 - y 72 + x 42 + y 77 } d { image key.png - x 74 - y 72 + x 79 + y 77 } f { image key.png - x 111 - y 72 + x 116 + y 77 } g { image key.png - x 148 - y 72 + x 153 + y 77 } h { image key.png - x 185 - y 72 + x 190 + y 77 } j { image key.png - x 222 - y 72 + x 227 + y 77 } k { image key.png - x 259 - y 72 + x 264 + y 77 } l { image key.png - x 296 - y 72 + x 301 + y 77 } DEL { image key.png - x 333 - y 72 + x 338 + y 77 } CAP { image key.png - x 0 - y 108 + x 5 + y 113 } z { image key.png - x 37 - y 108 + x 42 + y 113 } x { image key.png - x 74 - y 108 + x 79 + y 113 } c { image key.png - x 111 - y 108 + x 116 + y 113 } v { image key.png - x 148 - y 108 + x 153 + y 113 } b { image key.png - x 185 - y 108 + x 190 + y 113 } n { image key.png - x 222 - y 108 + x 227 + y 113 } m { image key.png - x 259 - y 108 + x 264 + y 113 } PERIOD { image key.png - x 296 - y 108 + x 301 + y 113 } ENTER { image key.png - x 333 - y 108 + x 338 + y 113 } ALT { image key.png - x 0 - y 144 + x 5 + y 149 } SYM { image key.png - x 37 - y 144 + x 42 + y 149 } AT { image key.png - x 74 - y 144 + x 79 + y 149 } SPACE { image spacebar.png - x 111 - y 144 + x 116 + y 149 } SLASH { image key.png - x 259 - y 144 + x 264 + y 149 } COMMA { image key.png - x 296 - y 144 + x 301 + y 149 } ALT2 { image key.png - x 333 - y 144 + x 338 + y 149 } } @@ -333,39 +353,76 @@ parts { layouts { portrait { - width 900 - height 730 + width 791 + height 534 color 0xe0e0e0 event EV_SW:0:1 - + part1 { - name device - x 40 - y -18 + name portrait + x 0 + y 0 } + part2 { - name keyboard - x 480 - y 200 + name landscape + x 800 + y 0 } + + part3 { + name device + x 28 + y 27 + } + part4 { + name controls + x 476 + y 77 + } + part5 { + name keyboard + x 395 + y 328 + } + } landscape { - width 900 - height 670 + width 640 + height 601 color 0xe0e0e0 event EV_SW:0:0 part1 { + name portrait + x 800 + y 0 + } + + part2 { + name landscape + x 0 + y 0 + } + + part3 { name device - x 50 - y 440 + x 80 + y 349 rotation 3 } - part2 { + + part4 { + name controls + x 410 + y 396 + } + + part5 { name keyboard - x 250 - y 470 + x 18 + y 396 } } } diff --git a/emulator/skins/HVGA/menu.png b/emulator/skins/HVGA/menu.png deleted file mode 100644 index e81d8abcf..000000000 Binary files a/emulator/skins/HVGA/menu.png and /dev/null differ diff --git a/emulator/skins/HVGA/power.png b/emulator/skins/HVGA/power.png deleted file mode 100644 index 5894288f0..000000000 Binary files a/emulator/skins/HVGA/power.png and /dev/null differ diff --git a/emulator/skins/HVGA/select.png b/emulator/skins/HVGA/select.png index 803d49315..f4a65d3b5 100644 Binary files a/emulator/skins/HVGA/select.png and b/emulator/skins/HVGA/select.png differ diff --git a/emulator/skins/HVGA/send.png b/emulator/skins/HVGA/send.png deleted file mode 100644 index f547c8817..000000000 Binary files a/emulator/skins/HVGA/send.png and /dev/null differ diff --git a/emulator/skins/HVGA/spacebar.png b/emulator/skins/HVGA/spacebar.png index 19fe60476..aa459bd13 100644 Binary files a/emulator/skins/HVGA/spacebar.png and b/emulator/skins/HVGA/spacebar.png differ diff --git a/emulator/skins/HVGA/volume_down.png b/emulator/skins/HVGA/volume_down.png deleted file mode 100644 index f8a88dec8..000000000 Binary files a/emulator/skins/HVGA/volume_down.png and /dev/null differ diff --git a/emulator/skins/HVGA/volume_up.png b/emulator/skins/HVGA/volume_up.png deleted file mode 100644 index 940457f70..000000000 Binary files a/emulator/skins/HVGA/volume_up.png and /dev/null differ diff --git a/emulator/skins/QVGA/.DS_Store b/emulator/skins/QVGA/.DS_Store deleted file mode 100644 index 6aff2f6f9..000000000 Binary files a/emulator/skins/QVGA/.DS_Store and /dev/null differ diff --git a/emulator/skins/QVGA/arrow_down.png b/emulator/skins/QVGA/arrow_down.png index 7398bae87..b9fde223d 100644 Binary files a/emulator/skins/QVGA/arrow_down.png and b/emulator/skins/QVGA/arrow_down.png differ diff --git a/emulator/skins/QVGA/arrow_left.png b/emulator/skins/QVGA/arrow_left.png index f7e3c12fb..281b1923a 100644 Binary files a/emulator/skins/QVGA/arrow_left.png and b/emulator/skins/QVGA/arrow_left.png differ diff --git a/emulator/skins/QVGA/arrow_right.png b/emulator/skins/QVGA/arrow_right.png index 33fa16946..4cbc65d33 100644 Binary files a/emulator/skins/QVGA/arrow_right.png and b/emulator/skins/QVGA/arrow_right.png differ diff --git a/emulator/skins/QVGA/arrow_up.png b/emulator/skins/QVGA/arrow_up.png index f21105a64..29c712151 100644 Binary files a/emulator/skins/QVGA/arrow_up.png and b/emulator/skins/QVGA/arrow_up.png differ diff --git a/emulator/skins/QVGA/back.png b/emulator/skins/QVGA/back.png deleted file mode 100644 index 8519ebd75..000000000 Binary files a/emulator/skins/QVGA/back.png and /dev/null differ diff --git a/emulator/skins/QVGA/background_land.png b/emulator/skins/QVGA/background_land.png new file mode 100644 index 000000000..cb002b51c Binary files /dev/null and b/emulator/skins/QVGA/background_land.png differ diff --git a/emulator/skins/QVGA/background_port.png b/emulator/skins/QVGA/background_port.png new file mode 100644 index 000000000..6728562f7 Binary files /dev/null and b/emulator/skins/QVGA/background_port.png differ diff --git a/emulator/skins/QVGA/button.png b/emulator/skins/QVGA/button.png new file mode 100644 index 000000000..8281d20fb Binary files /dev/null and b/emulator/skins/QVGA/button.png differ diff --git a/emulator/skins/QVGA/controls.png b/emulator/skins/QVGA/controls.png new file mode 100644 index 000000000..04b85e2ba Binary files /dev/null and b/emulator/skins/QVGA/controls.png differ diff --git a/emulator/skins/QVGA/device.png b/emulator/skins/QVGA/device.png deleted file mode 100644 index eb6410491..000000000 Binary files a/emulator/skins/QVGA/device.png and /dev/null differ diff --git a/emulator/skins/QVGA/end.png b/emulator/skins/QVGA/end.png deleted file mode 100644 index 8519ebd75..000000000 Binary files a/emulator/skins/QVGA/end.png and /dev/null differ diff --git a/emulator/skins/QVGA/home.png b/emulator/skins/QVGA/home.png deleted file mode 100644 index 8519ebd75..000000000 Binary files a/emulator/skins/QVGA/home.png and /dev/null differ diff --git a/emulator/skins/QVGA/key.png b/emulator/skins/QVGA/key.png index 7a3f563bd..40b03bf3f 100644 Binary files a/emulator/skins/QVGA/key.png and b/emulator/skins/QVGA/key.png differ diff --git a/emulator/skins/QVGA/keyboard.png b/emulator/skins/QVGA/keyboard.png index bb076d315..ca49dcf85 100644 Binary files a/emulator/skins/QVGA/keyboard.png and b/emulator/skins/QVGA/keyboard.png differ diff --git a/emulator/skins/QVGA/layout b/emulator/skins/QVGA/layout index d7539c542..f98e7bd48 100644 --- a/emulator/skins/QVGA/layout +++ b/emulator/skins/QVGA/layout @@ -1,84 +1,104 @@ parts { - device { + portrait { background { - image device.png + image background_port.png } + } + landscape { + background { + image background_land.png + } + } + + device { display { width 240 height 320 - x 33 - y 69 + x 0 + y 0 + } + } + + controls { + background { + image controls.png } - buttons { soft-left { - image menu.png - x 131 - y 404 + image button.png + x 56 + y 142 } home { - image home.png - x 77 - y 404 + image button.png + x 0 + y 142 } back { - image back.png - x 185 - y 404 + image button.png + x 112 + y 142 } dpad-up { image arrow_up.png - x 105 - y 463 + x 77 + y 53 } dpad-down { image arrow_down.png - x 104 - y 519 + x 77 + y 106 } dpad-left { image arrow_left.png - x 96 - y 470 + x 53 + y 53 } dpad-right { image arrow_right.png - x 172 - y 470 + x 123 + y 53 } dpad-center { image select.png - x 131 - y 492 + x 77 + y 81 } phone-dial { - image send.png - x 23 - y 404 + image button.png + x 0 + y 71 } phone-hangup { - image end.png - x 238 - y 404 + image button.png + x 168 + y 71 } power { - image power.png - x -16 + image button.png + x 168 y 0 } volume-up { - image volume_up.png - x 289 - y 177 + image button.png + x 112 + y 0 } volume-down { - image volume_down.png - x 289 - y 233 + image button.png + x 56 + y 0 } + + search { + image button.png + x 168 + y 142 + } + } } @@ -89,242 +109,242 @@ parts { buttons { 1 { image key.png - x 0 - y 0 + x 5 + y 5 } 2 { image key.png - x 37 - y 0 + x 42 + y 5 } 3 { image key.png - x 74 - y 0 + x 79 + y 5 } 4 { image key.png - x 111 - y 0 + x 116 + y 5 } 5 { image key.png - x 148 - y 0 + x 153 + y 5 } 6 { image key.png - x 185 - y 0 + x 190 + y 5 } 7 { image key.png - x 222 - y 0 + x 227 + y 5 } 8 { image key.png - x 259 - y 0 + x 264 + y 5 } 9 { image key.png - x 296 - y 0 + x 301 + y 5 } 0 { image key.png - x 333 - y 0 + x 338 + y 5 } q { image key.png - x 0 - y 36 + x 5 + y 41 } w { image key.png - x 37 - y 36 + x 42 + y 41 } e { image key.png - x 74 - y 36 + x 79 + y 41 } r { image key.png - x 111 - y 36 + x 116 + y 41 } t { image key.png - x 148 - y 36 + x 153 + y 41 } y { image key.png - x 185 - y 36 + x 190 + y 41 } u { image key.png - x 222 - y 36 + x 227 + y 41 } i { image key.png - x 259 - y 36 + x 264 + y 41 } o { image key.png - x 296 - y 36 + x 301 + y 41 } p { image key.png - x 333 - y 36 + x 338 + y 41 } a { image key.png - x 0 - y 72 + x 5 + y 77 } s { image key.png - x 37 - y 72 + x 42 + y 77 } d { image key.png - x 74 - y 72 + x 79 + y 77 } f { image key.png - x 111 - y 72 + x 116 + y 77 } g { image key.png - x 148 - y 72 + x 153 + y 77 } h { image key.png - x 185 - y 72 + x 190 + y 77 } j { image key.png - x 222 - y 72 + x 227 + y 77 } k { image key.png - x 259 - y 72 + x 264 + y 77 } l { image key.png - x 296 - y 72 + x 301 + y 77 } DEL { image key.png - x 333 - y 72 + x 338 + y 77 } CAP { image key.png - x 0 - y 108 + x 5 + y 113 } z { image key.png - x 37 - y 108 + x 42 + y 113 } x { image key.png - x 74 - y 108 + x 79 + y 113 } c { image key.png - x 111 - y 108 + x 116 + y 113 } v { image key.png - x 148 - y 108 + x 153 + y 113 } b { image key.png - x 185 - y 108 + x 190 + y 113 } n { image key.png - x 222 - y 108 + x 227 + y 113 } m { image key.png - x 259 - y 108 + x 264 + y 113 } PERIOD { image key.png - x 296 - y 108 + x 301 + y 113 } ENTER { image key.png - x 333 - y 108 + x 338 + y 113 } ALT { image key.png - x 0 - y 144 + x 5 + y 149 } SYM { image key.png - x 37 - y 144 + x 42 + y 149 } AT { image key.png - x 74 - y 144 + x 79 + y 149 } SPACE { image spacebar.png - x 111 - y 144 + x 116 + y 149 } SLASH { image key.png - x 259 - y 144 + x 264 + y 149 } COMMA { image key.png - x 296 - y 144 + x 301 + y 149 } ALT2 { image key.png - x 333 - y 144 + x 338 + y 149 } } @@ -333,39 +353,75 @@ parts { layouts { portrait { - width 750 - height 610 + width 711 + height 435 color 0xe0e0e0 event EV_SW:0:1 - + part1 { - name device - x 30 - y 097 + name portrait + x 0 + y 0 } + part2 { - name keyboard - x 360 - y 300 + name landscape + x 800 + y 0 + } + + part3 { + name device + x 28 + y 58 + } + part4 { + name controls + x 396 + y 27 + } + part5 { + name keyboard + x 315 + y 229 } } landscape { - width 645 - height 575 + width 640 + height 522 color 0xe0e0e0 event EV_SW:0:0 part1 { + name portrait + x 800 + y 0 + } + + part2 { + name landscape + x 0 + y 0 + } + + part3 { name device - x 10 - y 360 + x 160 + y 270 rotation 3 } - part2 { + + part4 { + name controls + x 410 + y 317 + } + + part5 { name keyboard - x 135 - y 380 + x 18 + y 317 } } } diff --git a/emulator/skins/QVGA/menu.png b/emulator/skins/QVGA/menu.png deleted file mode 100644 index 8519ebd75..000000000 Binary files a/emulator/skins/QVGA/menu.png and /dev/null differ diff --git a/emulator/skins/QVGA/power.png b/emulator/skins/QVGA/power.png deleted file mode 100644 index 0c04cede2..000000000 Binary files a/emulator/skins/QVGA/power.png and /dev/null differ diff --git a/emulator/skins/QVGA/select.png b/emulator/skins/QVGA/select.png index 8691f532b..f4a65d3b5 100644 Binary files a/emulator/skins/QVGA/select.png and b/emulator/skins/QVGA/select.png differ diff --git a/emulator/skins/QVGA/send.png b/emulator/skins/QVGA/send.png deleted file mode 100644 index 8519ebd75..000000000 Binary files a/emulator/skins/QVGA/send.png and /dev/null differ diff --git a/emulator/skins/QVGA/spacebar.png b/emulator/skins/QVGA/spacebar.png index 19fe60476..aa459bd13 100644 Binary files a/emulator/skins/QVGA/spacebar.png and b/emulator/skins/QVGA/spacebar.png differ diff --git a/emulator/skins/QVGA/volume_down.png b/emulator/skins/QVGA/volume_down.png deleted file mode 100644 index 09175b168..000000000 Binary files a/emulator/skins/QVGA/volume_down.png and /dev/null differ diff --git a/emulator/skins/QVGA/volume_up.png b/emulator/skins/QVGA/volume_up.png deleted file mode 100644 index ab52c639b..000000000 Binary files a/emulator/skins/QVGA/volume_up.png and /dev/null differ diff --git a/emulator/skins/WQVGA432/arrow_down.png b/emulator/skins/WQVGA432/arrow_down.png new file mode 100644 index 000000000..b9fde223d Binary files /dev/null and b/emulator/skins/WQVGA432/arrow_down.png differ diff --git a/emulator/skins/WQVGA432/arrow_left.png b/emulator/skins/WQVGA432/arrow_left.png new file mode 100644 index 000000000..281b1923a Binary files /dev/null and b/emulator/skins/WQVGA432/arrow_left.png differ diff --git a/emulator/skins/WQVGA432/arrow_right.png b/emulator/skins/WQVGA432/arrow_right.png new file mode 100644 index 000000000..4cbc65d33 Binary files /dev/null and b/emulator/skins/WQVGA432/arrow_right.png differ diff --git a/emulator/skins/WQVGA432/arrow_up.png b/emulator/skins/WQVGA432/arrow_up.png new file mode 100644 index 000000000..29c712151 Binary files /dev/null and b/emulator/skins/WQVGA432/arrow_up.png differ diff --git a/emulator/skins/WQVGA432/background_land.png b/emulator/skins/WQVGA432/background_land.png new file mode 100644 index 000000000..1450e2567 Binary files /dev/null and b/emulator/skins/WQVGA432/background_land.png differ diff --git a/emulator/skins/WQVGA432/background_port.png b/emulator/skins/WQVGA432/background_port.png new file mode 100644 index 000000000..891ab454c Binary files /dev/null and b/emulator/skins/WQVGA432/background_port.png differ diff --git a/emulator/skins/WQVGA432/button.png b/emulator/skins/WQVGA432/button.png new file mode 100644 index 000000000..8281d20fb Binary files /dev/null and b/emulator/skins/WQVGA432/button.png differ diff --git a/emulator/skins/WQVGA432/controls.png b/emulator/skins/WQVGA432/controls.png new file mode 100644 index 000000000..04b85e2ba Binary files /dev/null and b/emulator/skins/WQVGA432/controls.png differ diff --git a/emulator/skins/WQVGA432/hardware.ini b/emulator/skins/WQVGA432/hardware.ini new file mode 100644 index 000000000..2efe617a1 --- /dev/null +++ b/emulator/skins/WQVGA432/hardware.ini @@ -0,0 +1,2 @@ +# skin-specific hardware values +hw.lcd.density=120 \ No newline at end of file diff --git a/emulator/skins/WQVGA432/key.png b/emulator/skins/WQVGA432/key.png new file mode 100644 index 000000000..40b03bf3f Binary files /dev/null and b/emulator/skins/WQVGA432/key.png differ diff --git a/emulator/skins/WQVGA432/keyboard.png b/emulator/skins/WQVGA432/keyboard.png new file mode 100644 index 000000000..ca49dcf85 Binary files /dev/null and b/emulator/skins/WQVGA432/keyboard.png differ diff --git a/emulator/skins/WQVGA432/layout b/emulator/skins/WQVGA432/layout new file mode 100644 index 000000000..7e52b5320 --- /dev/null +++ b/emulator/skins/WQVGA432/layout @@ -0,0 +1,436 @@ +parts { + portrait { + background { + image background_port.png + } + } + landscape { + background { + image background_land.png + } + } + + device { + display { + width 240 + height 432 + x 0 + y 0 + } + } + + controls { + background { + image controls.png + } + buttons { + soft-left { + image button.png + x 56 + y 142 + } + home { + image button.png + x 0 + y 142 + } + back { + image button.png + x 112 + y 142 + } + dpad-up { + image arrow_up.png + x 77 + y 53 + } + dpad-down { + image arrow_down.png + x 77 + y 106 + } + dpad-left { + image arrow_left.png + x 53 + y 53 + } + dpad-right { + image arrow_right.png + x 123 + y 53 + } + dpad-center { + image select.png + x 77 + y 81 + } + phone-dial { + image button.png + x 0 + y 71 + } + phone-hangup { + image button.png + x 168 + y 71 + } + + power { + image button.png + x 168 + y 0 + } + + volume-up { + image button.png + x 112 + y 0 + } + + volume-down { + image button.png + x 56 + y 0 + } + + search { + image button.png + x 168 + y 142 + } + + } + } + + keyboard { + background { + image keyboard.png + } + buttons { + 1 { + image key.png + x 5 + y 5 + } + 2 { + image key.png + x 42 + y 5 + } + 3 { + image key.png + x 79 + y 5 + } + 4 { + image key.png + x 116 + y 5 + } + 5 { + image key.png + x 153 + y 5 + } + 6 { + image key.png + x 190 + y 5 + } + 7 { + image key.png + x 227 + y 5 + } + 8 { + image key.png + x 264 + y 5 + } + 9 { + image key.png + x 301 + y 5 + } + 0 { + image key.png + x 338 + y 5 + } + + q { + image key.png + x 5 + y 41 + } + w { + image key.png + x 42 + y 41 + } + e { + image key.png + x 79 + y 41 + } + r { + image key.png + x 116 + y 41 + } + t { + image key.png + x 153 + y 41 + } + y { + image key.png + x 190 + y 41 + } + u { + image key.png + x 227 + y 41 + } + i { + image key.png + x 264 + y 41 + } + o { + image key.png + x 301 + y 41 + } + p { + image key.png + x 338 + y 41 + } + + a { + image key.png + x 5 + y 77 + } + s { + image key.png + x 42 + y 77 + } + d { + image key.png + x 79 + y 77 + } + f { + image key.png + x 116 + y 77 + } + g { + image key.png + x 153 + y 77 + } + h { + image key.png + x 190 + y 77 + } + j { + image key.png + x 227 + y 77 + } + k { + image key.png + x 264 + y 77 + } + l { + image key.png + x 301 + y 77 + } + DEL { + image key.png + x 338 + y 77 + } + + CAP { + image key.png + x 5 + y 113 + } + z { + image key.png + x 42 + y 113 + } + x { + image key.png + x 79 + y 113 + } + c { + image key.png + x 116 + y 113 + } + v { + image key.png + x 153 + y 113 + } + b { + image key.png + x 190 + y 113 + } + n { + image key.png + x 227 + y 113 + } + m { + image key.png + x 264 + y 113 + } + PERIOD { + image key.png + x 301 + y 113 + } + ENTER { + image key.png + x 338 + y 113 + } + + ALT { + image key.png + x 5 + y 149 + } + SYM { + image key.png + x 42 + y 149 + } + AT { + image key.png + x 79 + y 149 + } + SPACE { + image spacebar.png + x 116 + y 149 + } + SLASH { + image key.png + x 264 + y 149 + } + COMMA { + image key.png + x 301 + y 149 + } + ALT2 { + image key.png + x 338 + y 149 + } + + } + } +} + +layouts { + portrait { + width 711 + height 486 + color 0xe0e0e0 + event EV_SW:0:1 + + part1 { + name portrait + x 0 + y 0 + } + + part2 { + name landscape + x 800 + y 0 + } + + part3 { + name device + x 28 + y 27 + } + part4 { + name controls + x 396 + y 53 + } + part5 { + name keyboard + x 315 + y 280 + } + } + + landscape { + width 640 + height 522 + color 0xe0e0e0 + event EV_SW:0:0 + + part1 { + name portrait + x 800 + y 0 + } + + part2 { + name landscape + x 0 + y 0 + } + + part3 { + name device + x 104 + y 270 + rotation 3 + } + + part4 { + name controls + x 410 + y 317 + } + + part5 { + name keyboard + x 18 + y 317 + } + } +} + +keyboard { + charmap qwerty2 +} + +network { + speed full + delay none +} diff --git a/emulator/skins/WQVGA432/select.png b/emulator/skins/WQVGA432/select.png new file mode 100644 index 000000000..f4a65d3b5 Binary files /dev/null and b/emulator/skins/WQVGA432/select.png differ diff --git a/emulator/skins/WQVGA432/spacebar.png b/emulator/skins/WQVGA432/spacebar.png new file mode 100644 index 000000000..aa459bd13 Binary files /dev/null and b/emulator/skins/WQVGA432/spacebar.png differ diff --git a/emulator/skins/WVGA/arrow_down.png b/emulator/skins/WVGA/arrow_down.png deleted file mode 100644 index 19b3764e8..000000000 Binary files a/emulator/skins/WVGA/arrow_down.png and /dev/null differ diff --git a/emulator/skins/WVGA/arrow_left.png b/emulator/skins/WVGA/arrow_left.png deleted file mode 100644 index 113e58427..000000000 Binary files a/emulator/skins/WVGA/arrow_left.png and /dev/null differ diff --git a/emulator/skins/WVGA/arrow_right.png b/emulator/skins/WVGA/arrow_right.png deleted file mode 100644 index ffe3356c0..000000000 Binary files a/emulator/skins/WVGA/arrow_right.png and /dev/null differ diff --git a/emulator/skins/WVGA/arrow_up.png b/emulator/skins/WVGA/arrow_up.png deleted file mode 100644 index 81c54df51..000000000 Binary files a/emulator/skins/WVGA/arrow_up.png and /dev/null differ diff --git a/emulator/skins/WVGA/back.png b/emulator/skins/WVGA/back.png deleted file mode 100644 index 41034d910..000000000 Binary files a/emulator/skins/WVGA/back.png and /dev/null differ diff --git a/emulator/skins/WVGA/device.png b/emulator/skins/WVGA/device.png deleted file mode 100644 index 36572948e..000000000 Binary files a/emulator/skins/WVGA/device.png and /dev/null differ diff --git a/emulator/skins/WVGA/device.pxi b/emulator/skins/WVGA/device.pxi deleted file mode 100644 index a6bc6a059..000000000 Binary files a/emulator/skins/WVGA/device.pxi and /dev/null differ diff --git a/emulator/skins/WVGA/end.png b/emulator/skins/WVGA/end.png deleted file mode 100644 index 6830a603b..000000000 Binary files a/emulator/skins/WVGA/end.png and /dev/null differ diff --git a/emulator/skins/WVGA/home.png b/emulator/skins/WVGA/home.png deleted file mode 100644 index 7d021369b..000000000 Binary files a/emulator/skins/WVGA/home.png and /dev/null differ diff --git a/emulator/skins/WVGA/key.png b/emulator/skins/WVGA/key.png deleted file mode 100644 index 7a3f563bd..000000000 Binary files a/emulator/skins/WVGA/key.png and /dev/null differ diff --git a/emulator/skins/WVGA/keyboard.png b/emulator/skins/WVGA/keyboard.png deleted file mode 100644 index bb076d315..000000000 Binary files a/emulator/skins/WVGA/keyboard.png and /dev/null differ diff --git a/emulator/skins/WVGA/menu.png b/emulator/skins/WVGA/menu.png deleted file mode 100644 index 41034d910..000000000 Binary files a/emulator/skins/WVGA/menu.png and /dev/null differ diff --git a/emulator/skins/WVGA/power.png b/emulator/skins/WVGA/power.png deleted file mode 100644 index 5894288f0..000000000 Binary files a/emulator/skins/WVGA/power.png and /dev/null differ diff --git a/emulator/skins/WVGA/search.png b/emulator/skins/WVGA/search.png deleted file mode 100644 index 41034d910..000000000 Binary files a/emulator/skins/WVGA/search.png and /dev/null differ diff --git a/emulator/skins/WVGA/select.png b/emulator/skins/WVGA/select.png deleted file mode 100644 index 803d49315..000000000 Binary files a/emulator/skins/WVGA/select.png and /dev/null differ diff --git a/emulator/skins/WVGA/send.png b/emulator/skins/WVGA/send.png deleted file mode 100644 index f547c8817..000000000 Binary files a/emulator/skins/WVGA/send.png and /dev/null differ diff --git a/emulator/skins/WVGA/spacebar.png b/emulator/skins/WVGA/spacebar.png deleted file mode 100644 index 19fe60476..000000000 Binary files a/emulator/skins/WVGA/spacebar.png and /dev/null differ diff --git a/emulator/skins/WVGA/volume_down.png b/emulator/skins/WVGA/volume_down.png deleted file mode 100644 index f8a88dec8..000000000 Binary files a/emulator/skins/WVGA/volume_down.png and /dev/null differ diff --git a/emulator/skins/WVGA/volume_up.png b/emulator/skins/WVGA/volume_up.png deleted file mode 100644 index 940457f70..000000000 Binary files a/emulator/skins/WVGA/volume_up.png and /dev/null differ diff --git a/emulator/skins/WVGA800/arrow_down.png b/emulator/skins/WVGA800/arrow_down.png new file mode 100644 index 000000000..b9fde223d Binary files /dev/null and b/emulator/skins/WVGA800/arrow_down.png differ diff --git a/emulator/skins/WVGA800/arrow_left.png b/emulator/skins/WVGA800/arrow_left.png new file mode 100644 index 000000000..281b1923a Binary files /dev/null and b/emulator/skins/WVGA800/arrow_left.png differ diff --git a/emulator/skins/WVGA800/arrow_right.png b/emulator/skins/WVGA800/arrow_right.png new file mode 100644 index 000000000..4cbc65d33 Binary files /dev/null and b/emulator/skins/WVGA800/arrow_right.png differ diff --git a/emulator/skins/WVGA800/arrow_up.png b/emulator/skins/WVGA800/arrow_up.png new file mode 100644 index 000000000..29c712151 Binary files /dev/null and b/emulator/skins/WVGA800/arrow_up.png differ diff --git a/emulator/skins/WVGA800/background_land.png b/emulator/skins/WVGA800/background_land.png new file mode 100644 index 000000000..4967717cd Binary files /dev/null and b/emulator/skins/WVGA800/background_land.png differ diff --git a/emulator/skins/WVGA800/background_port.png b/emulator/skins/WVGA800/background_port.png new file mode 100644 index 000000000..13ef2ea1e Binary files /dev/null and b/emulator/skins/WVGA800/background_port.png differ diff --git a/emulator/skins/WVGA800/button.png b/emulator/skins/WVGA800/button.png new file mode 100644 index 000000000..8281d20fb Binary files /dev/null and b/emulator/skins/WVGA800/button.png differ diff --git a/emulator/skins/WVGA800/controls.png b/emulator/skins/WVGA800/controls.png new file mode 100644 index 000000000..04b85e2ba Binary files /dev/null and b/emulator/skins/WVGA800/controls.png differ diff --git a/emulator/skins/WVGA/hardware.ini b/emulator/skins/WVGA800/hardware.ini similarity index 100% rename from emulator/skins/WVGA/hardware.ini rename to emulator/skins/WVGA800/hardware.ini diff --git a/emulator/skins/WVGA800/key.png b/emulator/skins/WVGA800/key.png new file mode 100644 index 000000000..40b03bf3f Binary files /dev/null and b/emulator/skins/WVGA800/key.png differ diff --git a/emulator/skins/WVGA800/keyboard.png b/emulator/skins/WVGA800/keyboard.png new file mode 100644 index 000000000..ca49dcf85 Binary files /dev/null and b/emulator/skins/WVGA800/keyboard.png differ diff --git a/emulator/skins/WVGA/layout b/emulator/skins/WVGA800/layout similarity index 50% rename from emulator/skins/WVGA/layout rename to emulator/skins/WVGA800/layout index c33c354c2..6037ab8b5 100644 --- a/emulator/skins/WVGA/layout +++ b/emulator/skins/WVGA800/layout @@ -1,89 +1,104 @@ parts { - device { + portrait { background { - image device.png + image background_port.png } + } + landscape { + background { + image background_land.png + } + } + + device { display { width 480 height 800 - x 65 - y 135 + x 0 + y 0 + } + } + + controls { + background { + image controls.png } - buttons { soft-left { - image menu.png - x 222 - y 945 + image button.png + x 56 + y 142 } home { - image home.png - x 106 - y 945 + image button.png + x 0 + y 142 } back { - image back.png - x 341 - y 945 - } - search { - image search.png - x 460 - y 945 + image button.png + x 112 + y 142 } dpad-up { image arrow_up.png - x 260 - y 1019 + x 77 + y 53 } dpad-down { image arrow_down.png - x 260 - y 1081 + x 77 + y 106 } dpad-left { image arrow_left.png - x 223 - y 1023 + x 53 + y 53 } dpad-right { image arrow_right.png - x 343 - y 1023 + x 123 + y 53 } dpad-center { image select.png - x 259 - y 1049 + x 77 + y 81 } phone-dial { - image send.png - x 107 - y 1043 + image button.png + x 0 + y 71 } phone-hangup { - image end.png - x 458 - y 1043 + image button.png + x 168 + y 71 } power { - image power.png - x -10 - y 120 + image button.png + x 168 + y 0 } volume-up { - image volume_up.png - x 570 - y 260 + image button.png + x 112 + y 0 } volume-down { - image volume_down.png - x 570 - y 310 + image button.png + x 56 + y 0 } + + search { + image button.png + x 168 + y 142 + } + } } @@ -94,242 +109,242 @@ parts { buttons { 1 { image key.png - x 0 - y 0 + x 5 + y 5 } 2 { image key.png - x 37 - y 0 + x 42 + y 5 } 3 { image key.png - x 74 - y 0 + x 79 + y 5 } 4 { image key.png - x 111 - y 0 + x 116 + y 5 } 5 { image key.png - x 148 - y 0 + x 153 + y 5 } 6 { image key.png - x 185 - y 0 + x 190 + y 5 } 7 { image key.png - x 222 - y 0 + x 227 + y 5 } 8 { image key.png - x 259 - y 0 + x 264 + y 5 } 9 { image key.png - x 296 - y 0 + x 301 + y 5 } 0 { image key.png - x 333 - y 0 + x 338 + y 5 } q { image key.png - x 0 - y 36 + x 5 + y 41 } w { image key.png - x 37 - y 36 + x 42 + y 41 } e { image key.png - x 74 - y 36 + x 79 + y 41 } r { image key.png - x 111 - y 36 + x 116 + y 41 } t { image key.png - x 148 - y 36 + x 153 + y 41 } y { image key.png - x 185 - y 36 + x 190 + y 41 } u { image key.png - x 222 - y 36 + x 227 + y 41 } i { image key.png - x 259 - y 36 + x 264 + y 41 } o { image key.png - x 296 - y 36 + x 301 + y 41 } p { image key.png - x 333 - y 36 + x 338 + y 41 } a { image key.png - x 0 - y 72 + x 5 + y 77 } s { image key.png - x 37 - y 72 + x 42 + y 77 } d { image key.png - x 74 - y 72 + x 79 + y 77 } f { image key.png - x 111 - y 72 + x 116 + y 77 } g { image key.png - x 148 - y 72 + x 153 + y 77 } h { image key.png - x 185 - y 72 + x 190 + y 77 } j { image key.png - x 222 - y 72 + x 227 + y 77 } k { image key.png - x 259 - y 72 + x 264 + y 77 } l { image key.png - x 296 - y 72 + x 301 + y 77 } DEL { image key.png - x 333 - y 72 + x 338 + y 77 } CAP { image key.png - x 0 - y 108 + x 5 + y 113 } z { image key.png - x 37 - y 108 + x 42 + y 113 } x { image key.png - x 74 - y 108 + x 79 + y 113 } c { image key.png - x 111 - y 108 + x 116 + y 113 } v { image key.png - x 148 - y 108 + x 153 + y 113 } b { image key.png - x 185 - y 108 + x 190 + y 113 } n { image key.png - x 222 - y 108 + x 227 + y 113 } m { image key.png - x 259 - y 108 + x 264 + y 113 } PERIOD { image key.png - x 296 - y 108 + x 301 + y 113 } ENTER { image key.png - x 333 - y 108 + x 338 + y 113 } ALT { image key.png - x 0 - y 144 + x 5 + y 149 } SYM { image key.png - x 37 - y 144 + x 42 + y 149 } AT { image key.png - x 74 - y 144 + x 79 + y 149 } SPACE { image spacebar.png - x 111 - y 144 + x 116 + y 149 } SLASH { image key.png - x 259 - y 144 + x 264 + y 149 } COMMA { image key.png - x 296 - y 144 + x 301 + y 149 } ALT2 { image key.png - x 333 - y 144 + x 338 + y 149 } } @@ -338,39 +353,76 @@ parts { layouts { portrait { - width 975 - height 1080 - color 0xffffff + width 950 + height 854 + color 0xe0e0e0 event EV_SW:0:1 - + part1 { - name device - x 10 - y -70 + name portrait + x 0 + y 0 } + part2 { - name keyboard - x 600 - y 400 + name landscape + x 1000 + y 0 } + + part3 { + name device + x 27 + y 27 + } + part4 { + name controls + x 635 + y 207 + } + part5 { + name keyboard + x 554 + y 459 + } + } landscape { - width 1080 - height 810 - color 0xffffff + width 853 + height 761 + color 0xe0e0e0 event EV_SW:0:0 part1 { + name portrait + x 900 + y 0 + } + + part2 { + name landscape + x 0 + y 0 + } + + part3 { name device - x -70 - y 640 + x 26 + y 509 rotation 3 } - part2 { + + part4 { + name controls + x 539 + y 556 + } + + part5 { name keyboard - x 250 - y 620 + x 98 + y 556 } } } diff --git a/emulator/skins/WVGA800/select.png b/emulator/skins/WVGA800/select.png new file mode 100644 index 000000000..f4a65d3b5 Binary files /dev/null and b/emulator/skins/WVGA800/select.png differ diff --git a/emulator/skins/WVGA800/spacebar.png b/emulator/skins/WVGA800/spacebar.png new file mode 100644 index 000000000..aa459bd13 Binary files /dev/null and b/emulator/skins/WVGA800/spacebar.png differ diff --git a/emulator/skins/WVGA854/arrow_down.png b/emulator/skins/WVGA854/arrow_down.png new file mode 100644 index 000000000..b9fde223d Binary files /dev/null and b/emulator/skins/WVGA854/arrow_down.png differ diff --git a/emulator/skins/WVGA854/arrow_left.png b/emulator/skins/WVGA854/arrow_left.png new file mode 100644 index 000000000..281b1923a Binary files /dev/null and b/emulator/skins/WVGA854/arrow_left.png differ diff --git a/emulator/skins/WVGA854/arrow_right.png b/emulator/skins/WVGA854/arrow_right.png new file mode 100644 index 000000000..4cbc65d33 Binary files /dev/null and b/emulator/skins/WVGA854/arrow_right.png differ diff --git a/emulator/skins/WVGA854/arrow_up.png b/emulator/skins/WVGA854/arrow_up.png new file mode 100644 index 000000000..29c712151 Binary files /dev/null and b/emulator/skins/WVGA854/arrow_up.png differ diff --git a/emulator/skins/WVGA854/background_land.png b/emulator/skins/WVGA854/background_land.png new file mode 100644 index 000000000..4f0f90e94 Binary files /dev/null and b/emulator/skins/WVGA854/background_land.png differ diff --git a/emulator/skins/WVGA854/background_port.png b/emulator/skins/WVGA854/background_port.png new file mode 100644 index 000000000..e35bf6738 Binary files /dev/null and b/emulator/skins/WVGA854/background_port.png differ diff --git a/emulator/skins/WVGA854/button.png b/emulator/skins/WVGA854/button.png new file mode 100644 index 000000000..8281d20fb Binary files /dev/null and b/emulator/skins/WVGA854/button.png differ diff --git a/emulator/skins/WVGA854/controls.png b/emulator/skins/WVGA854/controls.png new file mode 100644 index 000000000..04b85e2ba Binary files /dev/null and b/emulator/skins/WVGA854/controls.png differ diff --git a/emulator/skins/WVGA854/hardware.ini b/emulator/skins/WVGA854/hardware.ini new file mode 100644 index 000000000..02e9d89ee --- /dev/null +++ b/emulator/skins/WVGA854/hardware.ini @@ -0,0 +1,2 @@ +# skin-specific hardware values +hw.lcd.density=240 \ No newline at end of file diff --git a/emulator/skins/WVGA854/key.png b/emulator/skins/WVGA854/key.png new file mode 100644 index 000000000..40b03bf3f Binary files /dev/null and b/emulator/skins/WVGA854/key.png differ diff --git a/emulator/skins/WVGA854/keyboard.png b/emulator/skins/WVGA854/keyboard.png new file mode 100644 index 000000000..ca49dcf85 Binary files /dev/null and b/emulator/skins/WVGA854/keyboard.png differ diff --git a/emulator/skins/WVGA854/layout b/emulator/skins/WVGA854/layout new file mode 100644 index 000000000..ab0784d02 --- /dev/null +++ b/emulator/skins/WVGA854/layout @@ -0,0 +1,437 @@ +parts { + portrait { + background { + image background_port.png + } + } + landscape { + background { + image background_land.png + } + } + + device { + display { + width 480 + height 854 + x 0 + y 0 + } + } + + controls { + background { + image controls.png + } + buttons { + soft-left { + image button.png + x 56 + y 142 + } + home { + image button.png + x 0 + y 142 + } + back { + image button.png + x 112 + y 142 + } + dpad-up { + image arrow_up.png + x 77 + y 53 + } + dpad-down { + image arrow_down.png + x 77 + y 106 + } + dpad-left { + image arrow_left.png + x 53 + y 53 + } + dpad-right { + image arrow_right.png + x 123 + y 53 + } + dpad-center { + image select.png + x 77 + y 81 + } + phone-dial { + image button.png + x 0 + y 71 + } + phone-hangup { + image button.png + x 168 + y 71 + } + + power { + image button.png + x 168 + y 0 + } + + volume-up { + image button.png + x 112 + y 0 + } + + volume-down { + image button.png + x 56 + y 0 + } + + search { + image button.png + x 168 + y 142 + } + + } + } + + keyboard { + background { + image keyboard.png + } + buttons { + 1 { + image key.png + x 5 + y 5 + } + 2 { + image key.png + x 42 + y 5 + } + 3 { + image key.png + x 79 + y 5 + } + 4 { + image key.png + x 116 + y 5 + } + 5 { + image key.png + x 153 + y 5 + } + 6 { + image key.png + x 190 + y 5 + } + 7 { + image key.png + x 227 + y 5 + } + 8 { + image key.png + x 264 + y 5 + } + 9 { + image key.png + x 301 + y 5 + } + 0 { + image key.png + x 338 + y 5 + } + + q { + image key.png + x 5 + y 41 + } + w { + image key.png + x 42 + y 41 + } + e { + image key.png + x 79 + y 41 + } + r { + image key.png + x 116 + y 41 + } + t { + image key.png + x 153 + y 41 + } + y { + image key.png + x 190 + y 41 + } + u { + image key.png + x 227 + y 41 + } + i { + image key.png + x 264 + y 41 + } + o { + image key.png + x 301 + y 41 + } + p { + image key.png + x 338 + y 41 + } + + a { + image key.png + x 5 + y 77 + } + s { + image key.png + x 42 + y 77 + } + d { + image key.png + x 79 + y 77 + } + f { + image key.png + x 116 + y 77 + } + g { + image key.png + x 153 + y 77 + } + h { + image key.png + x 190 + y 77 + } + j { + image key.png + x 227 + y 77 + } + k { + image key.png + x 264 + y 77 + } + l { + image key.png + x 301 + y 77 + } + DEL { + image key.png + x 338 + y 77 + } + + CAP { + image key.png + x 5 + y 113 + } + z { + image key.png + x 42 + y 113 + } + x { + image key.png + x 79 + y 113 + } + c { + image key.png + x 116 + y 113 + } + v { + image key.png + x 153 + y 113 + } + b { + image key.png + x 190 + y 113 + } + n { + image key.png + x 227 + y 113 + } + m { + image key.png + x 264 + y 113 + } + PERIOD { + image key.png + x 301 + y 113 + } + ENTER { + image key.png + x 338 + y 113 + } + + ALT { + image key.png + x 5 + y 149 + } + SYM { + image key.png + x 42 + y 149 + } + AT { + image key.png + x 79 + y 149 + } + SPACE { + image spacebar.png + x 116 + y 149 + } + SLASH { + image key.png + x 264 + y 149 + } + COMMA { + image key.png + x 301 + y 149 + } + ALT2 { + image key.png + x 338 + y 149 + } + + } + } +} + +layouts { + portrait { + width 950 + height 908 + color 0xe0e0e0 + event EV_SW:0:1 + + part1 { + name portrait + x 0 + y 0 + } + + part2 { + name landscape + x 1000 + y 0 + } + + part3 { + name device + x 27 + y 27 + } + part4 { + name controls + x 635 + y 234 + } + part5 { + name keyboard + x 554 + y 486 + } + + } + + landscape { + width 907 + height 761 + color 0xe0e0e0 + event EV_SW:0:0 + + part1 { + name portrait + x 900 + y 0 + } + + part2 { + name landscape + x 0 + y 0 + } + + part3 { + name device + x 26 + y 509 + rotation 3 + } + + part4 { + name controls + x 567 + y 556 + } + + part5 { + name keyboard + x 126 + y 556 + } + } +} + +keyboard { + charmap qwerty2 +} + +network { + speed full + delay none +} diff --git a/emulator/skins/WVGA854/select.png b/emulator/skins/WVGA854/select.png new file mode 100644 index 000000000..f4a65d3b5 Binary files /dev/null and b/emulator/skins/WVGA854/select.png differ diff --git a/emulator/skins/WVGA854/spacebar.png b/emulator/skins/WVGA854/spacebar.png new file mode 100644 index 000000000..aa459bd13 Binary files /dev/null and b/emulator/skins/WVGA854/spacebar.png differ diff --git a/host/windows/.gitignore b/host/windows/.gitignore index dc7a154e8..434a0faf9 100755 --- a/host/windows/.gitignore +++ b/host/windows/.gitignore @@ -1,9 +1,12 @@ *.sln *.vcproj* +*.aps usb/api.* usb/Debug usb/Release usb/api/obj* usb/api/*.log usb/adb_winapi_test/obj* -usb/adb_winapi_test/*.log \ No newline at end of file +usb/adb_winapi_test/*.log +usb/winusb/obj* +usb/winusb/*.log \ No newline at end of file diff --git a/host/windows/prebuilt/usb/AdbWinApi.dll b/host/windows/prebuilt/usb/AdbWinApi.dll index 1fcfaa934..b5586eb50 100755 Binary files a/host/windows/prebuilt/usb/AdbWinApi.dll and b/host/windows/prebuilt/usb/AdbWinApi.dll differ diff --git a/host/windows/prebuilt/usb/AdbWinUsbApi.dll b/host/windows/prebuilt/usb/AdbWinUsbApi.dll new file mode 100755 index 000000000..0c9e00bd9 Binary files /dev/null and b/host/windows/prebuilt/usb/AdbWinUsbApi.dll differ diff --git a/host/windows/prebuilt/usb/Android.mk b/host/windows/prebuilt/usb/Android.mk index 180610109..9cf4e61f3 100644 --- a/host/windows/prebuilt/usb/Android.mk +++ b/host/windows/prebuilt/usb/Android.mk @@ -6,7 +6,8 @@ LOCAL_PREBUILT_LIBS := \ AdbWinApi.a LOCAL_PREBUILT_EXECUTABLES := \ - AdbWinApi.dll + AdbWinApi.dll \ + AdbWinUsbApi.dll .PHONY : kill-adb diff --git a/host/windows/usb/android_winusb.inf b/host/windows/usb/android_winusb.inf index c39961276..de4f93e94 100755 --- a/host/windows/usb/android_winusb.inf +++ b/host/windows/usb/android_winusb.inf @@ -1,20 +1,19 @@ ; -; WinUsb installation File. +; Android WinUsb driver installation. ; [Version] Signature = "$Windows NT$" Class = AndroidUsbDeviceClass ClassGuid = {3F966BD9-FA04-4ec5-991C-D326973B5128} Provider = %ProviderName% -DriverVer = 07/20/2009,2.0.0010.00001 +DriverVer = 08/11/2009,2.0.0010.00002 CatalogFile.NTx86 = androidwinusb86.cat CatalogFile.NTamd64 = androidwinusba64.cat ; -; This section is required even though we report our driver -; as a standard USB driver. If this section is removed the -; installer will report an error "Required section not found -; in INF file. +; This section seems to be required for WinUsb driver installation. +; If this section is removed the installer will report an error +; "Required section not found in INF file". ; [ClassInstall32] Addreg = AndroidWinUsbClassReg @@ -24,31 +23,31 @@ HKR,,,0,%ClassName% HKR,,Icon,,-1 [Manufacturer] -%ProviderName% = Google,NTx86,NTamd64 +%ProviderName% = Google, NTx86, NTamd64 [Google.NTx86] ; HTC Dream -%USB\HCT_Dream.DeviceDesc% = USB_Install, USB\VID_0BB4&PID_0C01 -%USB\HCT_Dream_Composite.DeviceDesc% = USB_Install, USB\VID_0BB4&PID_0C02&MI_01 -%USB\HCT_BootLoader.DeviceDesc% = USB_Install, USB\VID_0BB4&PID_0FFF -; HCT Magic -%USB\HCT_Magic_Composite.DeviceDesc% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01 +%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C01 +%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C02&MI_01 +%SingleBootLoaderInterface% = USB_Install, USB\VID_0BB4&PID_0FFF +; HTC Magic +%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01 [Google.NTamd64] ; HTC Dream -%USB\HCT_Dream.DeviceDesc% = USB_Install, USB\VID_0BB4&PID_0C01 -%USB\HCT_Dream_Composite.DeviceDesc% = USB_Install, USB\VID_0BB4&PID_0C02&MI_01 -%USB\HCT_BootLoader.DeviceDesc% = USB_Install, USB\VID_0BB4&PID_0FFF -; HCT Magic -%USB\HCT_Magic_Composite.DeviceDesc% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01 +%SingleAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C01 +%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C02&MI_01 +%SingleBootLoaderInterface% = USB_Install, USB\VID_0BB4&PID_0FFF +; HTC Magic +%CompositeAdbInterface% = USB_Install, USB\VID_0BB4&PID_0C03&MI_01 [USB_Install] -Include=winusb.inf -Needs=WINUSB.NT +Include = winusb.inf +Needs = WINUSB.NT [USB_Install.Services] -Include=winusb.inf -AddService=WinUSB,0x00000002,WinUSB_ServiceInstall +Include = winusb.inf +AddService = WinUSB,0x00000002,WinUSB_ServiceInstall [WinUSB_ServiceInstall] DisplayName = %WinUSB_SvcDesc% @@ -58,19 +57,20 @@ ErrorControl = 1 ServiceBinary = %12%\WinUSB.sys [USB_Install.Wdf] -KmdfService=WINUSB, WinUSB_Install +KmdfService = WINUSB, WinUSB_Install + [WinUSB_Install] -KmdfLibraryVersion=1.7 +KmdfLibraryVersion = 1.7 [USB_Install.HW] -AddReg=Dev_AddReg +AddReg = Dev_AddReg [Dev_AddReg] HKR,,DeviceInterfaceGUIDs,0x10000,"{F72FE0D4-CBCB-407d-8814-9ED673D0DD6B}" [USB_Install.CoInstallers] -AddReg=CoInstallers_AddReg -CopyFiles=CoInstallers_CopyFiles +AddReg = CoInstallers_AddReg +CopyFiles = CoInstallers_CopyFiles [CoInstallers_AddReg] HKR,,CoInstallers32,0x00010000,"WdfCoInstaller01007.dll,WdfCoInstaller","WinUSBCoInstaller.dll" @@ -87,19 +87,18 @@ CoInstallers_CopyFiles=11 2 = %DISK_NAME%,,,\amd64 [SourceDisksFiles.x86] -WinUSBCoInstaller.dll=1 -WdfCoInstaller01007.dll=1 +WinUSBCoInstaller.dll = 1 +WdfCoInstaller01007.dll = 1 [SourceDisksFiles.amd64] -WinUSBCoInstaller.dll=2 -WdfCoInstaller01007.dll=2 +WinUSBCoInstaller.dll = 2 +WdfCoInstaller01007.dll = 2 [Strings] -ProviderName="Google, Inc." -USB\HCT_Dream.DeviceDesc="Android ADB Interface" -USB\HCT_Dream_Composite.DeviceDesc="Android Composite ADB Interface" -USB\HCT_BootLoader.DeviceDesc="Android Bootloader Interface" -USB\HCT_Magic_Composite.DeviceDesc="Android Composite ADB Interface" -WinUSB_SvcDesc="Android USB Driver" -DISK_NAME="Android install disk" -ClassName="Android Phone" +ProviderName = "Google, Inc." +SingleAdbInterface = "Android ADB Interface" +CompositeAdbInterface = "Android Composite ADB Interface" +SingleBootLoaderInterface = "Android Bootloader Interface" +WinUSB_SvcDesc = "Android USB Driver" +DISK_NAME = "Android WinUsb installation disk" +ClassName = "Android Phone" diff --git a/host/windows/usb/api/AdbWinApi.cpp b/host/windows/usb/api/AdbWinApi.cpp index 4d18d3793..507a2b59d 100644 --- a/host/windows/usb/api/AdbWinApi.cpp +++ b/host/windows/usb/api/AdbWinApi.cpp @@ -17,6 +17,8 @@ // AdbWinApi.cpp : Implementation of DLL Exports. #include "stdafx.h" +#include "adb_api.h" +#include "adb_winusb_api.h" extern "C" { int _forceCRTManifest; @@ -24,8 +26,73 @@ int _forceMFCManifest; int _forceAtlDllManifest; }; +/// References InstantiateWinUsbInterface declared in adb_api.cpp +extern PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface; + class CAdbWinApiModule : public CAtlDllModuleT< CAdbWinApiModule > { -public: + public: + CAdbWinApiModule() + : CAtlDllModuleT< CAdbWinApiModule >(), + adbwinusbapi_handle_(NULL), + is_initialized_(false) { + } + + ~CAdbWinApiModule() { + // Unload AdbWinUsbApi.dll before we exit + if (NULL != adbwinusbapi_handle_) { + FreeLibrary(adbwinusbapi_handle_); + } + } + + /** \brief Loads AdbWinUsbApi.dll and caches its InstantiateWinUsbInterface + export. + + This method is called from DllMain on DLL_PROCESS_ATTACH event. In this + method we will check if WINUSB.DLL required by AdbWinUsbApi.dll is + installed, and if it is we will load AdbWinUsbApi.dll and cache address of + InstantiateWinUsbInterface routine exported from AdbWinUsbApi.dll + */ + void AttachToAdbWinUsbApi() { + // We only need to run this only once. + if (is_initialized_) { + return; + } + + // Just mark that we have ran initialization. + is_initialized_ = true; + + // Before we can load AdbWinUsbApi.dll we must make sure that WINUSB.DLL + // has been installed. Build path to the file. + wchar_t path_to_winusb_dll[MAX_PATH+1]; + if (!GetSystemDirectory(path_to_winusb_dll, MAX_PATH)) { + return; + } + wcscat(path_to_winusb_dll, L"\\WINUSB.DLL"); + + if (0xFFFFFFFF == GetFileAttributes(path_to_winusb_dll)) { + // WINUSB.DLL is not installed. We don't (in fact, can't) load + // AdbWinUsbApi.dll + return; + } + + // WINUSB.DLL is installed. Lets load AdbWinUsbApi.dll and cache its + // InstantiateWinUsbInterface export. + // We require that AdbWinUsbApi.dll is located in the same folder + // where AdbWinApi.dll and adb.exe are located, so by Windows + // conventions we can pass just module name, and not the full path. + adbwinusbapi_handle_ = LoadLibrary(L"AdbWinUsbApi.dll"); + if (NULL != adbwinusbapi_handle_) { + InstantiateWinUsbInterface = reinterpret_cast + (GetProcAddress(adbwinusbapi_handle_, "InstantiateWinUsbInterface")); + } + } + + protected: + /// Handle to the loaded AdbWinUsbApi.dll + HINSTANCE adbwinusbapi_handle_; + + /// Flags whether or not this module has been initialized. + bool is_initialized_; }; CAdbWinApiModule _AtlModule; @@ -34,5 +101,12 @@ CAdbWinApiModule _AtlModule; extern "C" BOOL WINAPI DllMain(HINSTANCE instance, DWORD reason, LPVOID reserved) { - return _AtlModule.DllMain(reason, reserved); + // Lets see if we need to initialize InstantiateWinUsbInterface + // variable. We do that only once, on condition that this DLL is + // being attached to the process and InstantiateWinUsbInterface + // address has not been calculated yet. + if (DLL_PROCESS_ATTACH == reason) { + _AtlModule.AttachToAdbWinUsbApi(); + } + return _AtlModule.DllMain(reason, reserved); } diff --git a/host/windows/usb/api/SOURCES b/host/windows/usb/api/SOURCES index f6e66143c..35695217b 100755 --- a/host/windows/usb/api/SOURCES +++ b/host/windows/usb/api/SOURCES @@ -50,8 +50,7 @@ TARGETLIBS = $(SDK_LIB_PATH)\ole32.lib \ $(SDK_LIB_PATH)\wbemuuid.lib \ $(SDK_LIB_PATH)\uuid.lib \ $(SDK_LIB_PATH)\setupapi.lib \ - $(SDK_LIB_PATH)\usbd.lib \ - $(SDK_LIB_PATH)\winusb.lib + $(SDK_LIB_PATH)\usbd.lib !IF "$(DDKBUILDENV)" == "fre" # Libraries for release (free) builds @@ -87,15 +86,12 @@ PRECOMPILED_SOURCEFILE = stdafx.cpp # Define source files for AdbWinApi.dll SOURCES = adb_api.cpp \ adb_endpoint_object.cpp \ - adb_winusb_endpoint_object.cpp \ adb_legacy_endpoint_object.cpp \ adb_helper_routines.cpp \ adb_interface.cpp \ - adb_winusb_interface.cpp \ adb_legacy_interface.cpp \ adb_interface_enum.cpp \ adb_io_completion.cpp \ - adb_winusb_io_completion.cpp \ adb_legacy_io_completion.cpp \ adb_object_handle.cpp \ AdbWinApi.cpp \ diff --git a/host/windows/usb/api/adb_api.cpp b/host/windows/usb/api/adb_api.cpp index f9bd94e6c..e58bcf17a 100644 --- a/host/windows/usb/api/adb_api.cpp +++ b/host/windows/usb/api/adb_api.cpp @@ -24,11 +24,19 @@ #include "adb_object_handle.h" #include "adb_interface_enum.h" #include "adb_interface.h" -#include "adb_winusb_interface.h" #include "adb_legacy_interface.h" #include "adb_endpoint_object.h" #include "adb_io_completion.h" #include "adb_helper_routines.h" +#include "adb_winusb_api.h" + +/** \brief Points to InstantiateWinUsbInterface exported from AdbWinUsbApi.dll. + + This variable is initialized with the actual address in DllMain routine for + this DLL on DLL_PROCESS_ATTACH event. + @see PFN_INSTWINUSBINTERFACE for more information. +*/ +PFN_INSTWINUSBINTERFACE InstantiateWinUsbInterface = NULL; ADBAPIHANDLE __cdecl AdbEnumInterfaces(GUID class_id, bool exclude_not_present, @@ -101,11 +109,22 @@ ADBAPIHANDLE __cdecl AdbCreateInterfaceByName( ADBAPIHANDLE ret = NULL; try { - // Instantiate object + // Instantiate interface object, depending on the USB driver type. if (IsLegacyInterface(interface_name)) { + // We have legacy USB driver underneath us. obj = new AdbLegacyInterfaceObject(interface_name); } else { - obj = new AdbWinUsbInterfaceObject(interface_name); + // We have WinUsb driver underneath us. Make sure that AdbWinUsbApi.dll + // is loaded and its InstantiateWinUsbInterface routine address has + // been cached. + if (NULL != InstantiateWinUsbInterface) { + obj = InstantiateWinUsbInterface(interface_name); + if (NULL == obj) { + return NULL; + } + } else { + return NULL; + } } // Create handle for it diff --git a/host/windows/usb/api/adb_api.h b/host/windows/usb/api/adb_api.h index e2ad129ca..20f0cd634 100644 --- a/host/windows/usb/api/adb_api.h +++ b/host/windows/usb/api/adb_api.h @@ -119,8 +119,10 @@ typedef struct _AdbEndpointInformation { // as being exported. #ifdef ADBWIN_EXPORTS #define ADBWIN_API EXTERN_C __declspec(dllexport) +#define ADBWIN_API_CLASS __declspec(dllexport) #else #define ADBWIN_API EXTERN_C __declspec(dllimport) +#define ADBWIN_API_CLASS __declspec(dllimport) #endif /** \brief Handle to an API object. diff --git a/host/windows/usb/api/adb_endpoint_object.h b/host/windows/usb/api/adb_endpoint_object.h index 295eb46f2..d92aaad47 100644 --- a/host/windows/usb/api/adb_endpoint_object.h +++ b/host/windows/usb/api/adb_endpoint_object.h @@ -29,7 +29,7 @@ This class implement functionality that is common for both, WinUsb and legacy APIs. */ -class AdbEndpointObject : public AdbObjectHandle { +class ADBWIN_API_CLASS AdbEndpointObject : public AdbObjectHandle { public: /** \brief Constructs the object diff --git a/host/windows/usb/api/adb_interface.h b/host/windows/usb/api/adb_interface.h index 4afb17da0..0aa0d1d55 100644 --- a/host/windows/usb/api/adb_interface.h +++ b/host/windows/usb/api/adb_interface.h @@ -23,12 +23,17 @@ #include "adb_object_handle.h" +// 'AdbInterfaceObject::interface_name_' : class 'std::basic_string<_E,_Tr,_A>' +// needs to have dll-interface to be used by clients of class +// 'AdbInterfaceObject' We're ok with that, since interface_name_ will not +// be referenced by name from outside of this class. +#pragma warning(disable: 4251) /** \brief Encapsulates an interface on our USB device. This is an abstract class that implements functionality common for both, legacy, and WinUsb based interfaces. */ -class AdbInterfaceObject : public AdbObjectHandle { +class ADBWIN_API_CLASS AdbInterfaceObject : public AdbObjectHandle { public: /** \brief Constructs the object. @@ -180,9 +185,6 @@ class AdbInterfaceObject : public AdbObjectHandle { } protected: - /// Name of the USB interface (device name) for this object - std::wstring interface_name_; - /// Cached usb device descriptor USB_DEVICE_DESCRIPTOR usb_device_descriptor_; @@ -191,6 +193,11 @@ class AdbInterfaceObject : public AdbObjectHandle { /// Cached usb interface descriptor USB_INTERFACE_DESCRIPTOR usb_interface_descriptor_; + + private: + /// Name of the USB interface (device name) for this object + std::wstring interface_name_; }; +#pragma warning(default: 4251) #endif // ANDROID_USB_API_ADB_INTERFACE_H__ diff --git a/host/windows/usb/api/adb_io_completion.h b/host/windows/usb/api/adb_io_completion.h index 8a7c1d91d..ea4b4fbce 100644 --- a/host/windows/usb/api/adb_io_completion.h +++ b/host/windows/usb/api/adb_io_completion.h @@ -33,7 +33,7 @@ like all other handles this handle must be closed after it's no longer needed. */ -class AdbIOCompletion : public AdbObjectHandle { +class ADBWIN_API_CLASS AdbIOCompletion : public AdbObjectHandle { public: /** \brief Constructs the object diff --git a/host/windows/usb/api/adb_object_handle.h b/host/windows/usb/api/adb_object_handle.h index 29ac5e2f2..2fa4ad03b 100644 --- a/host/windows/usb/api/adb_object_handle.h +++ b/host/windows/usb/api/adb_object_handle.h @@ -22,6 +22,7 @@ of the API through a handle. */ +#include "adb_api.h" #include "adb_api_private_defines.h" /** \brief Defines types of internal API objects @@ -71,7 +72,7 @@ enum AdbObjectType { All API objects that have handles that are sent back to API client must be derived from this class. */ -class AdbObjectHandle { +class ADBWIN_API_CLASS AdbObjectHandle { public: /** \brief Constructs the object diff --git a/host/windows/usb/api/adb_winusb_api.h b/host/windows/usb/api/adb_winusb_api.h new file mode 100755 index 000000000..268a99873 --- /dev/null +++ b/host/windows/usb/api/adb_winusb_api.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2006 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. + */ + +#ifndef ANDROID_USB_API_ADBWINUSBAPI_H__ +#define ANDROID_USB_API_ADBWINUSBAPI_H__ + +/** \file + Contains declarations required to link AdbWinApi and AdbWinUsbApi DLLs. +*/ + +/** \brief Function prototype for InstantiateWinUsbInterface routine exported + from AdbWinUsbApi.dll + + In order to provide backward compatibility with the systems that still run + legacy (custom) USB drivers, and have not installed WINUSB.DLL we need to + split functionality of our ADB API on Windows between two DLLs: AdbWinApi, + and AdbWinUsbApi. AdbWinApi is fully capable of working on top of the legacy + driver, but has no traces to WinUsb. AdbWinUsbApi is capable of working on + top of WinUsb API. We are forced to do this split, because we can have + dependency on WINUSB.DLL in the DLL that implements legacy API. The problem + is that customers may have a legacy driver that they don't want to upgrade + to WinUsb, so they may not have WINUSB.DLL installed on their machines, but + they still must be able to use ADB. So, the idea behind the split is as + such. When AdbWinApi.dll is loaded into a process, it will check WINUSB.DLL + installation (by checking existance of C:\Windows\System32\winusb.dll). If + WINUSB.DLL is installed, AdbWinApi will also load AdbWinUsbApi.dll (by + calling LoadLibrary), and will extract address of InstantiateWinUsbInterface + routine exported from AdbWinUsbApi.dll. Then this routine will be used to + instantiate AdbInterfaceObject instance on condition that it is confirmed + that USB driver underneath us is in deed WinUsb. +*/ +typedef class AdbInterfaceObject* \ + (__cdecl *PFN_INSTWINUSBINTERFACE)(const wchar_t*); + +#endif // ANDROID_USB_API_ADBWINUSBAPI_H__ diff --git a/host/windows/usb/api/stdafx.h b/host/windows/usb/api/stdafx.h index 92b2652ea..d57bec74b 100644 --- a/host/windows/usb/api/stdafx.h +++ b/host/windows/usb/api/stdafx.h @@ -71,11 +71,8 @@ #include #pragma warning(default: 4201) #pragma warning(disable: 4200) -extern "C" { #include -#include #include -} #include "resource.h" diff --git a/host/windows/usb/winusb/AdbWinUsbApi.cpp b/host/windows/usb/winusb/AdbWinUsbApi.cpp new file mode 100755 index 000000000..4916eebd2 --- /dev/null +++ b/host/windows/usb/winusb/AdbWinUsbApi.cpp @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// AdbWinUsbApi.cpp : Implementation of DLL Exports. + +#include "stdafx.h" +#include "adb_winusb_interface.h" + +class CAdbWinApiModule : public CAtlDllModuleT< CAdbWinApiModule > { +public: +}; + +CAdbWinApiModule _AtlModule; + +// DLL Entry Point +extern "C" BOOL WINAPI DllMain(HINSTANCE instance, + DWORD reason, + LPVOID reserved) { + return _AtlModule.DllMain(reason, reserved); +} + +/** \brief Instantiates interface instance that uses WinUsb API to communicate + with USB driver. + + This is the only exported routine from this DLL. This routine instantiates an + object of AdbWinUsbInterfaceObject on request from AdbWinApi.dll when it is + detected that underlying USB driver is WinUsb.sys. + @param[in] interface_name Name of the interface. + @return AdbInterfaceObject - casted instance of AdbWinUsbInterfaceObject + object on success, or NULL on failure with GetLastError providing + information on an error that occurred. +*/ +extern "C" __declspec(dllexport) +AdbInterfaceObject* __cdecl InstantiateWinUsbInterface( + const wchar_t* interface_name) { + // Validate parameter. + if (NULL == interface_name) { + return NULL; + } + + // Instantiate requested object. + try { + return new AdbWinUsbInterfaceObject(interface_name); + } catch (...) { + // We expect only OOM exceptions here. + SetLastError(ERROR_OUTOFMEMORY); + return NULL; + } +} diff --git a/host/windows/usb/winusb/AdbWinUsbApi.def b/host/windows/usb/winusb/AdbWinUsbApi.def new file mode 100755 index 000000000..9e616e91d --- /dev/null +++ b/host/windows/usb/winusb/AdbWinUsbApi.def @@ -0,0 +1,5 @@ +; AdbWinUsbApi.def : Declares the module parameters. + +LIBRARY "AdbWinUsbApi.DLL" + +EXPORTS diff --git a/host/windows/usb/winusb/AdbWinUsbApi.rc b/host/windows/usb/winusb/AdbWinUsbApi.rc new file mode 100755 index 000000000..44aa100f4 --- /dev/null +++ b/host/windows/usb/winusb/AdbWinUsbApi.rc @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//Microsoft Visual C++ generated resource script. +// +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +///////////////////////////////////////////////////////////////////////////// +// +// Generated from the TEXTINCLUDE 2 resource. +// +#include "winres.h" + +///////////////////////////////////////////////////////////////////////////// +#undef APSTUDIO_READONLY_SYMBOLS + +#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) +LANGUAGE 9, 1 +#pragma code_page(1252) +#ifdef APSTUDIO_INVOKED +///////////////////////////////////////////////////////////////////////////// +// +// TEXTINCLUDE +// + +1 TEXTINCLUDE +BEGIN + "resource.h\0" +END + +2 TEXTINCLUDE +BEGIN + "#include ""winres.h""\r\n" + "\0" +END + +#endif // APSTUDIO_INVOKED + +#ifndef _MAC +///////////////////////////////////////////////////////////////////////////// +// +// Version +// + +VS_VERSION_INFO VERSIONINFO + FILEVERSION 2,0,0,0 + PRODUCTVERSION 2,0,0,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS 0x1L +#else + FILEFLAGS 0x0L +#endif + FILEOS 0x4L + FILETYPE 0x2L + FILESUBTYPE 0x0L +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904e4" + BEGIN + VALUE "CompanyName", "Google, inc" + VALUE "FileDescription", "Android ADB API (WinUsb)" + VALUE "FileVersion", "2.0.0.0" + VALUE "LegalCopyright", "Copyright (C) 2006 The Android Open Source Project" + VALUE "InternalName", "AdbWinUsbApi.dll" + VALUE "OriginalFilename", "AdbWinUsbApi.dll" + VALUE "ProductName", "Android SDK" + VALUE "ProductVersion", "2.0.0.0" + VALUE "OLESelfRegister", "" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0409, 1252 + END +END + +#endif // !_MAC + +///////////////////////////////////////////////////////////////////////////// +// +// String Table +// + +STRINGTABLE +BEGIN + IDS_PROJNAME "AdbWinUsbApi" +END + +//////////////////////////////////////////////////////////////////////////// + + +#endif + +#ifndef APSTUDIO_INVOKED +#endif // not APSTUDIO_INVOKED diff --git a/host/windows/usb/winusb/BUILDME.TXT b/host/windows/usb/winusb/BUILDME.TXT new file mode 100755 index 000000000..2a459ef53 --- /dev/null +++ b/host/windows/usb/winusb/BUILDME.TXT @@ -0,0 +1,7 @@ +In order to build AdbWinUsbApi.dll you will need to install Windows Driver Kit, +which can be obtained from Microsoft. Assuming that WDK is installed, you +need to set one of the WDK's build environments, "cd" back into this directory, +and execute "build -cbeEIFZ" to clean and rebuild this project, or you can +execute "build -befEIF" to do a minimal build. +Note that you need to build AdbWinApi.dll (..\api) before you build +AdbWinUsbApi.dll, as it depends on AdbWinApi.lib library. diff --git a/host/windows/usb/winusb/MAKEFILE b/host/windows/usb/winusb/MAKEFILE new file mode 100755 index 000000000..fcd896d3f --- /dev/null +++ b/host/windows/usb/winusb/MAKEFILE @@ -0,0 +1,22 @@ +# +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +# +# DO NOT EDIT THIS FILE!!! Edit .\sources. if you want to add a new source +# file to this component. This file merely indirects to the real make file +# that is shared by all the components of NT OS/2 +# +!INCLUDE $(NTMAKEENV)\makefile.def diff --git a/host/windows/usb/winusb/Resource.h b/host/windows/usb/winusb/Resource.h new file mode 100755 index 000000000..3ede761da --- /dev/null +++ b/host/windows/usb/winusb/Resource.h @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//{{NO_DEPENDENCIES}} +// Microsoft Visual C++ generated include file. +// Used by AdbWinApi.rc +// + +#define IDS_PROJNAME 100 +#define IDR_ADBWINAPI 101 + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 201 +#define _APS_NEXT_COMMAND_VALUE 32768 +#define _APS_NEXT_CONTROL_VALUE 201 +#define _APS_NEXT_SYMED_VALUE 102 +#endif +#endif diff --git a/host/windows/usb/winusb/SOURCES b/host/windows/usb/winusb/SOURCES new file mode 100755 index 000000000..80d17ae1f --- /dev/null +++ b/host/windows/usb/winusb/SOURCES @@ -0,0 +1,93 @@ +# +# Copyright (C) 2009 The Android Open Source Project +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +TARGETNAME = AdbWinUsbApi +TARGETPATH = obj +TARGETTYPE = DYNLINK + +UMTYPE = windows +DLLDEF = AdbWinUsbApi.def + +# Use statically linked atl libraries: +# - atls.lib for free build +# - atlsd.lib for checked build +USE_STATIC_ATL = 1 +# Use ATL v. 7.1 +ATL_VER = 71 +# Use STL v. 6.0 +USE_STL = 1 +STL_VER = 60 +# Use multithreaded libraries +USE_LIBCMT = 1 + +# Include directories +INCLUDES = $(DDK_INC_PATH); \ + $(SDK_INC_PATH); \ + $(CRT_INC_PATH); \ + $(SDK_INC_PATH)\crt; \ + $(CRT_INC_PATH)\atl71; \ + $(SDK_INC_PATH)\crt\stl60 + +# Common target libraries +TARGETLIBS = $(SDK_LIB_PATH)\ole32.lib \ + $(SDK_LIB_PATH)\Advapi32.lib \ + $(SDK_LIB_PATH)\Kernel32.lib \ + $(SDK_LIB_PATH)\User32.lib \ + $(SDK_LIB_PATH)\oleaut32.lib \ + $(SDK_LIB_PATH)\wbemuuid.lib \ + $(SDK_LIB_PATH)\uuid.lib \ + $(SDK_LIB_PATH)\setupapi.lib \ + $(SDK_LIB_PATH)\usbd.lib \ + $(SDK_LIB_PATH)\winusb.lib \ + ..\api\obj$(BUILD_ALT_DIR)\i386\AdbWinApi.lib + +!IF "$(DDKBUILDENV)" == "fre" +# Libraries for release (free) builds +TARGETLIBS = $(TARGETLIBS) $(ATL_LIB_PATH)\atls.lib +!ELSE +# Libraries for debug (checked) builds +TARGETLIBS = $(TARGETLIBS) $(ATL_LIB_PATH)\atlsd.lib +!ENDIF + +# Common C defines +C_DEFINES= $(C_DEFINES) -DADBWINUSB_EXPORTS -D_UNICODE \ + -DUNICODE -DWIN32 -D_WINDOWS -D_USRDLL -D_WINDLL + +!IF "$(DDKBUILDENV)" == "fre" +# C defines for release (free) builds +C_DEFINES = $(C_DEFINES) -DNDEBUG +!ELSE +# C defines for debug (checked) builds +C_DEFINES = $(C_DEFINES) -D_DEBUG +!ENDIF + +# Turn on all warnings, and treat warnings as errors +MSC_WARNING_LEVEL = /W4 /Wp64 /WX + +# Common C defines +USER_C_FLAGS = $(USER_C_FLAGS) /FD /EHsc /wd4100 /wd4200 /wd4702 /nologo + +# Set precompiled header information +PRECOMPILED_CXX = 1 +PRECOMPILED_INCLUDE = stdafx.h +PRECOMPILED_SOURCEFILE = stdafx.cpp + +# Define source files for AdbWinUsbApi.dll +SOURCES = adb_winusb_endpoint_object.cpp \ + adb_winusb_interface.cpp \ + adb_winusb_io_completion.cpp \ + AdbWinUsbApi.cpp \ + AdbWinUsbApi.rc diff --git a/host/windows/usb/api/adb_winusb_endpoint_object.cpp b/host/windows/usb/winusb/adb_winusb_endpoint_object.cpp similarity index 93% rename from host/windows/usb/api/adb_winusb_endpoint_object.cpp rename to host/windows/usb/winusb/adb_winusb_endpoint_object.cpp index 236de3b49..16f78370c 100755 --- a/host/windows/usb/api/adb_winusb_endpoint_object.cpp +++ b/host/windows/usb/winusb/adb_winusb_endpoint_object.cpp @@ -22,7 +22,6 @@ #include "stdafx.h" #include "adb_winusb_endpoint_object.h" #include "adb_winusb_io_completion.h" -#include "adb_helper_routines.h" AdbWinUsbEndpointObject::AdbWinUsbEndpointObject( AdbWinUsbInterfaceObject* parent_interf, @@ -34,6 +33,17 @@ AdbWinUsbEndpointObject::AdbWinUsbEndpointObject( AdbWinUsbEndpointObject::~AdbWinUsbEndpointObject() { } +LONG AdbWinUsbEndpointObject::Release() { + ATLASSERT(ref_count_ > 0); + LONG ret = InterlockedDecrement(&ref_count_); + ATLASSERT(ret >= 0); + if (0 == ret) { + LastReferenceReleased(); + delete this; + } + return ret; +} + ADBAPIHANDLE AdbWinUsbEndpointObject::CommonAsyncReadWrite( bool is_read, void* buffer, diff --git a/host/windows/usb/api/adb_winusb_endpoint_object.h b/host/windows/usb/winusb/adb_winusb_endpoint_object.h similarity index 81% rename from host/windows/usb/api/adb_winusb_endpoint_object.h rename to host/windows/usb/winusb/adb_winusb_endpoint_object.h index 26ef53b16..92b6e04fe 100755 --- a/host/windows/usb/api/adb_winusb_endpoint_object.h +++ b/host/windows/usb/winusb/adb_winusb_endpoint_object.h @@ -21,7 +21,7 @@ encapsulates a handle opened to a WinUsb endpoint on our device. */ -#include "adb_endpoint_object.h" +#include "..\api\adb_endpoint_object.h" #include "adb_winusb_interface.h" /** Class AdbWinUsbEndpointObject encapsulates a handle opened to an endpoint on @@ -48,6 +48,30 @@ class AdbWinUsbEndpointObject : public AdbEndpointObject { */ virtual ~AdbWinUsbEndpointObject(); + // + // Virtual overrides + // + + public: + /** \brief Releases the object. + + If refcount drops to zero as the result of this release, the object is + destroyed in this method. As a general rule, objects must not be touched + after this method returns even if returned value is not zero. We override + this method in order to make sure that objects of this class are deleted + in contect of the DLL they were created in. The problem is that since + objects of this class were created in context of AdbWinUsbApi module, they + are allocated from the heap assigned to that module. Now, if these objects + are deleted outside of AdbWinUsbApi module, this will lead to the heap + corruption in the module that deleted these objects. Since all objects of + this class are deleted in the Release method only, by overriding it we make + sure that we free memory in the context of the module where it was + allocated. + @return Value of the reference counter after object is released in this + method. + */ + virtual LONG Release(); + // // Abstract overrides // diff --git a/host/windows/usb/api/adb_winusb_interface.cpp b/host/windows/usb/winusb/adb_winusb_interface.cpp similarity index 95% rename from host/windows/usb/api/adb_winusb_interface.cpp rename to host/windows/usb/winusb/adb_winusb_interface.cpp index d09c1cbeb..9d0377a46 100755 --- a/host/windows/usb/api/adb_winusb_interface.cpp +++ b/host/windows/usb/winusb/adb_winusb_interface.cpp @@ -40,6 +40,17 @@ AdbWinUsbInterfaceObject::~AdbWinUsbInterfaceObject() { ATLASSERT(INVALID_HANDLE_VALUE == usb_device_handle_); } +LONG AdbWinUsbInterfaceObject::Release() { + ATLASSERT(ref_count_ > 0); + LONG ret = InterlockedDecrement(&ref_count_); + ATLASSERT(ret >= 0); + if (0 == ret) { + LastReferenceReleased(); + delete this; + } + return ret; +} + ADBAPIHANDLE AdbWinUsbInterfaceObject::CreateHandle() { // Open USB device for this inteface Note that WinUsb API // requires the handle to be opened for overlapped I/O. diff --git a/host/windows/usb/api/adb_winusb_interface.h b/host/windows/usb/winusb/adb_winusb_interface.h similarity index 84% rename from host/windows/usb/api/adb_winusb_interface.h rename to host/windows/usb/winusb/adb_winusb_interface.h index 82f7f8985..2311fd170 100755 --- a/host/windows/usb/api/adb_winusb_interface.h +++ b/host/windows/usb/winusb/adb_winusb_interface.h @@ -22,7 +22,7 @@ via WinUsb API. */ -#include "adb_interface.h" +#include "..\api\adb_interface.h" /** \brief Encapsulates an interface on our USB device that is accessible via WinUsb API. @@ -48,6 +48,25 @@ class AdbWinUsbInterfaceObject : public AdbInterfaceObject { // public: + /** \brief Releases the object. + + If refcount drops to zero as the result of this release, the object is + destroyed in this method. As a general rule, objects must not be touched + after this method returns even if returned value is not zero. We override + this method in order to make sure that objects of this class are deleted + in contect of the DLL they were created in. The problem is that since + objects of this class were created in context of AdbWinUsbApi module, they + are allocated from the heap assigned to that module. Now, if these objects + are deleted outside of AdbWinUsbApi module, this will lead to the heap + corruption in the module that deleted these objects. Since all objects of + this class are deleted in the Release method only, by overriding it we make + sure that we free memory in the context of the module where it was + allocated. + @return Value of the reference counter after object is released in this + method. + */ + virtual LONG Release(); + /** \brief Creates handle to this object. In this call a handle for this object is generated and object is added diff --git a/host/windows/usb/api/adb_winusb_io_completion.cpp b/host/windows/usb/winusb/adb_winusb_io_completion.cpp similarity index 89% rename from host/windows/usb/api/adb_winusb_io_completion.cpp rename to host/windows/usb/winusb/adb_winusb_io_completion.cpp index baeb7bbb8..d98f87254 100755 --- a/host/windows/usb/api/adb_winusb_io_completion.cpp +++ b/host/windows/usb/winusb/adb_winusb_io_completion.cpp @@ -33,6 +33,17 @@ AdbWinUsbIOCompletion::AdbWinUsbIOCompletion( AdbWinUsbIOCompletion::~AdbWinUsbIOCompletion() { } +LONG AdbWinUsbIOCompletion::Release() { + ATLASSERT(ref_count_ > 0); + LONG ret = InterlockedDecrement(&ref_count_); + ATLASSERT(ret >= 0); + if (0 == ret) { + LastReferenceReleased(); + delete this; + } + return ret; +} + bool AdbWinUsbIOCompletion::GetOvelappedIoResult(LPOVERLAPPED ovl_data, ULONG* bytes_transferred, bool wait) { diff --git a/host/windows/usb/api/adb_winusb_io_completion.h b/host/windows/usb/winusb/adb_winusb_io_completion.h similarity index 75% rename from host/windows/usb/api/adb_winusb_io_completion.h rename to host/windows/usb/winusb/adb_winusb_io_completion.h index a97a3a8b2..93a4c07eb 100755 --- a/host/windows/usb/api/adb_winusb_io_completion.h +++ b/host/windows/usb/winusb/adb_winusb_io_completion.h @@ -22,7 +22,7 @@ asynchronous I/O requests issued via WinUsb API. */ -#include "adb_io_completion.h" +#include "..\api\adb_io_completion.h" #include "adb_winusb_endpoint_object.h" /** \brief Encapsulates encapsulates a wrapper around OVERLAPPED Win32 @@ -56,6 +56,30 @@ class AdbWinUsbIOCompletion : public AdbIOCompletion { */ virtual ~AdbWinUsbIOCompletion(); + // + // Virtual overrides + // + + public: + /** \brief Releases the object. + + If refcount drops to zero as the result of this release, the object is + destroyed in this method. As a general rule, objects must not be touched + after this method returns even if returned value is not zero. We override + this method in order to make sure that objects of this class are deleted + in contect of the DLL they were created in. The problem is that since + objects of this class were created in context of AdbWinUsbApi module, they + are allocated from the heap assigned to that module. Now, if these objects + are deleted outside of AdbWinUsbApi module, this will lead to the heap + corruption in the module that deleted these objects. Since all objects of + this class are deleted in the Release method only, by overriding it we make + sure that we free memory in the context of the module where it was + allocated. + @return Value of the reference counter after object is released in this + method. + */ + virtual LONG Release(); + // // Abstract overrides // diff --git a/host/windows/usb/winusb/stdafx.cpp b/host/windows/usb/winusb/stdafx.cpp new file mode 100755 index 000000000..562765b81 --- /dev/null +++ b/host/windows/usb/winusb/stdafx.cpp @@ -0,0 +1,21 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// stdafx.cpp : source file that includes just the standard includes +// AdbWinUsbApi.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" diff --git a/host/windows/usb/winusb/stdafx.h b/host/windows/usb/winusb/stdafx.h new file mode 100755 index 000000000..c2aa8dee6 --- /dev/null +++ b/host/windows/usb/winusb/stdafx.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/** \file + Visual Studio generated include file for standard system include files, or + project specific include files that are used frequently, but are changed + infrequently. +*/ + +#pragma once + +#ifndef STRICT +#define STRICT +#endif + +// Modify the following defines if you have to target a platform prior to the ones specified below. +// Refer to MSDN for the latest info on corresponding values for different platforms. +#ifndef WINVER // Allow use of features specific to Windows 95 and Windows NT 4 or later. +#define WINVER 0x0500 // Change this to the appropriate value to target Windows 98 and Windows 2000 or later. +#endif + +#ifndef _WIN32_WINNT // Allow use of features specific to Windows NT 4 or later. +#define _WIN32_WINNT 0x0500 // Change this to the appropriate value to target Windows 2000 or later. +#endif + +#ifndef _WIN32_WINDOWS // Allow use of features specific to Windows 98 or later. +#define _WIN32_WINDOWS 0x0500 // Change this to the appropriate value to target Windows Me or later. +#endif + +#ifndef _WIN32_IE // Allow use of features specific to IE 4.0 or later. +#define _WIN32_IE 0x0501 // Change this to the appropriate value to target IE 5.0 or later. +#endif + +// These defines prevent the MS header files from ejecting #pragma comment +// statements with the manifest information of the used ATL, STL, and CRT +#define _ATL_NOFORCE_MANIFEST +#define _STL_NOFORCE_MANIFEST +#define _CRT_NOFORCE_MANIFEST + +#define _ATL_APARTMENT_THREADED +#define _ATL_NO_AUTOMATIC_NAMESPACE + +#define _ATL_CSTRING_EXPLICIT_CONSTRUCTORS // some CString constructors will be explicit + +// turns off ATL's hiding of some common and often safely ignored warning messages +#define _ATL_ALL_WARNINGS + +// #define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers + +#include +#pragma warning(disable: 4702) +#pragma warning(disable: 4201) +#include +#include +#include +#include +#include +#include +#pragma warning(default: 4201) +#pragma warning(disable: 4200) +#include + +#include "resource.h" + +using namespace ATL; diff --git a/ndk/build/tools/make-release.sh b/ndk/build/tools/make-release.sh index f2b969737..002150a6c 100755 --- a/ndk/build/tools/make-release.sh +++ b/ndk/build/tools/make-release.sh @@ -23,7 +23,7 @@ NDK_ROOT_DIR=`dirname $0`/../.. NDK_ROOT_DIR=`cd $NDK_ROOT_DIR && pwd` # the release name -RELEASE=1.5_r2 +RELEASE=1.6_r1 # the package prefix PREFIX=android-ndk diff --git a/ndk/docs/CHANGES.TXT b/ndk/docs/CHANGES.TXT index d7771daff..faad11db8 100644 --- a/ndk/docs/CHANGES.TXT +++ b/ndk/docs/CHANGES.TXT @@ -1,7 +1,7 @@ Android NDK ChangeLog: ------------------------------------------------------------------------------- -current version +android-ndk-1.6_r1 IMPORTANT BUG FIXES: diff --git a/pdk/docs/community/index.jd b/pdk/docs/community/index.jd new file mode 100644 index 000000000..bc04eee7d --- /dev/null +++ b/pdk/docs/community/index.jd @@ -0,0 +1,6 @@ +home=true +@jd:body + +

+ Some community information here +

diff --git a/pdk/docs/guide/audio.jd b/pdk/docs/guide/audio.jd index 14e80bb45..66c05f744 100755 --- a/pdk/docs/guide/audio.jd +++ b/pdk/docs/guide/audio.jd @@ -1,5 +1,6 @@ page.title=Audio pdk.version=1.0 +doc.type=guide @jd:body
diff --git a/pdk/docs/guide/bluetooth.jd b/pdk/docs/guide/bluetooth.jd index e514ef0eb..bcf88dbec 100755 --- a/pdk/docs/guide/bluetooth.jd +++ b/pdk/docs/guide/bluetooth.jd @@ -1,5 +1,6 @@ page.title=Bluetooth pdk.version=1.0 +doc.type=guide @jd:body
diff --git a/pdk/docs/guide/bluetooth/bluetooth_process.jd b/pdk/docs/guide/bluetooth/bluetooth_process.jd index 86e9c935d..ea46f231e 100755 --- a/pdk/docs/guide/bluetooth/bluetooth_process.jd +++ b/pdk/docs/guide/bluetooth/bluetooth_process.jd @@ -1,6 +1,7 @@ page.title=Bluetooth Process Diagram pdk.version=1.0 +doc.type=guide @jd:body

The diagram below offers a process-oriented architectural overview of Android's Bluetooth stack. Click Bluetooth to return to the Bluetooth overview page.

- \ No newline at end of file + diff --git a/pdk/docs/guide/bring_up.jd b/pdk/docs/guide/bring_up.jd index 85d7b266c..a11fe00ff 100755 --- a/pdk/docs/guide/bring_up.jd +++ b/pdk/docs/guide/bring_up.jd @@ -1,5 +1,6 @@ page.title=Bring Up pdk.version=1.0 +doc.type=guide @jd:body

Once your code is built and you have verified that all necessary directories exist, power on and test your device with basic bring up, as described below. Bring up tests are typically designed to stress certain aspects of your system and allow you to characterize the device's behavior.

@@ -355,4 +356,4 @@ service akmd /sbin/akmd disabled user akmd group akmd - \ No newline at end of file + diff --git a/pdk/docs/guide/build_cookbook.jd b/pdk/docs/guide/build_cookbook.jd index fc34132c0..4bed9471b 100755 --- a/pdk/docs/guide/build_cookbook.jd +++ b/pdk/docs/guide/build_cookbook.jd @@ -1,5 +1,6 @@ page.title=Build Cookbook pdk.version=1.0 +doc.type=guide @jd:body
@@ -552,4 +553,4 @@ module. This can be fixed. If you ever need it to be, just ask.

- \ No newline at end of file + diff --git a/pdk/docs/guide/build_new_device.jd b/pdk/docs/guide/build_new_device.jd index dabdfb061..28e7c2eb3 100755 --- a/pdk/docs/guide/build_new_device.jd +++ b/pdk/docs/guide/build_new_device.jd @@ -1,5 +1,6 @@ page.title=Configuring a New Product pdk.version=1.0 +doc.type=guide @jd:body diff --git a/pdk/docs/guide/build_system.jd b/pdk/docs/guide/build_system.jd index d22998383..fd0ff8074 100755 --- a/pdk/docs/guide/build_system.jd +++ b/pdk/docs/guide/build_system.jd @@ -1,5 +1,6 @@ page.title=Android Build System pdk.version=1.0 +doc.type=guide @jd:body @@ -266,4 +267,4 @@ If you build one flavor and then want to build another, you should run make installclean between the two makes to guarantee that you don't pick up files installed by the previous flavor. make clean will also suffice, but it takes a lot longer. -

\ No newline at end of file +

diff --git a/pdk/docs/guide/camera.jd b/pdk/docs/guide/camera.jd index 281f76dd6..98636d8de 100755 --- a/pdk/docs/guide/camera.jd +++ b/pdk/docs/guide/camera.jd @@ -1,5 +1,6 @@ page.title=Camera pdk.version=1.0 +doc.type=guide @jd:body
diff --git a/pdk/docs/guide/customization.jd b/pdk/docs/guide/customization.jd index 9c39cd735..9c56681d1 100755 --- a/pdk/docs/guide/customization.jd +++ b/pdk/docs/guide/customization.jd @@ -1,5 +1,6 @@ page.title=Customization pdk.version=1.0 +doc.type=guide @jd:body
@@ -317,4 +318,4 @@ include $(LOCAL_PATH)/client/Android.mk

Animations

Android supports configurable animations for window and view transitions. System-level animations are defined in XML in global resource files located in //android/framework/base/core/res/res/anim/.

- \ No newline at end of file + diff --git a/pdk/docs/guide/dalvik.jd b/pdk/docs/guide/dalvik.jd index 948496a98..6fa37da9b 100755 --- a/pdk/docs/guide/dalvik.jd +++ b/pdk/docs/guide/dalvik.jd @@ -1,5 +1,6 @@ page.title=Dalvik pdk.version=1.0 +doc.type=guide @jd:body
diff --git a/pdk/docs/guide/debugging_gdb.jd b/pdk/docs/guide/debugging_gdb.jd index 9717cf384..f2a2db5d4 100755 --- a/pdk/docs/guide/debugging_gdb.jd +++ b/pdk/docs/guide/debugging_gdb.jd @@ -1,5 +1,6 @@ page.title=Debugging with GDB pdk.version=1.0 +doc.type=guide @jd:body
@@ -142,4 +143,4 @@ Execute the line shown in the debug output, substituting 5039 for the proper

Otherwise you need to determine the path of the crashing binary and follow the steps as mentioned above (for example, gdbclient hoser :5039 if - the hoser command has failed).

\ No newline at end of file + the hoser command has failed).

diff --git a/pdk/docs/guide/debugging_native.jd b/pdk/docs/guide/debugging_native.jd index 6705766a8..0f8b39731 100755 --- a/pdk/docs/guide/debugging_native.jd +++ b/pdk/docs/guide/debugging_native.jd @@ -1,5 +1,6 @@ page.title=Debugging Native Code pdk.version=1.0 +doc.type=guide @jd:body diff --git a/pdk/docs/guide/display_drivers.jd b/pdk/docs/guide/display_drivers.jd index ac41c55ce..1eddd155b 100755 --- a/pdk/docs/guide/display_drivers.jd +++ b/pdk/docs/guide/display_drivers.jd @@ -1,5 +1,6 @@ page.title=Display Drivers pdk.version=1.0 +doc.type=guide @jd:body diff --git a/pdk/docs/guide/getting_source_code.jd b/pdk/docs/guide/getting_source_code.jd index 19a7069ab..e7352743b 100755 --- a/pdk/docs/guide/getting_source_code.jd +++ b/pdk/docs/guide/getting_source_code.jd @@ -1,4 +1,6 @@ page.title=Getting Source Code +pdk.version=1.0 +doc.type=guide @jd:body diff --git a/pdk/docs/guide/gps.jd b/pdk/docs/guide/gps.jd index f2ce11c16..2acad6d7d 100755 --- a/pdk/docs/guide/gps.jd +++ b/pdk/docs/guide/gps.jd @@ -1,5 +1,6 @@ page.title=GPS pdk.version=1.0 +doc.type=guide @jd:body
diff --git a/pdk/docs/guide/group__memory.jd b/pdk/docs/guide/group__memory.jd index 87f19d5f9..0423515ae 100755 --- a/pdk/docs/guide/group__memory.jd +++ b/pdk/docs/guide/group__memory.jd @@ -1,4 +1,6 @@ page.title=Providing Heap Memory +pdk.version=1.0 +doc.type=guide @jd:body