merge from donut
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Záloha"</string>
|
<string name="appTitle" msgid="161410001913116606">"Záloha"</string>
|
||||||
<string name="title">"Akce není podporována"</string>
|
<string name="title" msgid="8156274565006125136">"Akce není podporována"</string>
|
||||||
<string name="error">"Tato akce není momentálně podporována."</string>
|
<string name="error" msgid="6539615832923362301">"Tato akce není momentálně podporována."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Reserve"</string>
|
<string name="appTitle" msgid="161410001913116606">"Reserve"</string>
|
||||||
<string name="title">"Ikke understøttet handling"</string>
|
<string name="title" msgid="8156274565006125136">"Ikke understøttet handling"</string>
|
||||||
<string name="error">"Handlingen er ikke understøttet i øjeblikket."</string>
|
<string name="error" msgid="6539615832923362301">"Handlingen er ikke understøttet i øjeblikket."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"Nicht unterstützte Aktion"</string>
|
<string name="title" msgid="8156274565006125136">"Nicht unterstützte Aktion"</string>
|
||||||
<string name="error">"Diese Aktion wird zurzeit nicht unterstützt."</string>
|
<string name="error" msgid="6539615832923362301">"Diese Aktion wird zurzeit nicht unterstützt."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Εναλλακτική"</string>
|
<string name="appTitle" msgid="161410001913116606">"Εναλλακτική"</string>
|
||||||
<string name="title">"Ενέργεια που δεν υποστηρίζεται"</string>
|
<string name="title" msgid="8156274565006125136">"Ενέργεια που δεν υποστηρίζεται"</string>
|
||||||
<string name="error">"Αυτή η ενέργεια δεν υποστηρίζεται αυτήν τη στιγμή."</string>
|
<string name="error" msgid="6539615832923362301">"Αυτή η ενέργεια δεν υποστηρίζεται αυτήν τη στιγμή."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"Acción no admitida"</string>
|
<string name="title" msgid="8156274565006125136">"Acción no admitida"</string>
|
||||||
<string name="error">"Esa acción no se admite actualmente."</string>
|
<string name="error" msgid="6539615832923362301">"Esa acción no se admite actualmente."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"Acción no admitida"</string>
|
<string name="title" msgid="8156274565006125136">"Acción no admitida"</string>
|
||||||
<string name="error">"Esa acción no se admite actualmente."</string>
|
<string name="error" msgid="6539615832923362301">"Esa acción no se admite actualmente."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Application de secours"</string>
|
<string name="appTitle" msgid="161410001913116606">"Application de secours"</string>
|
||||||
<string name="title">"Action non prise en charge"</string>
|
<string name="title" msgid="8156274565006125136">"Action non prise en charge"</string>
|
||||||
<string name="error">"Cette action n\'est actuellement pas prise en charge."</string>
|
<string name="error" msgid="6539615832923362301">"Cette action n\'est actuellement pas prise en charge."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"Azione non supportata"</string>
|
<string name="title" msgid="8156274565006125136">"Azione non supportata"</string>
|
||||||
<string name="error">"L\'azione non è al momento supportata."</string>
|
<string name="error" msgid="6539615832923362301">"L\'azione non è al momento supportata."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"サポートされていない操作"</string>
|
<string name="title" msgid="8156274565006125136">"サポートされていない操作"</string>
|
||||||
<string name="error">"現在サポートされていない操作です。"</string>
|
<string name="error" msgid="6539615832923362301">"現在サポートされていない操作です。"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"폴백"</string>
|
<string name="appTitle" msgid="161410001913116606">"폴백"</string>
|
||||||
<string name="title">"지원되지 않는 작업"</string>
|
<string name="title" msgid="8156274565006125136">"지원되지 않는 작업"</string>
|
||||||
<string name="error">"이 작업은 현재 지원되지 않습니다."</string>
|
<string name="error" msgid="6539615832923362301">"이 작업은 현재 지원되지 않습니다."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"Ustøttet handling"</string>
|
<string name="title" msgid="8156274565006125136">"Ustøttet handling"</string>
|
||||||
<string name="error">"Denne handlingen er ikke støttet nå."</string>
|
<string name="error" msgid="6539615832923362301">"Denne handlingen er ikke støttet nå."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Reserve"</string>
|
<string name="appTitle" msgid="161410001913116606">"Reserve"</string>
|
||||||
<string name="title">"Niet-ondersteunde actie"</string>
|
<string name="title" msgid="8156274565006125136">"Niet-ondersteunde actie"</string>
|
||||||
<string name="error">"Die actie wordt momenteel niet ondersteund."</string>
|
<string name="error" msgid="6539615832923362301">"Die actie wordt momenteel niet ondersteund."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Wycofanie"</string>
|
<string name="appTitle" msgid="161410001913116606">"Wycofanie"</string>
|
||||||
<string name="title">"Nieobsługiwana czynność"</string>
|
<string name="title" msgid="8156274565006125136">"Nieobsługiwana czynność"</string>
|
||||||
<string name="error">"Ta czynność nie jest aktualnie obsługiwana."</string>
|
<string name="error" msgid="6539615832923362301">"Ta czynność nie jest aktualnie obsługiwana."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"Acção não suportada"</string>
|
<string name="title" msgid="8156274565006125136">"Acção não suportada"</string>
|
||||||
<string name="error">"Esta·acção·ainda·não·é·suportada."</string>
|
<string name="error" msgid="6539615832923362301">"Esta acção ainda não é suportada."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"Ação não suportada"</string>
|
<string name="title" msgid="8156274565006125136">"Ação não suportada"</string>
|
||||||
<string name="error">"Essa ação não é suportada no momento."</string>
|
<string name="error" msgid="6539615832923362301">"Essa ação não é suportada no momento."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Переход в обходной режим"</string>
|
<string name="appTitle" msgid="161410001913116606">"Переход в обходной режим"</string>
|
||||||
<string name="title">"Неподдерживаемое действие"</string>
|
<string name="title" msgid="8156274565006125136">"Неподдерживаемое действие"</string>
|
||||||
<string name="error">"В настоящее время это действие не поддерживается."</string>
|
<string name="error" msgid="6539615832923362301">"В настоящее время это действие не поддерживается."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Reserv"</string>
|
<string name="appTitle" msgid="161410001913116606">"Reserv"</string>
|
||||||
<string name="title">"Åtgärden stöds inte"</string>
|
<string name="title" msgid="8156274565006125136">"Åtgärden stöds inte"</string>
|
||||||
<string name="error">"Den här åtgärden stöds inte för närvarande."</string>
|
<string name="error" msgid="6539615832923362301">"Den här åtgärden stöds inte för närvarande."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"Fallback"</string>
|
<string name="appTitle" msgid="161410001913116606">"Fallback"</string>
|
||||||
<string name="title">"Desteklenmeyen işlem"</string>
|
<string name="title" msgid="8156274565006125136">"Desteklenmeyen işlem"</string>
|
||||||
<string name="error">"Bu işlem şu an desteklenmiyor."</string>
|
<string name="error" msgid="6539615832923362301">"Bu işlem şu an desteklenmiyor."</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"后备"</string>
|
<string name="appTitle" msgid="161410001913116606">"后备"</string>
|
||||||
<string name="title">"不支持此操作"</string>
|
<string name="title" msgid="8156274565006125136">"不支持此操作"</string>
|
||||||
<string name="error">"目前不支持该操作。"</string>
|
<string name="error" msgid="6539615832923362301">"目前不支持该操作。"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
-->
|
-->
|
||||||
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
<resources xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
|
||||||
<string name="appTitle">"備用"</string>
|
<string name="appTitle" msgid="161410001913116606">"備用"</string>
|
||||||
<string name="title">"不支援的操作"</string>
|
<string name="title" msgid="8156274565006125136">"不支援的操作"</string>
|
||||||
<string name="error">"目前不支援此操作。"</string>
|
<string name="error" msgid="6539615832923362301">"目前不支援此操作。"</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ bin/sqlite3 tools/sqlite3
|
|||||||
bin/dmtracedump tools/dmtracedump
|
bin/dmtracedump tools/dmtracedump
|
||||||
bin/hprof-conv tools/hprof-conv
|
bin/hprof-conv tools/hprof-conv
|
||||||
bin/mksdcard tools/mksdcard
|
bin/mksdcard tools/mksdcard
|
||||||
|
bin/zipalign tools/zipalign
|
||||||
|
|
||||||
# the uper-jar file that apps link against
|
# the uper-jar file that apps link against
|
||||||
out/target/common/obj/PACKAGING/android_jar_intermediates/android.jar platforms/${PLATFORM_NAME}/android.jar
|
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.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.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/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
|
sdk/sdk-build.prop platforms/${PLATFORM_NAME}/build.prop
|
||||||
development/tools/scripts/plugin.prop tools/lib/plugin.prop
|
development/tools/scripts/plugin.prop tools/lib/plugin.prop
|
||||||
@@ -49,7 +50,6 @@ obj/framework.aidl platforms/${PLATFORM_NAME}/framework.aidl
|
|||||||
|
|
||||||
# sdk scripts
|
# sdk scripts
|
||||||
development/tools/scripts/AndroidManifest.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.template
|
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/AndroidManifest.tests.template platforms/${PLATFORM_NAME}/templates/AndroidManifest.tests.template
|
||||||
development/tools/scripts/iml.template platforms/${PLATFORM_NAME}/templates/iml.template
|
development/tools/scripts/iml.template platforms/${PLATFORM_NAME}/templates/iml.template
|
||||||
development/tools/scripts/ipr.template platforms/${PLATFORM_NAME}/templates/ipr.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/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/layout.template platforms/${PLATFORM_NAME}/templates/layout.template
|
||||||
development/tools/scripts/strings.template platforms/${PLATFORM_NAME}/templates/strings.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/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.template tools/lib/build.template
|
||||||
development/tools/scripts/build.alias.template tools/lib/build.alias.template
|
|
||||||
|
|
||||||
# emacs support
|
# emacs support
|
||||||
development/tools/scripts/android.el tools/lib/android.el
|
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/Snake platforms/${PLATFORM_NAME}/samples/Snake
|
||||||
development/samples/SoftKeyboard platforms/${PLATFORM_NAME}/samples/SoftKeyboard
|
development/samples/SoftKeyboard platforms/${PLATFORM_NAME}/samples/SoftKeyboard
|
||||||
development/samples/JetBoy platforms/${PLATFORM_NAME}/samples/JetBoy
|
development/samples/JetBoy platforms/${PLATFORM_NAME}/samples/JetBoy
|
||||||
|
development/samples/SearchableDictionary platforms/${PLATFORM_NAME}/samples/SearchableDictionary
|
||||||
|
|
||||||
# dx
|
# dx
|
||||||
bin/dx platforms/${PLATFORM_NAME}/tools/dx
|
bin/dx platforms/${PLATFORM_NAME}/tools/dx
|
||||||
@@ -148,7 +146,8 @@ external/qemu/android/avd/hardware-properties.ini tools/lib/hardware-properties.
|
|||||||
# emulator skins
|
# emulator skins
|
||||||
development/emulator/skins/HVGA platforms/${PLATFORM_NAME}/skins/HVGA
|
development/emulator/skins/HVGA platforms/${PLATFORM_NAME}/skins/HVGA
|
||||||
development/emulator/skins/QVGA platforms/${PLATFORM_NAME}/skins/QVGA
|
development/emulator/skins/QVGA platforms/${PLATFORM_NAME}/skins/QVGA
|
||||||
development/emulator/skins/WVGA platforms/${PLATFORM_NAME}/skins/WVGA
|
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
|
# NOTICE files are copied by build/core/Makefile
|
||||||
development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/templates/NOTICE.txt
|
development/tools/scripts/sdk_files_NOTICE.txt platforms/${PLATFORM_NAME}/templates/NOTICE.txt
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ DIST_DIR="$2"
|
|||||||
TEMP_DIR="$3"
|
TEMP_DIR="$3"
|
||||||
[ -z "$TEMP_DIR" ] && TEMP_DIR=${TMP:-/tmp}
|
[ -z "$TEMP_DIR" ] && TEMP_DIR=${TMP:-/tmp}
|
||||||
|
|
||||||
|
|
||||||
function die() {
|
function die() {
|
||||||
echo "Error:" $*
|
echo "Error:" $*
|
||||||
echo "Aborting"
|
echo "Aborting"
|
||||||
@@ -33,7 +32,9 @@ function die() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function usage() {
|
function usage() {
|
||||||
echo "Usage: ${PROG_NAME} linux_or_mac_sdk.zip output_dir [temp_dir]"
|
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."
|
echo "If temp_dir is not given, \$TMP is used. If that's missing, /tmp is used."
|
||||||
status
|
status
|
||||||
exit 2
|
exit 2
|
||||||
@@ -92,7 +93,14 @@ function build() {
|
|||||||
make -j 4 emulator || die "Build failed"
|
make -j 4 emulator || die "Build failed"
|
||||||
# Disable parallel build: it generates "permission denied" issues when
|
# Disable parallel build: it generates "permission denied" issues when
|
||||||
# multiple "ar.exe" are running in parallel.
|
# 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"
|
|| die "Build failed"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,12 +132,16 @@ function package() {
|
|||||||
"Instead found " $THE_PLATFORM
|
"Instead found " $THE_PLATFORM
|
||||||
[[ -d "$PLATFORM_TOOLS" ]] || die "Missing folder $PLATFORM_TOOLS."
|
[[ -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
|
# Remove obsolete stuff from tools & platform
|
||||||
TOOLS="$TEMP_SDK_DIR/tools"
|
TOOLS="$TEMP_SDK_DIR/tools"
|
||||||
LIB="$TEMP_SDK_DIR/tools/lib"
|
LIB="$TEMP_SDK_DIR/tools/lib"
|
||||||
rm -v "$TOOLS"/{adb,android,apkbuilder,ddms,dmtracedump,draw9patch,emulator}
|
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 "$LIB"/*/swt.jar
|
||||||
rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
|
rm -v "$PLATFORM_TOOLS"/{aapt,aidl,dx,dexdump}
|
||||||
|
|
||||||
@@ -183,8 +195,9 @@ function package() {
|
|||||||
|
|
||||||
# Copy or move platform specific tools to the default platform.
|
# Copy or move platform specific tools to the default platform.
|
||||||
cp -v dalvik/dx/etc/dx.bat "$PLATFORM_TOOLS"/
|
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} "$PLATFORM_TOOLS"/
|
||||||
mv -v "$TOOLS"/{aapt.exe,aidl.exe,dexdump.exe,mgwz.dll} "$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
|
# 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/<name>/tools/
|
# as well as all batch files including those in platforms/<name>/tools/
|
||||||
@@ -200,14 +213,14 @@ function package() {
|
|||||||
# Now move the final zip from the temp dest to the final dist dir
|
# 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"
|
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 "Done"
|
||||||
echo
|
echo
|
||||||
echo "Resulting SDK is in $DIST_DIR/$DEST_NAME_ZIP"
|
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
|
check
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ LOCAL_SRC_FILES := $(call all-subdir-java-files)
|
|||||||
LOCAL_MODULE := monkey
|
LOCAL_MODULE := monkey
|
||||||
include $(BUILD_JAVA_LIBRARY)
|
include $(BUILD_JAVA_LIBRARY)
|
||||||
|
|
||||||
|
################################################################
|
||||||
include $(CLEAR_VARS)
|
include $(CLEAR_VARS)
|
||||||
ALL_PREBUILT += $(TARGET_OUT)/bin/monkey
|
ALL_PREBUILT += $(TARGET_OUT)/bin/monkey
|
||||||
$(TARGET_OUT)/bin/monkey : $(LOCAL_PATH)/monkey | $(ACP)
|
$(TARGET_OUT)/bin/monkey : $(LOCAL_PATH)/monkey | $(ACP)
|
||||||
|
|||||||
129
cmds/monkey/README.NETWORK.txt
Normal file
@@ -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.
|
||||||
57
cmds/monkey/example_script.txt
Normal file
@@ -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
|
||||||
@@ -125,6 +125,9 @@ public class Monkey {
|
|||||||
/** a filename to the script (if any) **/
|
/** a filename to the script (if any) **/
|
||||||
private String mScriptFileName = null;
|
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 static final File TOMBSTONES_PATH = new File("/data/tombstones");
|
||||||
private HashSet<String> mTombstones = null;
|
private HashSet<String> mTombstones = null;
|
||||||
|
|
||||||
@@ -132,6 +135,10 @@ public class Monkey {
|
|||||||
MonkeyEventSource mEventSource;
|
MonkeyEventSource mEventSource;
|
||||||
private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
|
private MonkeyNetworkMonitor mNetworkMonitor = new MonkeyNetworkMonitor();
|
||||||
|
|
||||||
|
// information on the current activity.
|
||||||
|
public static Intent currentIntent;
|
||||||
|
public static String currentPackage;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Monitor operations happening in the system.
|
* Monitor operations happening in the system.
|
||||||
*/
|
*/
|
||||||
@@ -142,6 +149,8 @@ public class Monkey {
|
|||||||
System.out.println(" // " + (allow ? "Allowing" : "Rejecting")
|
System.out.println(" // " + (allow ? "Allowing" : "Rejecting")
|
||||||
+ " start of " + intent + " in package " + pkg);
|
+ " start of " + intent + " in package " + pkg);
|
||||||
}
|
}
|
||||||
|
currentPackage = pkg;
|
||||||
|
currentIntent = intent;
|
||||||
return allow;
|
return allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +163,7 @@ public class Monkey {
|
|||||||
+ " resume of package " + pkg);
|
+ " resume of package " + pkg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
currentPackage = pkg;
|
||||||
return allow;
|
return allow;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -365,6 +375,14 @@ public class Monkey {
|
|||||||
// script mode, ignore other options
|
// script mode, ignore other options
|
||||||
mEventSource = new MonkeySourceScript(mScriptFileName, mThrottle);
|
mEventSource = new MonkeySourceScript(mScriptFileName, mThrottle);
|
||||||
mEventSource.setVerbose(mVerbose);
|
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 {
|
} else {
|
||||||
// random source by default
|
// random source by default
|
||||||
if (mVerbose >= 2) { // check seeding performance
|
if (mVerbose >= 2) { // check seeding performance
|
||||||
@@ -527,6 +545,8 @@ public class Monkey {
|
|||||||
// do nothing - it's caught at the very start of run()
|
// do nothing - it's caught at the very start of run()
|
||||||
} else if (opt.equals("--dbg-no-events")) {
|
} else if (opt.equals("--dbg-no-events")) {
|
||||||
mSendNoEvents = true;
|
mSendNoEvents = true;
|
||||||
|
} else if (opt.equals("--port")) {
|
||||||
|
mServerPort = (int) nextOptionLong("Server port to listen on for commands");
|
||||||
} else if (opt.equals("-f")) {
|
} else if (opt.equals("-f")) {
|
||||||
mScriptFileName = nextOptionData();
|
mScriptFileName = nextOptionData();
|
||||||
} else if (opt.equals("-h")) {
|
} else if (opt.equals("-h")) {
|
||||||
@@ -544,6 +564,9 @@ public class Monkey {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If a server port hasn't been specified, we need to specify
|
||||||
|
// a count
|
||||||
|
if (mServerPort == -1) {
|
||||||
String countStr = nextArg();
|
String countStr = nextArg();
|
||||||
if (countStr == null) {
|
if (countStr == null) {
|
||||||
System.err.println("** Error: Count not specified");
|
System.err.println("** Error: Count not specified");
|
||||||
@@ -558,6 +581,7 @@ public class Monkey {
|
|||||||
showUsage();
|
showUsage();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -749,9 +773,11 @@ public class Monkey {
|
|||||||
} else if (injectCode == MonkeyEvent.INJECT_ERROR_SECURITY_EXCEPTION) {
|
} else if (injectCode == MonkeyEvent.INJECT_ERROR_SECURITY_EXCEPTION) {
|
||||||
systemCrashed = !mIgnoreSecurityExceptions;
|
systemCrashed = !mIgnoreSecurityExceptions;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Event Source has signaled that we have no more events to process
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got this far, we succeeded!
|
// If we got this far, we succeeded!
|
||||||
return mCount;
|
return mCount;
|
||||||
}
|
}
|
||||||
@@ -904,6 +930,7 @@ public class Monkey {
|
|||||||
System.err.println(" [--pct-appswitch PERCENT] [--pct-flip PERCENT]");
|
System.err.println(" [--pct-appswitch PERCENT] [--pct-flip PERCENT]");
|
||||||
System.err.println(" [--pct-anyevent PERCENT]");
|
System.err.println(" [--pct-anyevent PERCENT]");
|
||||||
System.err.println(" [--wait-dbg] [--dbg-no-events] [-f scriptfile]");
|
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(" [-s SEED] [-v [-v] ...] [--throttle MILLISEC]");
|
||||||
System.err.println(" COUNT");
|
System.err.println(" COUNT");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ public abstract class MonkeyEvent {
|
|||||||
public static final int EVENT_TYPE_ACTIVITY = 3;
|
public static final int EVENT_TYPE_ACTIVITY = 3;
|
||||||
public static final int EVENT_TYPE_FLIP = 4; // Keyboard flip
|
public static final int EVENT_TYPE_FLIP = 4; // Keyboard flip
|
||||||
public static final int EVENT_TYPE_THROTTLE = 5;
|
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_SUCCESS = 1;
|
||||||
public static final int INJECT_FAIL = 0;
|
public static final int INJECT_FAIL = 0;
|
||||||
|
|||||||
@@ -33,12 +33,19 @@ public class MonkeyKeyEvent extends MonkeyEvent {
|
|||||||
private int mDeviceId = -1;
|
private int mDeviceId = -1;
|
||||||
private long mEventTime = -1;
|
private long mEventTime = -1;
|
||||||
|
|
||||||
|
private KeyEvent keyEvent = null;
|
||||||
|
|
||||||
public MonkeyKeyEvent(int action, int keycode) {
|
public MonkeyKeyEvent(int action, int keycode) {
|
||||||
super(EVENT_TYPE_KEY);
|
super(EVENT_TYPE_KEY);
|
||||||
mAction = action;
|
mAction = action;
|
||||||
mKeyCode = keycode;
|
mKeyCode = keycode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MonkeyKeyEvent(KeyEvent e) {
|
||||||
|
super(EVENT_TYPE_KEY);
|
||||||
|
keyEvent = e;
|
||||||
|
}
|
||||||
|
|
||||||
public MonkeyKeyEvent(long downTime, long eventTime, int action,
|
public MonkeyKeyEvent(long downTime, long eventTime, int action,
|
||||||
int code, int repeat, int metaState,
|
int code, int repeat, int metaState,
|
||||||
int device, int scancode) {
|
int device, int scancode) {
|
||||||
@@ -82,14 +89,17 @@ public class MonkeyKeyEvent extends MonkeyEvent {
|
|||||||
* @return the key event
|
* @return the key event
|
||||||
*/
|
*/
|
||||||
private KeyEvent getEvent() {
|
private KeyEvent getEvent() {
|
||||||
|
if (keyEvent == null) {
|
||||||
if (mDeviceId < 0) {
|
if (mDeviceId < 0) {
|
||||||
return new KeyEvent(mAction, mKeyCode);
|
keyEvent = new KeyEvent(mAction, mKeyCode);
|
||||||
}
|
} else {
|
||||||
|
|
||||||
// for scripts
|
// for scripts
|
||||||
return new KeyEvent(mDownTime, mEventTime, mAction,
|
keyEvent = new KeyEvent(mDownTime, mEventTime, mAction,
|
||||||
mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode);
|
mKeyCode, mRepeatCount, mMetaState, mDeviceId, mScancode);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return keyEvent;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isThrottlable() {
|
public boolean isThrottlable() {
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String> 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<String, MonkeyCommand> COMMAND_MAP = new HashMap<String, MonkeyCommand>();
|
||||||
|
|
||||||
|
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<MonkeyEvent> queuedEvents = new LinkedList<MonkeyEvent>();
|
||||||
|
|
||||||
|
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<String> commandLineSplit(String line) {
|
||||||
|
ArrayList<String> result = new ArrayList<String>();
|
||||||
|
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<String> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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<String, VarGetter> VAR_MAP = new TreeMap<String, VarGetter>();
|
||||||
|
|
||||||
|
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<String> command,
|
||||||
|
CommandQueue queue) {
|
||||||
|
Set<String> 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<String> 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -55,7 +55,7 @@ public class MonkeySourceRandom implements MonkeyEventSource {
|
|||||||
/** Nice names for all key events. */
|
/** Nice names for all key events. */
|
||||||
private static final String[] KEY_NAMES = {
|
private static final String[] KEY_NAMES = {
|
||||||
"KEYCODE_UNKNOWN",
|
"KEYCODE_UNKNOWN",
|
||||||
"KEYCODE_MENU",
|
"KEYCODE_SOFT_LEFT",
|
||||||
"KEYCODE_SOFT_RIGHT",
|
"KEYCODE_SOFT_RIGHT",
|
||||||
"KEYCODE_HOME",
|
"KEYCODE_HOME",
|
||||||
"KEYCODE_BACK",
|
"KEYCODE_BACK",
|
||||||
@@ -186,6 +186,22 @@ public class MonkeySourceRandom implements MonkeyEventSource {
|
|||||||
return KEY_NAMES[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<ComponentName> MainApps, long throttle) {
|
public MonkeySourceRandom(long seed, ArrayList<ComponentName> MainApps, long throttle) {
|
||||||
// default values for random distributions
|
// default values for random distributions
|
||||||
// note, these are straight percentages, to match user input (cmd line args)
|
// note, these are straight percentages, to match user input (cmd line args)
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="refresh" content="0;url=docs/sdk/1.1_r1/index.html">
|
<meta http-equiv="refresh" content="0;url=docs/sdk/RELEASENOTES.html">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<a href="docs/sdk/1.1_r1/index.html">click here if you are not redirected</a>
|
<a href="docs/sdk/RELEASENOTES.html">click here if you are not redirected</a>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 449 B |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 4.0 KiB After Width: | Height: | Size: 795 B |
|
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 453 B |
|
Before Width: | Height: | Size: 3.5 KiB |
BIN
emulator/skins/HVGA/background_land.png
Normal file
|
After Width: | Height: | Size: 2.9 KiB |
BIN
emulator/skins/HVGA/background_port.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
emulator/skins/HVGA/button.png
Normal file
|
After Width: | Height: | Size: 592 B |
BIN
emulator/skins/HVGA/controls.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 154 B |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 20 KiB |
@@ -1,84 +1,104 @@
|
|||||||
parts {
|
parts {
|
||||||
device {
|
portrait {
|
||||||
background {
|
background {
|
||||||
image device.png
|
image background_port.png
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
landscape {
|
||||||
|
background {
|
||||||
|
image background_land.png
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
device {
|
||||||
display {
|
display {
|
||||||
width 320
|
width 320
|
||||||
height 480
|
height 480
|
||||||
x 31
|
x 0
|
||||||
y 72
|
y 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
controls {
|
||||||
|
background {
|
||||||
|
image controls.png
|
||||||
|
}
|
||||||
buttons {
|
buttons {
|
||||||
soft-left {
|
soft-left {
|
||||||
image menu.png
|
image button.png
|
||||||
x 147
|
x 56
|
||||||
y 555
|
y 142
|
||||||
}
|
}
|
||||||
home {
|
home {
|
||||||
image home.png
|
image button.png
|
||||||
x 48
|
x 0
|
||||||
y 590
|
y 142
|
||||||
}
|
}
|
||||||
back {
|
back {
|
||||||
image back.png
|
image button.png
|
||||||
x 286
|
x 112
|
||||||
y 590
|
y 142
|
||||||
}
|
}
|
||||||
dpad-up {
|
dpad-up {
|
||||||
image arrow_up.png
|
image arrow_up.png
|
||||||
x 140
|
x 77
|
||||||
y 595
|
y 53
|
||||||
}
|
}
|
||||||
dpad-down {
|
dpad-down {
|
||||||
image arrow_down.png
|
image arrow_down.png
|
||||||
x 140
|
x 77
|
||||||
y 656
|
y 106
|
||||||
}
|
}
|
||||||
dpad-left {
|
dpad-left {
|
||||||
image arrow_left.png
|
image arrow_left.png
|
||||||
x 111
|
x 53
|
||||||
y 598
|
y 53
|
||||||
}
|
}
|
||||||
dpad-right {
|
dpad-right {
|
||||||
image arrow_right.png
|
image arrow_right.png
|
||||||
x 222
|
x 123
|
||||||
y 598
|
y 53
|
||||||
}
|
}
|
||||||
dpad-center {
|
dpad-center {
|
||||||
image select.png
|
image select.png
|
||||||
x 142
|
x 77
|
||||||
y 626
|
y 81
|
||||||
}
|
}
|
||||||
phone-dial {
|
phone-dial {
|
||||||
image send.png
|
image button.png
|
||||||
x 48
|
x 0
|
||||||
y 646
|
y 71
|
||||||
}
|
}
|
||||||
phone-hangup {
|
phone-hangup {
|
||||||
image end.png
|
image button.png
|
||||||
x 286
|
x 168
|
||||||
y 646
|
y 71
|
||||||
}
|
}
|
||||||
|
|
||||||
power {
|
power {
|
||||||
image power.png
|
image button.png
|
||||||
x -38
|
x 168
|
||||||
y 52
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
volume-up {
|
volume-up {
|
||||||
image volume_up.png
|
image button.png
|
||||||
x 362
|
x 112
|
||||||
y 260
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
volume-down {
|
volume-down {
|
||||||
image volume_down.png
|
image button.png
|
||||||
x 362
|
x 56
|
||||||
y 310
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
search {
|
||||||
|
image button.png
|
||||||
|
x 168
|
||||||
|
y 142
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,242 +109,242 @@ parts {
|
|||||||
buttons {
|
buttons {
|
||||||
1 {
|
1 {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
2 {
|
2 {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
3 {
|
3 {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
4 {
|
4 {
|
||||||
image key.png
|
image key.png
|
||||||
x 111
|
x 116
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
5 {
|
5 {
|
||||||
image key.png
|
image key.png
|
||||||
x 148
|
x 153
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
6 {
|
6 {
|
||||||
image key.png
|
image key.png
|
||||||
x 185
|
x 190
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
7 {
|
7 {
|
||||||
image key.png
|
image key.png
|
||||||
x 222
|
x 227
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
8 {
|
8 {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
9 {
|
9 {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
0 {
|
0 {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
|
|
||||||
q {
|
q {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
w {
|
w {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
e {
|
e {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
r {
|
r {
|
||||||
image key.png
|
image key.png
|
||||||
x 111
|
x 116
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
t {
|
t {
|
||||||
image key.png
|
image key.png
|
||||||
x 148
|
x 153
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
y {
|
y {
|
||||||
image key.png
|
image key.png
|
||||||
x 185
|
x 190
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
u {
|
u {
|
||||||
image key.png
|
image key.png
|
||||||
x 222
|
x 227
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
i {
|
i {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
o {
|
o {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
s {
|
s {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
d {
|
d {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
f {
|
f {
|
||||||
image key.png
|
image key.png
|
||||||
x 111
|
x 116
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
g {
|
g {
|
||||||
image key.png
|
image key.png
|
||||||
x 148
|
x 153
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
h {
|
h {
|
||||||
image key.png
|
image key.png
|
||||||
x 185
|
x 190
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
j {
|
j {
|
||||||
image key.png
|
image key.png
|
||||||
x 222
|
x 227
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
k {
|
k {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
l {
|
l {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
DEL {
|
DEL {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
|
|
||||||
CAP {
|
CAP {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
z {
|
z {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
x {
|
x {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
c {
|
c {
|
||||||
image key.png
|
image key.png
|
||||||
x 111
|
x 116
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
v {
|
v {
|
||||||
image key.png
|
image key.png
|
||||||
x 148
|
x 153
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
b {
|
b {
|
||||||
image key.png
|
image key.png
|
||||||
x 185
|
x 190
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
n {
|
n {
|
||||||
image key.png
|
image key.png
|
||||||
x 222
|
x 227
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
m {
|
m {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
PERIOD {
|
PERIOD {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
ENTER {
|
ENTER {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
|
|
||||||
ALT {
|
ALT {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
SYM {
|
SYM {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
AT {
|
AT {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
SPACE {
|
SPACE {
|
||||||
image spacebar.png
|
image spacebar.png
|
||||||
x 111
|
x 116
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
SLASH {
|
SLASH {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
COMMA {
|
COMMA {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
ALT2 {
|
ALT2 {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -333,39 +353,76 @@ parts {
|
|||||||
|
|
||||||
layouts {
|
layouts {
|
||||||
portrait {
|
portrait {
|
||||||
width 900
|
width 791
|
||||||
height 730
|
height 534
|
||||||
color 0xe0e0e0
|
color 0xe0e0e0
|
||||||
event EV_SW:0:1
|
event EV_SW:0:1
|
||||||
|
|
||||||
part1 {
|
part1 {
|
||||||
name device
|
name portrait
|
||||||
x 40
|
x 0
|
||||||
y -18
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
part2 {
|
part2 {
|
||||||
name keyboard
|
name landscape
|
||||||
x 480
|
x 800
|
||||||
y 200
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
part3 {
|
||||||
|
name device
|
||||||
|
x 28
|
||||||
|
y 27
|
||||||
|
}
|
||||||
|
part4 {
|
||||||
|
name controls
|
||||||
|
x 476
|
||||||
|
y 77
|
||||||
|
}
|
||||||
|
part5 {
|
||||||
|
name keyboard
|
||||||
|
x 395
|
||||||
|
y 328
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
landscape {
|
landscape {
|
||||||
width 900
|
width 640
|
||||||
height 670
|
height 601
|
||||||
color 0xe0e0e0
|
color 0xe0e0e0
|
||||||
event EV_SW:0:0
|
event EV_SW:0:0
|
||||||
|
|
||||||
part1 {
|
part1 {
|
||||||
|
name portrait
|
||||||
|
x 800
|
||||||
|
y 0
|
||||||
|
}
|
||||||
|
|
||||||
|
part2 {
|
||||||
|
name landscape
|
||||||
|
x 0
|
||||||
|
y 0
|
||||||
|
}
|
||||||
|
|
||||||
|
part3 {
|
||||||
name device
|
name device
|
||||||
x 50
|
x 80
|
||||||
y 440
|
y 349
|
||||||
rotation 3
|
rotation 3
|
||||||
}
|
}
|
||||||
part2 {
|
|
||||||
|
part4 {
|
||||||
|
name controls
|
||||||
|
x 410
|
||||||
|
y 396
|
||||||
|
}
|
||||||
|
|
||||||
|
part5 {
|
||||||
name keyboard
|
name keyboard
|
||||||
x 250
|
x 18
|
||||||
y 470
|
y 396
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 384 B |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 3.8 KiB |
BIN
emulator/skins/QVGA/.DS_Store
vendored
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 449 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 825 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 795 B |
|
Before Width: | Height: | Size: 3.3 KiB After Width: | Height: | Size: 453 B |
|
Before Width: | Height: | Size: 3.0 KiB |
BIN
emulator/skins/QVGA/background_land.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
emulator/skins/QVGA/background_port.png
Normal file
|
After Width: | Height: | Size: 2.5 KiB |
BIN
emulator/skins/QVGA/button.png
Normal file
|
After Width: | Height: | Size: 592 B |
BIN
emulator/skins/QVGA/controls.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
|
Before Width: | Height: | Size: 50 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 154 B |
|
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 20 KiB |
@@ -1,84 +1,104 @@
|
|||||||
parts {
|
parts {
|
||||||
device {
|
portrait {
|
||||||
background {
|
background {
|
||||||
image device.png
|
image background_port.png
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
landscape {
|
||||||
|
background {
|
||||||
|
image background_land.png
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
device {
|
||||||
display {
|
display {
|
||||||
width 240
|
width 240
|
||||||
height 320
|
height 320
|
||||||
x 33
|
x 0
|
||||||
y 69
|
y 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
controls {
|
||||||
|
background {
|
||||||
|
image controls.png
|
||||||
|
}
|
||||||
buttons {
|
buttons {
|
||||||
soft-left {
|
soft-left {
|
||||||
image menu.png
|
image button.png
|
||||||
x 131
|
x 56
|
||||||
y 404
|
y 142
|
||||||
}
|
}
|
||||||
home {
|
home {
|
||||||
image home.png
|
image button.png
|
||||||
x 77
|
x 0
|
||||||
y 404
|
y 142
|
||||||
}
|
}
|
||||||
back {
|
back {
|
||||||
image back.png
|
image button.png
|
||||||
x 185
|
x 112
|
||||||
y 404
|
y 142
|
||||||
}
|
}
|
||||||
dpad-up {
|
dpad-up {
|
||||||
image arrow_up.png
|
image arrow_up.png
|
||||||
x 105
|
x 77
|
||||||
y 463
|
y 53
|
||||||
}
|
}
|
||||||
dpad-down {
|
dpad-down {
|
||||||
image arrow_down.png
|
image arrow_down.png
|
||||||
x 104
|
x 77
|
||||||
y 519
|
y 106
|
||||||
}
|
}
|
||||||
dpad-left {
|
dpad-left {
|
||||||
image arrow_left.png
|
image arrow_left.png
|
||||||
x 96
|
x 53
|
||||||
y 470
|
y 53
|
||||||
}
|
}
|
||||||
dpad-right {
|
dpad-right {
|
||||||
image arrow_right.png
|
image arrow_right.png
|
||||||
x 172
|
x 123
|
||||||
y 470
|
y 53
|
||||||
}
|
}
|
||||||
dpad-center {
|
dpad-center {
|
||||||
image select.png
|
image select.png
|
||||||
x 131
|
x 77
|
||||||
y 492
|
y 81
|
||||||
}
|
}
|
||||||
phone-dial {
|
phone-dial {
|
||||||
image send.png
|
image button.png
|
||||||
x 23
|
x 0
|
||||||
y 404
|
y 71
|
||||||
}
|
}
|
||||||
phone-hangup {
|
phone-hangup {
|
||||||
image end.png
|
image button.png
|
||||||
x 238
|
x 168
|
||||||
y 404
|
y 71
|
||||||
}
|
}
|
||||||
|
|
||||||
power {
|
power {
|
||||||
image power.png
|
image button.png
|
||||||
x -16
|
x 168
|
||||||
y 0
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
volume-up {
|
volume-up {
|
||||||
image volume_up.png
|
image button.png
|
||||||
x 289
|
x 112
|
||||||
y 177
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
volume-down {
|
volume-down {
|
||||||
image volume_down.png
|
image button.png
|
||||||
x 289
|
x 56
|
||||||
y 233
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
search {
|
||||||
|
image button.png
|
||||||
|
x 168
|
||||||
|
y 142
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -89,242 +109,242 @@ parts {
|
|||||||
buttons {
|
buttons {
|
||||||
1 {
|
1 {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
2 {
|
2 {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
3 {
|
3 {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
4 {
|
4 {
|
||||||
image key.png
|
image key.png
|
||||||
x 111
|
x 116
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
5 {
|
5 {
|
||||||
image key.png
|
image key.png
|
||||||
x 148
|
x 153
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
6 {
|
6 {
|
||||||
image key.png
|
image key.png
|
||||||
x 185
|
x 190
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
7 {
|
7 {
|
||||||
image key.png
|
image key.png
|
||||||
x 222
|
x 227
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
8 {
|
8 {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
9 {
|
9 {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
0 {
|
0 {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 0
|
y 5
|
||||||
}
|
}
|
||||||
|
|
||||||
q {
|
q {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
w {
|
w {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
e {
|
e {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
r {
|
r {
|
||||||
image key.png
|
image key.png
|
||||||
x 111
|
x 116
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
t {
|
t {
|
||||||
image key.png
|
image key.png
|
||||||
x 148
|
x 153
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
y {
|
y {
|
||||||
image key.png
|
image key.png
|
||||||
x 185
|
x 190
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
u {
|
u {
|
||||||
image key.png
|
image key.png
|
||||||
x 222
|
x 227
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
i {
|
i {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
o {
|
o {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
p {
|
p {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 36
|
y 41
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
s {
|
s {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
d {
|
d {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
f {
|
f {
|
||||||
image key.png
|
image key.png
|
||||||
x 111
|
x 116
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
g {
|
g {
|
||||||
image key.png
|
image key.png
|
||||||
x 148
|
x 153
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
h {
|
h {
|
||||||
image key.png
|
image key.png
|
||||||
x 185
|
x 190
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
j {
|
j {
|
||||||
image key.png
|
image key.png
|
||||||
x 222
|
x 227
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
k {
|
k {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
l {
|
l {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
DEL {
|
DEL {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 72
|
y 77
|
||||||
}
|
}
|
||||||
|
|
||||||
CAP {
|
CAP {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
z {
|
z {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
x {
|
x {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
c {
|
c {
|
||||||
image key.png
|
image key.png
|
||||||
x 111
|
x 116
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
v {
|
v {
|
||||||
image key.png
|
image key.png
|
||||||
x 148
|
x 153
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
b {
|
b {
|
||||||
image key.png
|
image key.png
|
||||||
x 185
|
x 190
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
n {
|
n {
|
||||||
image key.png
|
image key.png
|
||||||
x 222
|
x 227
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
m {
|
m {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
PERIOD {
|
PERIOD {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
ENTER {
|
ENTER {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 108
|
y 113
|
||||||
}
|
}
|
||||||
|
|
||||||
ALT {
|
ALT {
|
||||||
image key.png
|
image key.png
|
||||||
x 0
|
x 5
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
SYM {
|
SYM {
|
||||||
image key.png
|
image key.png
|
||||||
x 37
|
x 42
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
AT {
|
AT {
|
||||||
image key.png
|
image key.png
|
||||||
x 74
|
x 79
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
SPACE {
|
SPACE {
|
||||||
image spacebar.png
|
image spacebar.png
|
||||||
x 111
|
x 116
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
SLASH {
|
SLASH {
|
||||||
image key.png
|
image key.png
|
||||||
x 259
|
x 264
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
COMMA {
|
COMMA {
|
||||||
image key.png
|
image key.png
|
||||||
x 296
|
x 301
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
ALT2 {
|
ALT2 {
|
||||||
image key.png
|
image key.png
|
||||||
x 333
|
x 338
|
||||||
y 144
|
y 149
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -333,39 +353,75 @@ parts {
|
|||||||
|
|
||||||
layouts {
|
layouts {
|
||||||
portrait {
|
portrait {
|
||||||
width 750
|
width 711
|
||||||
height 610
|
height 435
|
||||||
color 0xe0e0e0
|
color 0xe0e0e0
|
||||||
event EV_SW:0:1
|
event EV_SW:0:1
|
||||||
|
|
||||||
part1 {
|
part1 {
|
||||||
name device
|
name portrait
|
||||||
x 30
|
x 0
|
||||||
y 097
|
y 0
|
||||||
}
|
}
|
||||||
|
|
||||||
part2 {
|
part2 {
|
||||||
|
name landscape
|
||||||
|
x 800
|
||||||
|
y 0
|
||||||
|
}
|
||||||
|
|
||||||
|
part3 {
|
||||||
|
name device
|
||||||
|
x 28
|
||||||
|
y 58
|
||||||
|
}
|
||||||
|
part4 {
|
||||||
|
name controls
|
||||||
|
x 396
|
||||||
|
y 27
|
||||||
|
}
|
||||||
|
part5 {
|
||||||
name keyboard
|
name keyboard
|
||||||
x 360
|
x 315
|
||||||
y 300
|
y 229
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
landscape {
|
landscape {
|
||||||
width 645
|
width 640
|
||||||
height 575
|
height 522
|
||||||
color 0xe0e0e0
|
color 0xe0e0e0
|
||||||
event EV_SW:0:0
|
event EV_SW:0:0
|
||||||
|
|
||||||
part1 {
|
part1 {
|
||||||
|
name portrait
|
||||||
|
x 800
|
||||||
|
y 0
|
||||||
|
}
|
||||||
|
|
||||||
|
part2 {
|
||||||
|
name landscape
|
||||||
|
x 0
|
||||||
|
y 0
|
||||||
|
}
|
||||||
|
|
||||||
|
part3 {
|
||||||
name device
|
name device
|
||||||
x 10
|
x 160
|
||||||
y 360
|
y 270
|
||||||
rotation 3
|
rotation 3
|
||||||
}
|
}
|
||||||
part2 {
|
|
||||||
|
part4 {
|
||||||
|
name controls
|
||||||
|
x 410
|
||||||
|
y 317
|
||||||
|
}
|
||||||
|
|
||||||
|
part5 {
|
||||||
name keyboard
|
name keyboard
|
||||||
x 135
|
x 18
|
||||||
y 380
|
y 317
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 835 B |
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 384 B |
|
Before Width: | Height: | Size: 3.0 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
BIN
emulator/skins/WQVGA432/arrow_down.png
Normal file
|
After Width: | Height: | Size: 449 B |
BIN
emulator/skins/WQVGA432/arrow_left.png
Normal file
|
After Width: | Height: | Size: 825 B |
BIN
emulator/skins/WQVGA432/arrow_right.png
Normal file
|
After Width: | Height: | Size: 795 B |
BIN
emulator/skins/WQVGA432/arrow_up.png
Normal file
|
After Width: | Height: | Size: 453 B |
BIN
emulator/skins/WQVGA432/background_land.png
Normal file
|
After Width: | Height: | Size: 2.6 KiB |
BIN
emulator/skins/WQVGA432/background_port.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
emulator/skins/WQVGA432/button.png
Normal file
|
After Width: | Height: | Size: 592 B |
BIN
emulator/skins/WQVGA432/controls.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
2
emulator/skins/WQVGA432/hardware.ini
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# skin-specific hardware values
|
||||||
|
hw.lcd.density=120
|
||||||
BIN
emulator/skins/WQVGA432/key.png
Normal file
|
After Width: | Height: | Size: 154 B |
BIN
emulator/skins/WQVGA432/keyboard.png
Normal file
|
After Width: | Height: | Size: 20 KiB |
436
emulator/skins/WQVGA432/layout
Normal file
@@ -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
|
||||||
|
}
|
||||||
BIN
emulator/skins/WQVGA432/select.png
Normal file
|
After Width: | Height: | Size: 384 B |
BIN
emulator/skins/WQVGA432/spacebar.png
Normal file
|
After Width: | Height: | Size: 192 B |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 4.0 KiB |
|
Before Width: | Height: | Size: 3.4 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |
|
Before Width: | Height: | Size: 17 KiB |
|
Before Width: | Height: | Size: 3.5 KiB |