summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Android.mk5
-rw-r--r--api/current.xml1689
-rw-r--r--camera/libcameraservice/CameraService.cpp7
-rw-r--r--camera/libcameraservice/CameraService.h2
-rw-r--r--cmds/bootanimation/Android.mk30
-rw-r--r--cmds/bootanimation/BootAnimation.cpp (renamed from libs/surfaceflinger/BootAnimation.cpp)27
-rw-r--r--cmds/bootanimation/BootAnimation.h (renamed from libs/surfaceflinger/BootAnimation.h)6
-rw-r--r--cmds/bootanimation/bootanimation_main.cpp52
-rw-r--r--cmds/dumpstate/dumpstate.c3
-rw-r--r--cmds/pm/src/com/android/commands/pm/Pm.java3
-rw-r--r--cmds/runtime/main_runtime.cpp4
-rw-r--r--core/java/android/app/SearchDialog.java95
-rw-r--r--core/java/android/app/SuggestionsAdapter.java35
-rw-r--r--core/java/android/content/pm/PackageManager.java9
-rwxr-xr-xcore/java/android/gesture/Gesture.java (renamed from tests/sketch/src/com/android/gesture/Gesture.java)208
-rw-r--r--core/java/android/gesture/GestureConstants.java (renamed from tests/sketch/src/com/android/gesture/GestureConstants.java)16
-rw-r--r--core/java/android/gesture/GestureLibrary.java346
-rwxr-xr-xcore/java/android/gesture/GestureOverlayView.java688
-rw-r--r--core/java/android/gesture/GesturePoint.java (renamed from tests/sketch/src/com/android/gesture/GesturePoint.java)14
-rw-r--r--core/java/android/gesture/GestureStroke.java (renamed from tests/sketch/src/com/android/gesture/GestureStroke.java)169
-rwxr-xr-xcore/java/android/gesture/GestureUtilities.java (renamed from tests/sketch/src/com/android/gesture/GestureUtilities.java)52
-rwxr-xr-xcore/java/android/gesture/Instance.java (renamed from tests/sketch/src/com/android/gesture/Instance.java)47
-rw-r--r--core/java/android/gesture/InstanceLearner.java (renamed from tests/sketch/src/com/android/gesture/InstanceLearner.java)34
-rwxr-xr-xcore/java/android/gesture/Learner.java (renamed from tests/sketch/src/com/android/gesture/Learner.java)4
-rw-r--r--core/java/android/gesture/LetterRecognizer.java280
-rw-r--r--core/java/android/gesture/OrientedBoundingBox.java (renamed from tests/sketch/src/com/android/gesture/OrientedBoundingBox.java)7
-rwxr-xr-xcore/java/android/gesture/Prediction.java (renamed from tests/sketch/src/com/android/gesture/Prediction.java)2
-rw-r--r--core/java/android/hardware/ISensorService.aidl4
-rw-r--r--core/java/android/hardware/SensorManager.java72
-rw-r--r--core/java/android/os/BatteryStats.java22
-rw-r--r--core/java/android/os/Build.java3
-rw-r--r--core/java/android/os/Bundle.java68
-rw-r--r--core/java/android/os/Parcel.java68
-rw-r--r--core/java/android/provider/MediaStore.java2
-rw-r--r--core/java/android/view/SurfaceView.java13
-rw-r--r--core/java/android/view/View.java31
-rw-r--r--core/java/android/view/ViewGroup.java12
-rw-r--r--core/java/android/view/Window.java6
-rw-r--r--core/java/android/view/WindowManager.java9
-rw-r--r--core/java/android/webkit/WebSettings.java4
-rw-r--r--core/java/android/widget/AbsListView.java390
-rw-r--r--core/java/android/widget/ExpandableListView.java5
-rw-r--r--core/java/android/widget/FastScroller.java40
-rw-r--r--core/java/android/widget/FrameLayout.java29
-rw-r--r--core/java/android/widget/ListView.java3
-rw-r--r--core/java/android/widget/PopupWindow.java14
-rw-r--r--core/java/android/widget/TextView.java11
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java139
-rw-r--r--core/java/com/android/internal/os/PowerProfile.java185
-rw-r--r--core/jni/android_hardware_SensorManager.cpp37
-rw-r--r--core/res/AndroidManifest.xml6
-rw-r--r--core/res/res/drawable/search_spinner.xml36
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim1.pngbin0 -> 523 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim10.pngbin0 -> 529 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim11.pngbin0 -> 525 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim12.pngbin0 -> 527 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim2.pngbin0 -> 525 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim3.pngbin0 -> 522 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim4.pngbin0 -> 519 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim5.pngbin0 -> 521 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim6.pngbin0 -> 509 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim7.pngbin0 -> 517 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim8.pngbin0 -> 533 bytes
-rwxr-xr-xcore/res/res/drawable/search_spinner_anim9.pngbin0 -> 534 bytes
-rw-r--r--core/res/res/layout/google_web_content_helper_layout.xml26
-rw-r--r--core/res/res/layout/list_gestures_overlay.xml19
-rw-r--r--core/res/res/layout/search_bar.xml1
-rw-r--r--core/res/res/layout/search_dropdown_item_icons_2line.xml9
-rw-r--r--core/res/res/raw/latin_lowercasebin36186 -> 28496 bytes
-rw-r--r--core/res/res/values-ja/donottranslate.xml23
-rw-r--r--core/res/res/values/attrs.xml55
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/donottranslate.xml23
-rw-r--r--core/res/res/values/public.xml14
-rw-r--r--core/res/res/values/strings.xml8
-rw-r--r--core/res/res/values/styles.xml17
-rw-r--r--core/res/res/values/themes.xml4
-rw-r--r--core/res/res/xml/power_profile_default.xml36
-rw-r--r--data/etc/platform.xml3
-rwxr-xr-xdata/fonts/DroidSansJapanese.ttfbin1174432 -> 1173140 bytes
-rw-r--r--docs/html/guide/appendix/media-formats.jd29
-rw-r--r--docs/html/guide/developing/eclipse-adt.jd12
-rw-r--r--docs/html/index.jd6
-rw-r--r--docs/html/sdk/1.5_r2/index.jd87
-rw-r--r--docs/html/sdk/1.5_r2/installing.jd332
-rw-r--r--docs/html/sdk/1.5_r2/requirements.jd39
-rw-r--r--docs/html/sdk/1.5_r2/upgrading.jd395
-rw-r--r--docs/html/sdk/RELEASENOTES.jd12
-rw-r--r--docs/html/sdk/android-1.5-highlights.jd1
-rw-r--r--docs/html/sdk/older_releases.jd107
-rw-r--r--docs/html/sdk/preview/features.html21
-rw-r--r--docs/html/sdk/sdk_toc.cs9
-rw-r--r--include/tts/TtsEngine.h167
-rw-r--r--libs/surfaceflinger/Android.mk1
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp30
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.h3
-rw-r--r--libs/surfaceflinger/VRamHeap.cpp2
-rw-r--r--libs/ui/ISurfaceFlingerClient.cpp13
-rw-r--r--libs/utils/Parcel.cpp8
-rw-r--r--libs/utils/backup_helper_file.cpp37
-rw-r--r--libs/utils/futex_synchro.c1
-rw-r--r--location/java/android/location/ILocationCollector.aidl36
-rw-r--r--location/java/android/location/ILocationManager.aidl2
-rw-r--r--location/java/android/location/ILocationProvider.aidl2
-rw-r--r--location/java/android/location/LocationManager.java21
-rw-r--r--location/java/com/android/internal/location/GpsLocationProvider.java7
-rw-r--r--location/java/com/android/internal/location/LocationProviderProxy.java8
-rw-r--r--location/java/com/android/internal/location/MockProvider.java3
-rw-r--r--media/libmediaplayerservice/MediaRecorderClient.cpp4
-rw-r--r--services/java/com/android/server/LocationManagerService.java37
-rw-r--r--services/java/com/android/server/PackageManagerService.java47
-rw-r--r--services/java/com/android/server/SensorService.java6
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java28
-rw-r--r--services/jni/com_android_server_SensorService.cpp77
-rw-r--r--telephony/java/com/android/internal/telephony/SmsHeader.java15
-rw-r--r--telephony/java/com/android/internal/telephony/TelephonyEventLog.java2
-rw-r--r--telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java30
-rw-r--r--test-runner/android/test/TestLocationProvider.java3
-rw-r--r--tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java37
-rw-r--r--tests/DumpRenderTree/AndroidManifest.xml3
-rwxr-xr-xtests/sketch/AndroidManifest.xml25
-rwxr-xr-xtests/sketch/res/layout/demo.xml7
-rwxr-xr-xtests/sketch/res/layout/gestureviewer.xml6
-rw-r--r--tests/sketch/res/layout/overlaydemo.xml33
-rw-r--r--tests/sketch/src/com/android/gesture/GestureLibrary.java344
-rwxr-xr-xtests/sketch/src/com/android/gesture/GestureListener.java30
-rwxr-xr-xtests/sketch/src/com/android/gesture/GestureOverlay.java390
-rw-r--r--tests/sketch/src/com/android/gesture/LetterRecognizer.java180
-rw-r--r--tests/sketch/src/com/android/gesture/TouchThroughGesturing.java165
-rw-r--r--tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java55
-rw-r--r--tests/sketch/src/com/android/gesture/example/GestureEntry.java41
-rwxr-xr-xtests/sketch/src/com/android/gesture/example/GestureLibViewer.java20
-rw-r--r--tests/sketch/tools/Converter.java11
-rwxr-xr-xtts/java/android/tts/ITts.aidl59
-rwxr-xr-x[-rw-r--r--]tts/java/android/tts/ITtsCallback.aidl (renamed from tests/sketch/src/com/android/gesture/GestureActionListener.java)14
135 files changed, 6223 insertions, 2122 deletions
diff --git a/Android.mk b/Android.mk
index bbda5fb..4df6f8e 100644
--- a/Android.mk
+++ b/Android.mk
@@ -135,7 +135,6 @@ LOCAL_SRC_FILES += \
location/java/android/location/IGeocodeProvider.aidl \
location/java/android/location/IGpsStatusListener.aidl \
location/java/android/location/IGpsStatusProvider.aidl \
- location/java/android/location/ILocationCollector.aidl \
location/java/android/location/ILocationListener.aidl \
location/java/android/location/ILocationManager.aidl \
location/java/android/location/ILocationProvider.aidl \
@@ -148,6 +147,8 @@ LOCAL_SRC_FILES += \
telephony/java/com/android/internal/telephony/ITelephonyRegistry.aidl \
telephony/java/com/android/internal/telephony/IIccPhoneBook.aidl \
telephony/java/com/android/internal/telephony/ISms.aidl \
+ tts/java/android/tts/ITtsCallback.aidl \
+ tts/java/android/tts/ITts.aidl \
wifi/java/android/net/wifi/IWifiManager.aidl \
telephony/java/com/android/internal/telephony/IExtendedNetworkService.aidl
@@ -341,7 +342,7 @@ web_docs_sample_code_flags := \
# most current Android platform version included in the SDK package.
framework_docs_SDK_VERSION := 1.5
# release version for SDK (ie "Release x")
-framework_docs_SDK_REL_ID := 1
+framework_docs_SDK_REL_ID := 2
framework_docs_SDK_CURRENT_DIR := $(framework_docs_SDK_VERSION)_r$(framework_docs_SDK_REL_ID)
framework_docs_LOCAL_DROIDDOC_OPTIONS += \
diff --git a/api/current.xml b/api/current.xml
index e1c84ec..bb1f871 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -529,17 +529,6 @@
visibility="public"
>
</field>
-<field name="INSTALL_LOCATION_COLLECTOR"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value="&quot;android.permission.INSTALL_LOCATION_COLLECTOR&quot;"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="INSTALL_LOCATION_PROVIDER"
type="java.lang.String"
transient="false"
@@ -3529,83 +3518,6 @@
visibility="public"
>
</field>
-<field name="donut_resource_pad33"
- type="int"
- transient="false"
- volatile="false"
- value="16843391"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad34"
- type="int"
- transient="false"
- volatile="false"
- value="16843390"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad35"
- type="int"
- transient="false"
- volatile="false"
- value="16843389"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad36"
- type="int"
- transient="false"
- volatile="false"
- value="16843388"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad37"
- type="int"
- transient="false"
- volatile="false"
- value="16843387"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad38"
- type="int"
- transient="false"
- volatile="false"
- value="16843386"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad39"
- type="int"
- transient="false"
- volatile="false"
- value="16843385"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="donut_resource_pad4"
type="int"
transient="false"
@@ -3617,61 +3529,6 @@
visibility="public"
>
</field>
-<field name="donut_resource_pad40"
- type="int"
- transient="false"
- volatile="false"
- value="16843384"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad41"
- type="int"
- transient="false"
- volatile="false"
- value="16843383"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad42"
- type="int"
- transient="false"
- volatile="false"
- value="16843382"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad43"
- type="int"
- transient="false"
- volatile="false"
- value="16843381"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="donut_resource_pad44"
- type="int"
- transient="false"
- volatile="false"
- value="16843380"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="donut_resource_pad5"
type="int"
transient="false"
@@ -4024,6 +3881,17 @@
visibility="public"
>
</field>
+<field name="eventsInterceptionEnabled"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843390"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="excludeFromRecents"
type="int"
transient="false"
@@ -4145,6 +4013,39 @@
visibility="public"
>
</field>
+<field name="fadeDuration"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843384"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="fadeEnabled"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843391"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="fadeOffset"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843383"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="fadingEdge"
type="int"
transient="false"
@@ -4464,6 +4365,83 @@
visibility="public"
>
</field>
+<field name="gestureColor"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843381"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestureStrokeAngleThreshold"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843389"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestureStrokeLengthThreshold"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843387"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestureStrokeSquarenessThreshold"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843388"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestureStrokeType"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843386"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestureStrokeWidth"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843380"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="gestures"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843385"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="gradientRadius"
type="int"
transient="false"
@@ -8864,6 +8842,17 @@
visibility="public"
>
</field>
+<field name="uncertainGestureColor"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843382"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="unselectedAlpha"
type="int"
transient="false"
@@ -46175,6 +46164,1338 @@
</method>
</class>
</package>
+<package name="android.gesture"
+>
+<class name="Gesture"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.os.Parcelable">
+</implements>
+<constructor name="Gesture"
+ type="android.gesture.Gesture"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="addStroke"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="stroke" type="android.gesture.GestureStroke">
+</parameter>
+</method>
+<method name="describeContents"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getBoundingBox"
+ return="android.graphics.RectF"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getID"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getLength"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStrokes"
+ return="java.util.ArrayList&lt;android.gesture.GestureStroke&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getStrokesCount"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="toBitmap"
+ return="android.graphics.Bitmap"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+<parameter name="edge" type="int">
+</parameter>
+<parameter name="numSample" type="int">
+</parameter>
+<parameter name="color" type="int">
+</parameter>
+</method>
+<method name="toBitmap"
+ return="android.graphics.Bitmap"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+<parameter name="edge" type="int">
+</parameter>
+<parameter name="color" type="int">
+</parameter>
+</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="path" type="android.graphics.Path">
+</parameter>
+</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+<parameter name="edge" type="int">
+</parameter>
+<parameter name="numSample" type="int">
+</parameter>
+</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="path" type="android.graphics.Path">
+</parameter>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+<parameter name="edge" type="int">
+</parameter>
+<parameter name="numSample" type="int">
+</parameter>
+</method>
+<method name="writeToParcel"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="out" type="android.os.Parcel">
+</parameter>
+<parameter name="flags" type="int">
+</parameter>
+</method>
+<field name="CREATOR"
+ type="android.os.Parcelable.Creator"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="GestureLibrary"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="GestureLibrary"
+ type="android.gesture.GestureLibrary"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="path" type="java.lang.String">
+</parameter>
+</constructor>
+<method name="addGesture"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="entryName" type="java.lang.String">
+</parameter>
+<parameter name="gesture" type="android.gesture.Gesture">
+</parameter>
+</method>
+<method name="getGestureEntries"
+ return="java.util.Set&lt;java.lang.String&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestures"
+ return="java.util.ArrayList&lt;android.gesture.Gesture&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="entryName" type="java.lang.String">
+</parameter>
+</method>
+<method name="getOrientationStyle"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getSequenceType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="load"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="recognize"
+ return="java.util.ArrayList&lt;android.gesture.Prediction&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gesture" type="android.gesture.Gesture">
+</parameter>
+</method>
+<method name="removeEntry"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="entryName" type="java.lang.String">
+</parameter>
+</method>
+<method name="removeGesture"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="entryName" type="java.lang.String">
+</parameter>
+<parameter name="gesture" type="android.gesture.Gesture">
+</parameter>
+</method>
+<method name="save"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="setOrientationStyle"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="style" type="int">
+</parameter>
+</method>
+<method name="setSequenceType"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="type" type="int">
+</parameter>
+</method>
+<field name="ORIENTATION_INVARIANT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ORIENTATION_SENSITIVE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SEQUENCE_INVARIANT"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SEQUENCE_SENSITIVE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="GestureOverlayView"
+ extends="android.widget.FrameLayout"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="GestureOverlayView"
+ type="android.gesture.GestureOverlayView"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+</constructor>
+<constructor name="GestureOverlayView"
+ type="android.gesture.GestureOverlayView"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+</constructor>
+<constructor name="GestureOverlayView"
+ type="android.gesture.GestureOverlayView"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="attrs" type="android.util.AttributeSet">
+</parameter>
+<parameter name="defStyle" type="int">
+</parameter>
+</constructor>
+<method name="addOnGestureListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.gesture.GestureOverlayView.OnGestureListener">
+</parameter>
+</method>
+<method name="addOnGesturePerformedListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.gesture.GestureOverlayView.OnGesturePerformedListener">
+</parameter>
+</method>
+<method name="cancelClearAnimation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="cancelGesture"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="clear"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="animated" type="boolean">
+</parameter>
+</method>
+<method name="getCurrentStroke"
+ return="java.util.ArrayList&lt;android.gesture.GesturePoint&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGesture"
+ return="android.gesture.Gesture"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureColor"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeAngleThreshold"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeLengthThreshold"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeSquarenessTreshold"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeType"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStrokeWidth"
+ return="float"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getOrientation"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUncertainGestureColor"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isEventsInterceptionEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isFadeEnabled"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="isGesturing"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="removeAllOnGestureListeners"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="removeAllOnGesturePerformedListeners"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="removeOnGestureListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.gesture.GestureOverlayView.OnGestureListener">
+</parameter>
+</method>
+<method name="removeOnGesturePerformedListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.gesture.GestureOverlayView.OnGesturePerformedListener">
+</parameter>
+</method>
+<method name="setEventsInterceptionEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="enabled" type="boolean">
+</parameter>
+</method>
+<method name="setFadeEnabled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fadeEnabled" type="boolean">
+</parameter>
+</method>
+<method name="setGesture"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gesture" type="android.gesture.Gesture">
+</parameter>
+</method>
+<method name="setGestureColor"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="color" type="int">
+</parameter>
+</method>
+<method name="setGestureStrokeAngleThreshold"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStrokeAngleThreshold" type="float">
+</parameter>
+</method>
+<method name="setGestureStrokeLengthThreshold"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStrokeLengthThreshold" type="float">
+</parameter>
+</method>
+<method name="setGestureStrokeSquarenessTreshold"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStrokeSquarenessTreshold" type="float">
+</parameter>
+</method>
+<method name="setGestureStrokeType"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStrokeType" type="int">
+</parameter>
+</method>
+<method name="setGestureStrokeWidth"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStrokeWidth" type="float">
+</parameter>
+</method>
+<method name="setOrientation"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="orientation" type="int">
+</parameter>
+</method>
+<method name="setUncertainGestureColor"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="color" type="int">
+</parameter>
+</method>
+<field name="GESTURE_STROKE_TYPE_MULTIPLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="GESTURE_STROKE_TYPE_SINGLE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ORIENTATION_HORIZONTAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="ORIENTATION_VERTICAL"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="GestureOverlayView.OnGestureListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onGesture"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="overlay" type="android.gesture.GestureOverlayView">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+<method name="onGestureCancelled"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="overlay" type="android.gesture.GestureOverlayView">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+<method name="onGestureEnded"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="overlay" type="android.gesture.GestureOverlayView">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+<method name="onGestureStarted"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="overlay" type="android.gesture.GestureOverlayView">
+</parameter>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+</interface>
+<interface name="GestureOverlayView.OnGesturePerformedListener"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="onGesturePerformed"
+ return="void"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="overlay" type="android.gesture.GestureOverlayView">
+</parameter>
+<parameter name="gesture" type="android.gesture.Gesture">
+</parameter>
+</method>
+</interface>
+<class name="GesturePoint"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="GesturePoint"
+ type="android.gesture.GesturePoint"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="x" type="float">
+</parameter>
+<parameter name="y" type="float">
+</parameter>
+<parameter name="t" type="long">
+</parameter>
+</constructor>
+<field name="timestamp"
+ type="long"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="x"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="y"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="GestureStroke"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="GestureStroke"
+ type="android.gesture.GestureStroke"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="points" type="java.util.ArrayList&lt;android.gesture.GesturePoint&gt;">
+</parameter>
+</constructor>
+<method name="clearPath"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="computeOrientedBoundingBox"
+ return="android.gesture.OrientedBoundingBox"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="toPath"
+ return="android.graphics.Path"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="width" type="float">
+</parameter>
+<parameter name="height" type="float">
+</parameter>
+<parameter name="numSample" type="int">
+</parameter>
+</method>
+<field name="boundingBox"
+ type="android.graphics.RectF"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="length"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="points"
+ type="float[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="LetterRecognizer"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getLetterRecognizer"
+ return="android.gesture.LetterRecognizer"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="context" type="android.content.Context">
+</parameter>
+<parameter name="type" type="int">
+</parameter>
+</method>
+<method name="recognize"
+ return="java.util.ArrayList&lt;android.gesture.Prediction&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gesture" type="android.gesture.Gesture">
+</parameter>
+</method>
+<method name="recognize"
+ return="java.util.ArrayList&lt;android.gesture.Prediction&gt;"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gesture" type="android.gesture.Gesture">
+</parameter>
+<parameter name="predictions" type="java.util.ArrayList&lt;android.gesture.Prediction&gt;">
+</parameter>
+</method>
+<field name="RECOGNIZER_LATIN_LOWERCASE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="OrientedBoundingBox"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<field name="centerX"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="centerY"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="height"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="orientation"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="squareness"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="width"
+ type="float"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<class name="Prediction"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<field name="name"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="score"
+ type="double"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+</package>
<package name="android.graphics"
>
<class name="AvoidXfermode"
@@ -88656,6 +89977,16 @@
visibility="public"
>
</field>
+<field name="CPU_ABI"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="DEVICE"
type="java.lang.String"
transient="false"
@@ -158386,6 +159717,17 @@
visibility="public"
>
</method>
+<method name="getGestures"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getListPaddingBottom"
return="int"
abstract="false"
@@ -158759,6 +160101,19 @@
<parameter name="filterText" type="java.lang.String">
</parameter>
</method>
+<method name="setGestures"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestures" type="int">
+</parameter>
+</method>
<method name="setOnScrollListener"
return="void"
abstract="false"
@@ -158904,6 +160259,39 @@
<parameter name="dr" type="android.graphics.drawable.Drawable">
</parameter>
</method>
+<field name="GESTURES_FILTER"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="GESTURES_JUMP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="GESTURES_NONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="TRANSCRIPT_MODE_ALWAYS_SCROLL"
type="int"
transient="false"
@@ -167528,6 +168916,21 @@
deprecated="not deprecated"
visibility="public"
>
+<parameter name="width" type="int">
+</parameter>
+<parameter name="height" type="int">
+</parameter>
+</method>
+<method name="update"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
<parameter name="x" type="int">
</parameter>
<parameter name="y" type="int">
diff --git a/camera/libcameraservice/CameraService.cpp b/camera/libcameraservice/CameraService.cpp
index f85ea9f..4e6859c 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -1052,8 +1052,6 @@ status_t CameraService::dump(int fd, const Vector<String16>& args)
}
-#if DEBUG_HEAP_LEAKS
-
#define CHECK_INTERFACE(interface, data, reply) \
do { if (!data.enforceInterface(interface::getInterfaceDescriptor())) { \
LOGW("Call incorrectly routed to " #interface); \
@@ -1085,6 +1083,7 @@ status_t CameraService::onTransact(
status_t err = BnCameraService::onTransact(code, data, reply, flags);
+#if DEBUG_HEAP_LEAKS
LOGD("+++ onTransact err %d code %d", err, code);
if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) {
@@ -1120,9 +1119,9 @@ status_t CameraService::onTransact(
break;
}
}
+#endif // DEBUG_HEAP_LEAKS
+
return err;
}
-#endif // DEBUG_HEAP_LEAKS
-
}; // namespace android
diff --git a/camera/libcameraservice/CameraService.h b/camera/libcameraservice/CameraService.h
index 6752f26..a421fd3 100644
--- a/camera/libcameraservice/CameraService.h
+++ b/camera/libcameraservice/CameraService.h
@@ -58,10 +58,8 @@ public:
void removeClient(const sp<ICameraClient>& cameraClient);
-#if DEBUG_HEAP_LEAKS
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags);
-#endif
private:
diff --git a/cmds/bootanimation/Android.mk b/cmds/bootanimation/Android.mk
new file mode 100644
index 0000000..9c94c2e
--- /dev/null
+++ b/cmds/bootanimation/Android.mk
@@ -0,0 +1,30 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+ bootanimation_main.cpp \
+ BootAnimation.cpp
+
+# need "-lrt" on Linux simulator to pick up clock_gettime
+ifeq ($(TARGET_SIMULATOR),true)
+ ifeq ($(HOST_OS),linux)
+ LOCAL_LDLIBS += -lrt
+ endif
+endif
+
+LOCAL_SHARED_LIBRARIES := \
+ libcutils \
+ libutils \
+ libui \
+ libcorecg \
+ libsgl \
+ libEGL \
+ libGLESv1_CM
+
+LOCAL_C_INCLUDES := \
+ $(call include-path-for, corecg graphics)
+
+LOCAL_MODULE:= bootanimation
+
+
+include $(BUILD_EXECUTABLE)
diff --git a/libs/surfaceflinger/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index db40385..3b9db8d 100644
--- a/libs/surfaceflinger/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -22,6 +22,7 @@
#include <fcntl.h>
#include <utils/misc.h>
+#include <utils/IPCThreadState.h>
#include <utils/threads.h>
#include <utils/Atomic.h>
#include <utils/Errors.h>
@@ -49,10 +50,9 @@ namespace android {
// ---------------------------------------------------------------------------
-BootAnimation::BootAnimation(const sp<ISurfaceComposer>& composer) :
- Thread(false) {
- mSession = SurfaceComposerClient::clientForConnection(
- composer->createConnection()->asBinder());
+BootAnimation::BootAnimation() : Thread(false)
+{
+ mSession = new SurfaceComposerClient();
}
BootAnimation::~BootAnimation() {
@@ -131,7 +131,7 @@ status_t BootAnimation::readyToRun() {
// create the native surface
sp<Surface> s = session()->createSurface(getpid(), 0, dinfo.w, dinfo.h,
- PIXEL_FORMAT_RGB_565);
+ PIXEL_FORMAT_RGB_565, ISurfaceComposer::eGPU);
session()->openTransaction();
s->setLayer(0x40000000);
session()->closeTransaction();
@@ -144,7 +144,10 @@ status_t BootAnimation::readyToRun() {
EGLConfig config;
EGLSurface surface;
EGLContext context;
+
EGLDisplay display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+
+ eglInitialize(display, 0, 0);
eglChooseConfig(display, attribs, &config, 1, &numConfigs);
mNativeWindowSurface = new EGLNativeWindowSurface(s);
@@ -170,17 +173,15 @@ status_t BootAnimation::readyToRun() {
return NO_ERROR;
}
-void BootAnimation::requestExit() {
- mBarrier.open();
- Thread::requestExit();
-}
-
bool BootAnimation::threadLoop() {
bool r = android();
eglMakeCurrent(mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
eglDestroyContext(mDisplay, mContext);
eglDestroySurface(mDisplay, mSurface);
mNativeWindowSurface.clear();
+ mFlingerSurface.clear();
+ eglTerminate(mDisplay);
+ IPCThreadState::self()->stopProcess();
return r;
}
@@ -227,8 +228,10 @@ bool BootAnimation::android() {
glBindTexture(GL_TEXTURE_2D, mAndroid[0].name);
glDrawTexiOES(xc, yc, 0, mAndroid[0].w, mAndroid[0].h);
- eglSwapBuffers(mDisplay, mSurface);
-
+ EGLBoolean res = eglSwapBuffers(mDisplay, mSurface);
+ if (res == EGL_FALSE)
+ break;
+
// 12fps: don't animate too fast to preserve CPU
const nsecs_t sleepTime = 83333 - ns2us(systemTime() - now);
if (sleepTime > 0)
diff --git a/libs/surfaceflinger/BootAnimation.h b/cmds/bootanimation/BootAnimation.h
index 3fb6670..42e9eed 100644
--- a/libs/surfaceflinger/BootAnimation.h
+++ b/cmds/bootanimation/BootAnimation.h
@@ -29,8 +29,6 @@
#include <EGL/egl.h>
#include <GLES/gl.h>
-#include "Barrier.h"
-
class SkBitmap;
namespace android {
@@ -43,11 +41,10 @@ class EGLNativeWindowSurface;
class BootAnimation : public Thread
{
public:
- BootAnimation(const sp<ISurfaceComposer>& composer);
+ BootAnimation();
virtual ~BootAnimation();
const sp<SurfaceComposerClient>& session() const;
- virtual void requestExit();
private:
virtual bool threadLoop();
@@ -73,7 +70,6 @@ private:
EGLDisplay mSurface;
sp<Surface> mFlingerSurface;
sp<EGLNativeWindowSurface> mNativeWindowSurface;
- Barrier mBarrier;
};
// ---------------------------------------------------------------------------
diff --git a/cmds/bootanimation/bootanimation_main.cpp b/cmds/bootanimation/bootanimation_main.cpp
new file mode 100644
index 0000000..675ea81
--- /dev/null
+++ b/cmds/bootanimation/bootanimation_main.cpp
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "BootAnimation"
+
+#include <utils/IPCThreadState.h>
+#include <utils/ProcessState.h>
+#include <utils/IServiceManager.h>
+#include <utils/Log.h>
+#include <utils/threads.h>
+
+#include <ui/ISurfaceComposer.h>
+
+#if defined(HAVE_PTHREADS)
+# include <pthread.h>
+# include <sys/resource.h>
+#endif
+
+#include "BootAnimation.h"
+
+using namespace android;
+
+// ---------------------------------------------------------------------------
+
+int main(int argc, char** argv)
+{
+#if defined(HAVE_PTHREADS)
+ setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
+#endif
+
+ sp<ProcessState> proc(ProcessState::self());
+ ProcessState::self()->startThreadPool();
+
+ // create the boot animation object
+ sp<BootAnimation> boot = new BootAnimation();
+
+ IPCThreadState::self()->joinThreadPool();
+ return 0;
+}
diff --git a/cmds/dumpstate/dumpstate.c b/cmds/dumpstate/dumpstate.c
index eabf98e..cc951c1 100644
--- a/cmds/dumpstate/dumpstate.c
+++ b/cmds/dumpstate/dumpstate.c
@@ -165,6 +165,7 @@ int main(int argc, char *argv[]) {
int c, fd, vibrate_fd, fds[2];
char path[PATH_MAX];
pid_t pid;
+ gid_t groups[] = { AID_LOG, AID_SDCARD_RW };
/* set as high priority, and protect from OOM killer */
setpriority(PRIO_PROCESS, 0, -20);
@@ -207,7 +208,7 @@ int main(int argc, char *argv[]) {
vibrate_fd = -1;
/* switch to non-root user and group */
- setgid(AID_LOG);
+ setgroups(sizeof(groups)/sizeof(groups[0]), groups);
setuid(AID_SHELL);
/* make it safe to use both printf and STDOUT_FILENO */
diff --git a/cmds/pm/src/com/android/commands/pm/Pm.java b/cmds/pm/src/com/android/commands/pm/Pm.java
index 8212b92..fd9e708 100644
--- a/cmds/pm/src/com/android/commands/pm/Pm.java
+++ b/cmds/pm/src/com/android/commands/pm/Pm.java
@@ -543,6 +543,9 @@ public final class Pm {
case PackageManager.INSTALL_FAILED_TEST_ONLY:
s = "INSTALL_FAILED_TEST_ONLY";
break;
+ case PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE:
+ s = "INSTALL_FAILED_CPU_ABI_INCOMPATIBLE";
+ break;
case PackageManager.INSTALL_PARSE_FAILED_NOT_APK:
s = "INSTALL_PARSE_FAILED_NOT_APK";
break;
diff --git a/cmds/runtime/main_runtime.cpp b/cmds/runtime/main_runtime.cpp
index 1531a9e..476f38a 100644
--- a/cmds/runtime/main_runtime.cpp
+++ b/cmds/runtime/main_runtime.cpp
@@ -45,9 +45,9 @@ static const char* ZYGOTE_ARGV[] = {
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,3001,3002,3003",
/* CAP_SYS_TTY_CONFIG & CAP_SYS_RESOURCE & CAP_NET_BROADCAST &
* CAP_NET_ADMIN & CAP_NET_RAW & CAP_NET_BIND_SERVICE & CAP_KILL &
- * CAP_SYS_BOOT
+ * CAP_SYS_BOOT CAP_SYS_NICE
*/
- "--capabilities=88161312,88161312",
+ "--capabilities=96549920,96549920",
"--runtime-init",
"--nice-name=system_server",
"com.android.server.SystemServer"
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 343380c..aaaf7bf 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -31,7 +31,13 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
+import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
+import android.location.Criteria;
+import android.location.Location;
+import android.location.LocationListener;
+import android.location.LocationManager;
+import android.location.LocationProvider;
import android.net.Uri;
import android.os.Bundle;
import android.os.SystemClock;
@@ -103,6 +109,7 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
private Button mGoButton;
private ImageButton mVoiceButton;
private View mSearchPlate;
+ private AnimationDrawable mWorkingSpinner;
// interaction with searchable application
private SearchableInfo mSearchable;
@@ -143,6 +150,15 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
private final WeakHashMap<String, Drawable> mOutsideDrawablesCache =
new WeakHashMap<String, Drawable>();
+ // Objects we keep around for requesting location updates when the dialog is started
+ // (and canceling them when the dialog is stopped). We don't actually make use of the
+ // updates ourselves here, so the LocationListener is just a dummy which doesn't do
+ // anything. We only do this here so that other suggest providers which wish to provide
+ // location-based suggestions are more likely to get a good fresh location.
+ private LocationManager mLocationManager;
+ private LocationProvider mLocationProvider;
+ private LocationListener mDummyLocationListener;
+
/**
* Constructor - fires it up and makes it look like the search UI.
*
@@ -182,6 +198,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
mGoButton = (Button) findViewById(com.android.internal.R.id.search_go_btn);
mVoiceButton = (ImageButton) findViewById(com.android.internal.R.id.search_voice_btn);
mSearchPlate = findViewById(com.android.internal.R.id.search_plate);
+ mWorkingSpinner = (AnimationDrawable) getContext().getResources().
+ getDrawable(com.android.internal.R.drawable.search_spinner);
// attach listeners
mSearchAutoComplete.addTextChangedListener(mTextWatcher);
@@ -217,6 +235,37 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
RecognizerIntent.LANGUAGE_MODEL_WEB_SEARCH);
mVoiceAppSearchIntent = new Intent(RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
+
+ mLocationManager =
+ (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
+
+ if (mLocationManager != null) {
+ Criteria criteria = new Criteria();
+ criteria.setAccuracy(Criteria.ACCURACY_COARSE);
+
+ String providerName = mLocationManager.getBestProvider(criteria, true);
+
+ if (providerName != null) {
+ mLocationProvider = mLocationManager.getProvider(providerName);
+ }
+
+ // Just a dumb listener that doesn't do anything - requesting location updates here
+ // is only intended to give location-based suggestion providers the best chance
+ // of getting a good fresh location.
+ mDummyLocationListener = new LocationListener() {
+ public void onLocationChanged(Location location) {
+ }
+
+ public void onProviderDisabled(String provider) {
+ }
+
+ public void onProviderEnabled(String provider) {
+ }
+
+ public void onStatusChanged(String provider, int status, Bundle extras) {
+ }
+ };
+ }
}
/**
@@ -239,7 +288,6 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
return doShow(initialQuery, selectInitialQuery, componentName, appSearchData, globalSearch);
}
-
/**
* Called in response to a press of the hard search button in
* {@link #onKeyDown(int, KeyEvent)}, this method toggles between in-app
@@ -360,6 +408,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// receive broadcasts
getContext().registerReceiver(mBroadcastReceiver, mCloseDialogsFilter);
getContext().registerReceiver(mBroadcastReceiver, mPackageFilter);
+
+ startLocationUpdates();
}
/**
@@ -372,6 +422,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
public void onStop() {
super.onStop();
+ stopLocationUpdates();
+
// TODO: Removing the listeners means that they never get called, since
// Dialog.dismissDialog() calls onStop() before sendDismissMessage().
setOnCancelListener(null);
@@ -396,6 +448,43 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
}
/**
+ * Asks the LocationManager for location updates so that it goes and gets a fresh location
+ * if needed.
+ */
+ private void startLocationUpdates() {
+ if (mLocationManager != null && mLocationProvider != null) {
+ mLocationManager.requestLocationUpdates(mLocationProvider.getName(),
+ 0, 0, mDummyLocationListener, getContext().getMainLooper());
+ }
+
+ }
+
+ /**
+ * Makes sure to stop listening for location updates to save battery.
+ */
+ private void stopLocationUpdates() {
+ mLocationManager.removeUpdates(mDummyLocationListener);
+ }
+
+ /**
+ * Sets the search dialog to the 'working' state, which shows a working spinner in the
+ * right hand size of the text field.
+ *
+ * @param working true to show spinner, false to hide spinner
+ */
+ public void setWorking(boolean working) {
+ if (working) {
+ mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
+ null, null, mWorkingSpinner, null);
+ mWorkingSpinner.start();
+ } else {
+ mSearchAutoComplete.setCompoundDrawablesWithIntrinsicBounds(
+ null, null, null, null);
+ mWorkingSpinner.stop();
+ }
+ }
+
+ /**
* Closes and gets rid of the suggestions adapter.
*/
private void closeSuggestionsAdapter() {
@@ -563,8 +652,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// attach the suggestions adapter, if suggestions are available
// The existence of a suggestions authority is the proxy for "suggestions available here"
if (mSearchable.getSuggestAuthority() != null) {
- mSuggestionsAdapter = new SuggestionsAdapter(getContext(), mSearchable,
- mOutsideDrawablesCache);
+ mSuggestionsAdapter = new SuggestionsAdapter(getContext(), this, mSearchable,
+ mOutsideDrawablesCache, mGlobalSearchMode);
mSearchAutoComplete.setAdapter(mSuggestionsAdapter);
}
}
diff --git a/core/java/android/app/SuggestionsAdapter.java b/core/java/android/app/SuggestionsAdapter.java
index 6a02fc9..2fe9a8d 100644
--- a/core/java/android/app/SuggestionsAdapter.java
+++ b/core/java/android/app/SuggestionsAdapter.java
@@ -25,6 +25,7 @@ import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
+import android.os.Bundle;
import android.server.search.SearchableInfo;
import android.text.Html;
import android.text.TextUtils;
@@ -45,12 +46,18 @@ import java.util.WeakHashMap;
* @hide
*/
class SuggestionsAdapter extends ResourceCursorAdapter {
+ // The value used to query a cursor whether it is still expecting more input,
+ // so we can correctly display (or not display) the 'working' spinner in the search dialog.
+ public static final String IS_WORKING = "isWorking";
+
private static final boolean DBG = false;
private static final String LOG_TAG = "SuggestionsAdapter";
+ private SearchDialog mSearchDialog;
private SearchableInfo mSearchable;
private Context mProviderContext;
private WeakHashMap<String, Drawable> mOutsideDrawablesCache;
+ private boolean mGlobalSearchMode;
// Cached column indexes, updated when the cursor changes.
private int mFormatCol;
@@ -61,12 +68,13 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
private int mIconBitmap1Col;
private int mIconBitmap2Col;
- public SuggestionsAdapter(Context context, SearchableInfo searchable,
- WeakHashMap<String, Drawable> outsideDrawablesCache) {
+ public SuggestionsAdapter(Context context, SearchDialog searchDialog, SearchableInfo searchable,
+ WeakHashMap<String, Drawable> outsideDrawablesCache, boolean globalSearchMode) {
super(context,
com.android.internal.R.layout.search_dropdown_item_icons_2line,
null, // no initial cursor
true); // auto-requery
+ mSearchDialog = searchDialog;
mSearchable = searchable;
// set up provider resources (gives us icons, etc.)
@@ -74,6 +82,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
mProviderContext = mSearchable.getProviderContext(mContext, activityContext);
mOutsideDrawablesCache = outsideDrawablesCache;
+ mGlobalSearchMode = globalSearchMode;
}
/**
@@ -118,6 +127,28 @@ class SuggestionsAdapter extends ResourceCursorAdapter {
mIconBitmap1Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_1_BITMAP);
mIconBitmap2Col = c.getColumnIndex(SearchManager.SUGGEST_COLUMN_ICON_2_BITMAP);
}
+ updateWorking();
+ }
+
+ @Override
+ public void notifyDataSetChanged() {
+ super.notifyDataSetChanged();
+ updateWorking();
+ }
+
+ /**
+ * Updates the search dialog according to the current working status of the cursor.
+ */
+ private void updateWorking() {
+ if (!mGlobalSearchMode || mCursor == null) return;
+
+ Bundle request = new Bundle();
+ request.putString(SearchManager.EXTRA_DATA_KEY, IS_WORKING);
+ Bundle response = mCursor.respond(request);
+ if (response.containsKey(IS_WORKING)) {
+ boolean isWorking = response.getBoolean(IS_WORKING);
+ mSearchDialog.setWorking(isWorking);
+ }
}
/**
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index eecbce4..238a98a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -398,6 +398,15 @@ public abstract class PackageManager {
public static final int INSTALL_FAILED_TEST_ONLY = -15;
/**
+ * Installation return code: this is passed to the {@link IPackageInstallObserver} by
+ * {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)} if
+ * the package being installed contains native code, but none that is
+ * compatible with the the device's CPU_ABI.
+ * @hide
+ */
+ public static final int INSTALL_FAILED_CPU_ABI_INCOMPATIBLE = -16;
+
+ /**
* Installation parse return code: this is passed to the {@link IPackageInstallObserver} by
* {@link #installPackage(android.net.Uri, IPackageInstallObserver, int)}
* if the parser was given a path that is not a file, or does not end with the expected
diff --git a/tests/sketch/src/com/android/gesture/Gesture.java b/core/java/android/gesture/Gesture.java
index 44711ca..6aca105 100755
--- a/tests/sketch/src/com/android/gesture/Gesture.java
+++ b/core/java/android/gesture/Gesture.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
import android.graphics.Bitmap;
import android.graphics.Canvas;
@@ -23,10 +23,13 @@ import android.graphics.Path;
import android.graphics.RectF;
import android.os.Parcel;
import android.os.Parcelable;
-
-import org.xmlpull.v1.XmlSerializer;
+import android.util.Log;
import java.io.IOException;
+import java.io.DataOutputStream;
+import java.io.DataInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.ByteArrayInputStream;
import java.util.ArrayList;
/**
@@ -54,6 +57,11 @@ public class Gesture implements Parcelable {
mGestureID = GESTURE_ID_BASE + sGestureCount++;
}
+ void recycle() {
+ mStrokes.clear();
+ mBoundingBox.setEmpty();
+ }
+
/**
* @return all the strokes of the gesture
*/
@@ -108,6 +116,40 @@ public class Gesture implements Parcelable {
return mBoundingBox;
}
+ public Path toPath() {
+ return toPath(null);
+ }
+
+ public Path toPath(Path path) {
+ if (path == null) path = new Path();
+
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
+ for (int i = 0; i < count; i++) {
+ path.addPath(strokes.get(i).getPath());
+ }
+
+ return path;
+ }
+
+ public Path toPath(int width, int height, int edge, int numSample) {
+ return toPath(null, width, height, edge, numSample);
+ }
+
+ public Path toPath(Path path, int width, int height, int edge, int numSample) {
+ if (path == null) path = new Path();
+
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
+ for (int i = 0; i < count; i++) {
+ path.addPath(strokes.get(i).toPath(width - 2 * edge, height - 2 * edge, numSample));
+ }
+
+ return path;
+ }
+
/**
* Set the id of the gesture
*
@@ -149,10 +191,12 @@ public class Gesture implements Parcelable {
* @return the bitmap
*/
public Bitmap toBitmap(int width, int height, int edge, int numSample, int color) {
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
+ final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+
canvas.translate(edge, edge);
- Paint paint = new Paint();
+
+ final Paint paint = new Paint();
paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS);
paint.setDither(BITMAP_RENDERING_DITHER);
paint.setColor(color);
@@ -182,10 +226,12 @@ public class Gesture implements Parcelable {
* @return the bitmap
*/
public Bitmap toBitmap(int width, int height, int edge, int color) {
- Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
- Canvas canvas = new Canvas(bitmap);
+ final Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+ final Canvas canvas = new Canvas(bitmap);
+
canvas.translate(edge, edge);
- Paint paint = new Paint();
+
+ final Paint paint = new Paint();
paint.setAntiAlias(BITMAP_RENDERING_ANTIALIAS);
paint.setDither(BITMAP_RENDERING_DITHER);
paint.setColor(color);
@@ -193,78 +239,66 @@ public class Gesture implements Parcelable {
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setStrokeWidth(BITMAP_RENDERING_WIDTH);
- ArrayList<GestureStroke> strokes = mStrokes;
- int count = strokes.size();
+
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
for (int i = 0; i < count; i++) {
- GestureStroke stroke = strokes.get(i);
- stroke.draw(canvas, paint);
+ strokes.get(i).draw(canvas, paint);
}
return bitmap;
}
- /**
- * Save the gesture as XML
- *
- * @param namespace
- * @param serializer
- * @throws IOException
- */
- void toXML(String namespace, XmlSerializer serializer) throws IOException {
- serializer.startTag(namespace, GestureConstants.XML_TAG_GESTURE);
- serializer.attribute(namespace, GestureConstants.XML_TAG_ID, Long.toString(mGestureID));
- ArrayList<GestureStroke> strokes = mStrokes;
- int count = strokes.size();
+ void serialize(DataOutputStream out) throws IOException {
+ final ArrayList<GestureStroke> strokes = mStrokes;
+ final int count = strokes.size();
+
+ // Write gesture ID
+ out.writeLong(mGestureID);
+ // Write number of strokes
+ out.writeInt(count);
+
for (int i = 0; i < count; i++) {
- GestureStroke stroke = strokes.get(i);
- stroke.toXML(namespace, serializer);
+ strokes.get(i).serialize(out);
}
- serializer.endTag(namespace, GestureConstants.XML_TAG_GESTURE);
}
- /**
- * Create the gesture from a string
- *
- * @param str
- */
- public void createFromString(String str) {
- int startIndex = 0;
- int endIndex;
- while ((endIndex =
- str.indexOf(GestureConstants.STRING_GESTURE_DELIIMITER, startIndex + 1)) != -1) {
- String token = str.substring(startIndex, endIndex);
- if (startIndex > 0) { // stroke tokens
- addStroke(GestureStroke.createFromString(token));
- } else { // id token
- mGestureID = Long.parseLong(token);
- }
- startIndex = endIndex + 1;
- }
- }
+ static Gesture deserialize(DataInputStream in) throws IOException {
+ final Gesture gesture = new Gesture();
+
+ // Gesture ID
+ gesture.mGestureID = in.readLong();
+ // Number of strokes
+ final int count = in.readInt();
- /**
- * Convert the gesture to string
- */
- @Override
- public String toString() {
- StringBuilder str = new StringBuilder();
- str.append(mGestureID);
- ArrayList<GestureStroke> strokes = mStrokes;
- int count = strokes.size();
for (int i = 0; i < count; i++) {
- GestureStroke stroke = strokes.get(i);
- str.append(GestureConstants.STRING_GESTURE_DELIIMITER);
- str.append(stroke.toString());
+ gesture.addStroke(GestureStroke.deserialize(in));
}
- return str.toString();
+ return gesture;
}
public static final Parcelable.Creator<Gesture> CREATOR = new Parcelable.Creator<Gesture>() {
public Gesture createFromParcel(Parcel in) {
- String str = in.readString();
- Gesture gesture = new Gesture();
- gesture.createFromString(str);
+ Gesture gesture = null;
+ final long gestureID = in.readLong();
+
+ final DataInputStream inStream = new DataInputStream(
+ new ByteArrayInputStream(in.createByteArray()));
+
+ try {
+ gesture = deserialize(inStream);
+ } catch (IOException e) {
+ Log.e(GestureConstants.LOG_TAG, "Error reading Gesture from parcel:", e);
+ } finally {
+ GestureUtilities.closeStream(inStream);
+ }
+
+ if (gesture != null) {
+ gesture.mGestureID = gestureID;
+ }
+
return gesture;
}
@@ -273,35 +307,31 @@ public class Gesture implements Parcelable {
}
};
- /**
- * Build a gesture from a byte array
- *
- * @param bytes
- * @return the gesture
- */
- static Gesture buildFromArray(byte[] bytes) {
- String str = new String(bytes);
- Gesture gesture = new Gesture();
- gesture.createFromString(str);
- return gesture;
- }
-
- /**
- * Save a gesture to a byte array
- *
- * @param stroke
- * @return the byte array
- */
- static byte[] saveToArray(Gesture stroke) {
- String str = stroke.toString();
- return str.getBytes();
- }
-
public void writeToParcel(Parcel out, int flags) {
- out.writeString(toString());
+ out.writeLong(mGestureID);
+
+ boolean result = false;
+ final ByteArrayOutputStream byteStream =
+ new ByteArrayOutputStream(GestureConstants.IO_BUFFER_SIZE);
+ final DataOutputStream outStream = new DataOutputStream(byteStream);
+
+ try {
+ serialize(outStream);
+ result = true;
+ } catch (IOException e) {
+ Log.e(GestureConstants.LOG_TAG, "Error writing Gesture to parcel:", e);
+ } finally {
+ GestureUtilities.closeStream(outStream);
+ GestureUtilities.closeStream(byteStream);
+ }
+
+ if (result) {
+ out.writeByteArray(byteStream.toByteArray());
+ }
}
public int describeContents() {
- return CONTENTS_FILE_DESCRIPTOR;
+ return 0;
}
}
+
diff --git a/tests/sketch/src/com/android/gesture/GestureConstants.java b/core/java/android/gesture/GestureConstants.java
index cb64791..230db0c 100644
--- a/tests/sketch/src/com/android/gesture/GestureConstants.java
+++ b/core/java/android/gesture/GestureConstants.java
@@ -14,19 +14,13 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
interface GestureConstants {
- static final String XML_TAG_LIBRARY = "library";
- static final String XML_TAG_ENTRY = "entry";
- static final String XML_TAG_GESTURE = "gesture";
- static final String XML_TAG_STROKE = "stroke";
- static final String XML_TAG_ID = "id";
- static final String XML_TAG_NAME = "name";
- static final String STRING_GESTURE_DELIIMITER = "#";
- static final String STRING_STROKE_DELIIMITER = ",";
static final int STROKE_STRING_BUFFER_SIZE = 1024;
static final int STROKE_POINT_BUFFER_SIZE = 100; // number of points
- static final int IO_BUFFER_SIZE = 8 * 1024; // 8K
- String LOG_TAG = "GestureLibrary";
+
+ static final int IO_BUFFER_SIZE = 32 * 1024; // 32K
+
+ static final String LOG_TAG = "Gestures";
}
diff --git a/core/java/android/gesture/GestureLibrary.java b/core/java/android/gesture/GestureLibrary.java
new file mode 100644
index 0000000..1cf192e
--- /dev/null
+++ b/core/java/android/gesture/GestureLibrary.java
@@ -0,0 +1,346 @@
+/*
+ * Copyright (C) 2008-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 android.gesture;
+
+import android.util.Log;
+import android.os.SystemClock;
+
+import java.io.BufferedInputStream;
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.DataOutputStream;
+import java.io.DataInputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Set;
+import java.util.Map;
+
+import static android.gesture.GestureConstants.LOG_TAG;
+
+/**
+ * GestureLibrary maintains gesture examples and makes predictions on a new
+ * gesture
+ */
+//
+// File format for GestureLibrary:
+//
+// Nb. bytes Java type Description
+// -----------------------------------
+// Header
+// 2 bytes short File format version number
+// 4 bytes int Number of entries
+// Entry
+// X bytes UTF String Entry name
+// 4 bytes int Number of gestures
+// Gesture
+// 8 bytes long Gesture ID
+// 4 bytes int Number of strokes
+// Stroke
+// 4 bytes int Number of points
+// Point
+// 4 bytes float X coordinate of the point
+// 4 bytes float Y coordinate of the point
+// 8 bytes long Time stamp
+//
+public class GestureLibrary {
+ public static final int SEQUENCE_INVARIANT = 1;
+ // when SEQUENCE_SENSITIVE is used, only single stroke gestures are currently allowed
+ public static final int SEQUENCE_SENSITIVE = 2;
+
+ // ORIENTATION_SENSITIVE and ORIENTATION_INVARIANT are only for SEQUENCE_SENSITIVE gestures
+ public static final int ORIENTATION_INVARIANT = 1;
+ public static final int ORIENTATION_SENSITIVE = 2;
+
+ private static final short FILE_FORMAT_VERSION = 1;
+
+ private static final boolean PROFILE_LOADING_SAVING = false;
+
+ private int mSequenceType = SEQUENCE_SENSITIVE;
+ private int mOrientationStyle = ORIENTATION_SENSITIVE;
+
+ private final String mGestureFileName;
+
+ private final HashMap<String, ArrayList<Gesture>> mNamedGestures =
+ new HashMap<String, ArrayList<Gesture>>();
+
+ private Learner mClassifier;
+
+ private boolean mChanged = false;
+
+ /**
+ * @param path where gesture data is stored
+ */
+ public GestureLibrary(String path) {
+ mGestureFileName = path;
+ mClassifier = new InstanceLearner();
+ }
+
+ /**
+ * Specify how the gesture library will handle orientation.
+ * Use ORIENTATION_INVARIANT or ORIENTATION_SENSITIVE
+ *
+ * @param style
+ */
+ public void setOrientationStyle(int style) {
+ mOrientationStyle = style;
+ }
+
+ public int getOrientationStyle() {
+ return mOrientationStyle;
+ }
+
+ /**
+ * @param type SEQUENCE_INVARIANT or SEQUENCE_SENSITIVE
+ */
+ public void setSequenceType(int type) {
+ mSequenceType = type;
+ }
+
+ /**
+ * @return SEQUENCE_INVARIANT or SEQUENCE_SENSITIVE
+ */
+ public int getSequenceType() {
+ return mSequenceType;
+ }
+
+ /**
+ * Get all the gesture entry names in the library
+ *
+ * @return a set of strings
+ */
+ public Set<String> getGestureEntries() {
+ return mNamedGestures.keySet();
+ }
+
+ /**
+ * Recognize a gesture
+ *
+ * @param gesture the query
+ * @return a list of predictions of possible entries for a given gesture
+ */
+ public ArrayList<Prediction> recognize(Gesture gesture) {
+ Instance instance = Instance.createInstance(mSequenceType, gesture, null);
+ return mClassifier.classify(mSequenceType, instance.vector);
+ }
+
+ /**
+ * Add a gesture for the entry
+ *
+ * @param entryName entry name
+ * @param gesture
+ */
+ public void addGesture(String entryName, Gesture gesture) {
+ if (entryName == null || entryName.length() == 0) {
+ return;
+ }
+ ArrayList<Gesture> gestures = mNamedGestures.get(entryName);
+ if (gestures == null) {
+ gestures = new ArrayList<Gesture>();
+ mNamedGestures.put(entryName, gestures);
+ }
+ gestures.add(gesture);
+ mClassifier.addInstance(Instance.createInstance(mSequenceType, gesture, entryName));
+ mChanged = true;
+ }
+
+ /**
+ * Remove a gesture from the library. If there are no more gestures for the
+ * given entry, the gesture entry will be removed.
+ *
+ * @param entryName entry name
+ * @param gesture
+ */
+ public void removeGesture(String entryName, Gesture gesture) {
+ ArrayList<Gesture> gestures = mNamedGestures.get(entryName);
+ if (gestures == null) {
+ return;
+ }
+
+ gestures.remove(gesture);
+
+ // if there are no more samples, remove the entry automatically
+ if (gestures.isEmpty()) {
+ mNamedGestures.remove(entryName);
+ }
+
+ mClassifier.removeInstance(gesture.getID());
+
+ mChanged = true;
+ }
+
+ /**
+ * Remove a entry of gestures
+ *
+ * @param entryName the entry name
+ */
+ public void removeEntry(String entryName) {
+ mNamedGestures.remove(entryName);
+ mClassifier.removeInstances(entryName);
+ mChanged = true;
+ }
+
+ /**
+ * Get all the gestures of an entry
+ *
+ * @param entryName
+ * @return the list of gestures that is under this name
+ */
+ public ArrayList<Gesture> getGestures(String entryName) {
+ ArrayList<Gesture> gestures = mNamedGestures.get(entryName);
+ if (gestures != null) {
+ return new ArrayList<Gesture>(gestures);
+ } else {
+ return null;
+ }
+ }
+
+ /**
+ * Save the gesture library
+ */
+ public boolean save() {
+ if (!mChanged) {
+ return true;
+ }
+
+ boolean result = false;
+ DataOutputStream out = null;
+
+ try {
+ File file = new File(mGestureFileName);
+ if (!file.getParentFile().exists()) {
+ if (!file.getParentFile().mkdirs()) {
+ return false;
+ }
+ }
+
+ long start;
+ if (PROFILE_LOADING_SAVING) {
+ start = SystemClock.elapsedRealtime();
+ }
+
+ final HashMap<String, ArrayList<Gesture>> maps = mNamedGestures;
+
+ out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file),
+ GestureConstants.IO_BUFFER_SIZE));
+ // Write version number
+ out.writeShort(FILE_FORMAT_VERSION);
+ // Write number of entries
+ out.writeInt(maps.size());
+
+ for (Map.Entry<String, ArrayList<Gesture>> entry : maps.entrySet()) {
+ final String key = entry.getKey();
+ final ArrayList<Gesture> examples = entry.getValue();
+ final int count = examples.size();
+
+ // Write entry name
+ out.writeUTF(key);
+ // Write number of examples for this entry
+ out.writeInt(count);
+
+ for (int i = 0; i < count; i++) {
+ examples.get(i).serialize(out);
+ }
+ }
+
+ out.flush();
+
+ if (PROFILE_LOADING_SAVING) {
+ long end = SystemClock.elapsedRealtime();
+ Log.d(LOG_TAG, "Saving gestures library = " + (end - start) + " ms");
+ }
+
+ mChanged = false;
+ result = true;
+ } catch (IOException ex) {
+ Log.d(LOG_TAG, "Failed to save gestures:", ex);
+ } finally {
+ GestureUtilities.closeStream(out);
+ }
+
+ return result;
+ }
+
+ /**
+ * Load the gesture library
+ */
+ public boolean load() {
+ boolean result = false;
+
+ final File file = new File(mGestureFileName);
+ if (file.exists()) {
+ DataInputStream in = null;
+ try {
+ in = new DataInputStream(new BufferedInputStream(
+ new FileInputStream(mGestureFileName), GestureConstants.IO_BUFFER_SIZE));
+
+ long start;
+ if (PROFILE_LOADING_SAVING) {
+ start = SystemClock.elapsedRealtime();
+ }
+
+ // Read file format version number
+ final short versionNumber = in.readShort();
+ switch (versionNumber) {
+ case 1:
+ readFormatV1(in);
+ break;
+ }
+
+ if (PROFILE_LOADING_SAVING) {
+ long end = SystemClock.elapsedRealtime();
+ Log.d(LOG_TAG, "Loading gestures library = " + (end - start) + " ms");
+ }
+
+ result = true;
+ } catch (IOException ex) {
+ Log.d(LOG_TAG, "Failed to load gestures:", ex);
+ } finally {
+ GestureUtilities.closeStream(in);
+ }
+ }
+
+ return result;
+ }
+
+ private void readFormatV1(DataInputStream in) throws IOException {
+ final Learner classifier = mClassifier;
+ final HashMap<String, ArrayList<Gesture>> namedGestures = mNamedGestures;
+ namedGestures.clear();
+
+ // Number of entries in the library
+ final int entriesCount = in.readInt();
+
+ for (int i = 0; i < entriesCount; i++) {
+ // Entry name
+ final String name = in.readUTF();
+ // Number of gestures
+ final int gestureCount = in.readInt();
+
+ final ArrayList<Gesture> gestures = new ArrayList<Gesture>(gestureCount);
+ for (int j = 0; j < gestureCount; j++) {
+ final Gesture gesture = Gesture.deserialize(in);
+ gestures.add(gesture);
+ classifier.addInstance(Instance.createInstance(mSequenceType, gesture, name));
+ }
+
+ namedGestures.put(name, gestures);
+ }
+ }
+}
diff --git a/core/java/android/gesture/GestureOverlayView.java b/core/java/android/gesture/GestureOverlayView.java
new file mode 100755
index 0000000..c21cc55
--- /dev/null
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -0,0 +1,688 @@
+/*
+ * 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 android.gesture;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.graphics.RectF;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.animation.AnimationUtils;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import android.widget.FrameLayout;
+import android.os.SystemClock;
+import com.android.internal.R;
+
+import java.util.ArrayList;
+
+/**
+ * A transparent overlay for gesture input that can be placed on top of other
+ * widgets or contain other widgets.
+ *
+ * @attr ref android.R.styleable#GestureOverlayView_eventsInterceptionEnabled
+ * @attr ref android.R.styleable#GestureOverlayView_fadeDuration
+ * @attr ref android.R.styleable#GestureOverlayView_fadeOffset
+ * @attr ref android.R.styleable#GestureOverlayView_fadeEnabled
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeWidth
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeAngleThreshold
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeLengthThreshold
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeSquarenessThreshold
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeType
+ * @attr ref android.R.styleable#GestureOverlayView_gestureColor
+ * @attr ref android.R.styleable#GestureOverlayView_uncertainGestureColor
+ */
+public class GestureOverlayView extends FrameLayout {
+ public static final int GESTURE_STROKE_TYPE_SINGLE = 0;
+ public static final int GESTURE_STROKE_TYPE_MULTIPLE = 1;
+
+ public static final int ORIENTATION_HORIZONTAL = 0;
+ public static final int ORIENTATION_VERTICAL = 1;
+
+ private static final int FADE_ANIMATION_RATE = 16;
+ private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
+ private static final boolean DITHER_FLAG = true;
+
+ private final Paint mGesturePaint = new Paint();
+
+ private long mFadeDuration = 150;
+ private long mFadeOffset = 420;
+ private long mFadingStart;
+ private boolean mFadingHasStarted;
+ private boolean mFadeEnabled = true;
+
+ private int mCurrentColor;
+ private int mCertainGestureColor = 0xFFFFFF00;
+ private int mUncertainGestureColor = 0x48FFFF00;
+ private float mGestureStrokeWidth = 12.0f;
+ private int mInvalidateExtraBorder = 10;
+
+ private int mGestureStrokeType = GESTURE_STROKE_TYPE_SINGLE;
+ private float mGestureStrokeLengthThreshold = 30.0f;
+ private float mGestureStrokeSquarenessTreshold = 0.275f;
+ private float mGestureStrokeAngleThreshold = 40.0f;
+
+ private int mOrientation = ORIENTATION_VERTICAL;
+
+ private final Rect mInvalidRect = new Rect();
+ private final Path mPath = new Path();
+
+ private float mX;
+ private float mY;
+
+ private float mCurveEndX;
+ private float mCurveEndY;
+
+ private float mTotalLength;
+ private boolean mIsGesturing = false;
+ private boolean mInterceptEvents = true;
+ private boolean mIsListeningForGestures;
+
+ // current gesture
+ private Gesture mCurrentGesture;
+ private final ArrayList<GesturePoint> mStrokeBuffer = new ArrayList<GesturePoint>(100);
+
+ // TODO: Make this a list of WeakReferences
+ private final ArrayList<OnGestureListener> mOnGestureListeners =
+ new ArrayList<OnGestureListener>();
+ // TODO: Make this a list of WeakReferences
+ private final ArrayList<OnGesturePerformedListener> mOnGesturePerformedListeners =
+ new ArrayList<OnGesturePerformedListener>();
+
+ private boolean mHandleGestureActions;
+
+ // fading out effect
+ private boolean mIsFadingOut = false;
+ private float mFadingAlpha = 1.0f;
+ private final AccelerateDecelerateInterpolator mInterpolator =
+ new AccelerateDecelerateInterpolator();
+
+ private final FadeOutRunnable mFadingOut = new FadeOutRunnable();
+
+ public GestureOverlayView(Context context) {
+ super(context);
+ init();
+ }
+
+ public GestureOverlayView(Context context, AttributeSet attrs) {
+ this(context, attrs, com.android.internal.R.attr.gestureOverlayViewStyle);
+ }
+
+ public GestureOverlayView(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs, defStyle);
+
+ TypedArray a = context.obtainStyledAttributes(attrs,
+ R.styleable.GestureOverlayView, defStyle, 0);
+
+ mGestureStrokeWidth = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth,
+ mGestureStrokeWidth);
+ mInvalidateExtraBorder = Math.max(1, ((int) mGestureStrokeWidth) - 1);
+ mCertainGestureColor = a.getColor(R.styleable.GestureOverlayView_gestureColor,
+ mCertainGestureColor);
+ mUncertainGestureColor = a.getColor(R.styleable.GestureOverlayView_uncertainGestureColor,
+ mUncertainGestureColor);
+ mFadeDuration = a.getInt(R.styleable.GestureOverlayView_fadeDuration, (int) mFadeDuration);
+ mFadeOffset = a.getInt(R.styleable.GestureOverlayView_fadeOffset, (int) mFadeOffset);
+ mGestureStrokeType = a.getInt(R.styleable.GestureOverlayView_gestureStrokeType,
+ mGestureStrokeType);
+ mGestureStrokeLengthThreshold = a.getFloat(
+ R.styleable.GestureOverlayView_gestureStrokeLengthThreshold,
+ mGestureStrokeLengthThreshold);
+ mGestureStrokeAngleThreshold = a.getFloat(
+ R.styleable.GestureOverlayView_gestureStrokeAngleThreshold,
+ mGestureStrokeAngleThreshold);
+ mGestureStrokeSquarenessTreshold = a.getFloat(
+ R.styleable.GestureOverlayView_gestureStrokeSquarenessThreshold,
+ mGestureStrokeSquarenessTreshold);
+ mInterceptEvents = a.getBoolean(R.styleable.GestureOverlayView_eventsInterceptionEnabled,
+ mInterceptEvents);
+ mFadeEnabled = a.getBoolean(R.styleable.GestureOverlayView_fadeEnabled,
+ mFadeEnabled);
+ mOrientation = a.getInt(R.styleable.GestureOverlayView_orientation, mOrientation);
+
+ a.recycle();
+
+ init();
+ }
+
+ private void init() {
+ setWillNotDraw(false);
+
+ final Paint gesturePaint = mGesturePaint;
+ gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
+ gesturePaint.setColor(mCertainGestureColor);
+ gesturePaint.setStyle(Paint.Style.STROKE);
+ gesturePaint.setStrokeJoin(Paint.Join.ROUND);
+ gesturePaint.setStrokeCap(Paint.Cap.ROUND);
+ gesturePaint.setStrokeWidth(mGestureStrokeWidth);
+ gesturePaint.setDither(DITHER_FLAG);
+
+ mCurrentColor = mCertainGestureColor;
+ setPaintAlpha(255);
+ }
+
+ public ArrayList<GesturePoint> getCurrentStroke() {
+ return mStrokeBuffer;
+ }
+
+ public int getOrientation() {
+ return mOrientation;
+ }
+
+ public void setOrientation(int orientation) {
+ mOrientation = orientation;
+ }
+
+ public void setGestureColor(int color) {
+ mCertainGestureColor = color;
+ }
+
+ public void setUncertainGestureColor(int color) {
+ mUncertainGestureColor = color;
+ }
+
+ public int getUncertainGestureColor() {
+ return mUncertainGestureColor;
+ }
+
+ public int getGestureColor() {
+ return mCertainGestureColor;
+ }
+
+ public float getGestureStrokeWidth() {
+ return mGestureStrokeWidth;
+ }
+
+ public void setGestureStrokeWidth(float gestureStrokeWidth) {
+ mGestureStrokeWidth = gestureStrokeWidth;
+ mInvalidateExtraBorder = Math.max(1, ((int) gestureStrokeWidth) - 1);
+ mGesturePaint.setStrokeWidth(gestureStrokeWidth);
+ }
+
+ public int getGestureStrokeType() {
+ return mGestureStrokeType;
+ }
+
+ public void setGestureStrokeType(int gestureStrokeType) {
+ mGestureStrokeType = gestureStrokeType;
+ }
+
+ public float getGestureStrokeLengthThreshold() {
+ return mGestureStrokeLengthThreshold;
+ }
+
+ public void setGestureStrokeLengthThreshold(float gestureStrokeLengthThreshold) {
+ mGestureStrokeLengthThreshold = gestureStrokeLengthThreshold;
+ }
+
+ public float getGestureStrokeSquarenessTreshold() {
+ return mGestureStrokeSquarenessTreshold;
+ }
+
+ public void setGestureStrokeSquarenessTreshold(float gestureStrokeSquarenessTreshold) {
+ mGestureStrokeSquarenessTreshold = gestureStrokeSquarenessTreshold;
+ }
+
+ public float getGestureStrokeAngleThreshold() {
+ return mGestureStrokeAngleThreshold;
+ }
+
+ public void setGestureStrokeAngleThreshold(float gestureStrokeAngleThreshold) {
+ mGestureStrokeAngleThreshold = gestureStrokeAngleThreshold;
+ }
+
+ public boolean isEventsInterceptionEnabled() {
+ return mInterceptEvents;
+ }
+
+ public void setEventsInterceptionEnabled(boolean enabled) {
+ mInterceptEvents = enabled;
+ }
+
+ public boolean isFadeEnabled() {
+ return mFadeEnabled;
+ }
+
+ public void setFadeEnabled(boolean fadeEnabled) {
+ mFadeEnabled = fadeEnabled;
+ }
+
+ public Gesture getGesture() {
+ return mCurrentGesture;
+ }
+
+ public void setGesture(Gesture gesture) {
+ if (mCurrentGesture != null) {
+ clear(false);
+ }
+
+ setCurrentColor(mCertainGestureColor);
+ mCurrentGesture = gesture;
+
+ final Path path = mCurrentGesture.toPath();
+ final RectF bounds = new RectF();
+ path.computeBounds(bounds, true);
+
+ mPath.rewind();
+ mPath.addPath(path, (getWidth() - bounds.width()) / 2.0f,
+ (getHeight() - bounds.height()) / 2.0f);
+
+ invalidate();
+ }
+
+ public void addOnGestureListener(OnGestureListener listener) {
+ mOnGestureListeners.add(listener);
+ }
+
+ public void removeOnGestureListener(OnGestureListener listener) {
+ mOnGestureListeners.remove(listener);
+ }
+
+ public void removeAllOnGestureListeners() {
+ mOnGestureListeners.clear();
+ }
+
+ public void addOnGesturePerformedListener(OnGesturePerformedListener listener) {
+ mOnGesturePerformedListeners.add(listener);
+ if (mOnGesturePerformedListeners.size() > 0) {
+ mHandleGestureActions = true;
+ }
+ }
+
+ public void removeOnGesturePerformedListener(OnGesturePerformedListener listener) {
+ mOnGesturePerformedListeners.remove(listener);
+ if (mOnGesturePerformedListeners.size() <= 0) {
+ mHandleGestureActions = false;
+ }
+ }
+
+ public void removeAllOnGesturePerformedListeners() {
+ mOnGesturePerformedListeners.clear();
+ mHandleGestureActions = false;
+ }
+
+ public boolean isGesturing() {
+ return mIsGesturing;
+ }
+
+ private void setCurrentColor(int color) {
+ mCurrentColor = color;
+ if (mFadingHasStarted) {
+ setPaintAlpha((int) (255 * mFadingAlpha));
+ } else {
+ setPaintAlpha(255);
+ }
+ invalidate();
+ }
+
+ @Override
+ public void draw(Canvas canvas) {
+ super.draw(canvas);
+
+ if (mCurrentGesture != null) {
+ canvas.drawPath(mPath, mGesturePaint);
+ }
+ }
+
+ private void setPaintAlpha(int alpha) {
+ alpha += alpha >> 7;
+ final int baseAlpha = mCurrentColor >>> 24;
+ final int useAlpha = baseAlpha * alpha >> 8;
+ mGesturePaint.setColor((mCurrentColor << 8 >>> 8) | (useAlpha << 24));
+ }
+
+ public void clear(boolean animated) {
+ clear(animated, false);
+ }
+
+ private void clear(boolean animated, boolean fireActionPerformed) {
+ setPaintAlpha(255);
+ removeCallbacks(mFadingOut);
+ mFadingOut.fireActionPerformed = fireActionPerformed;
+
+ if (animated && mCurrentGesture != null) {
+ mFadingAlpha = 1.0f;
+ mIsFadingOut = true;
+ mFadingHasStarted = false;
+ mFadingStart = AnimationUtils.currentAnimationTimeMillis() + mFadeOffset;
+
+ postDelayed(mFadingOut, mFadeOffset);
+ } else {
+ mFadingAlpha = 1.0f;
+ mIsFadingOut = false;
+ mFadingHasStarted = false;
+
+ if (fireActionPerformed) {
+ post(mFadingOut);
+ } else {
+ mCurrentGesture = null;
+ mPath.rewind();
+ invalidate();
+ }
+ }
+ }
+
+ public void cancelClearAnimation() {
+ setPaintAlpha(255);
+ mIsFadingOut = false;
+ mFadingHasStarted = false;
+ removeCallbacks(mFadingOut);
+ mPath.rewind();
+ mCurrentGesture = null;
+ }
+
+ public void cancelGesture() {
+ mIsListeningForGestures = false;
+
+ // add the stroke to the current gesture
+ mCurrentGesture.addStroke(new GestureStroke(mStrokeBuffer));
+
+ // pass the event to handlers
+ final long now = SystemClock.uptimeMillis();
+ final MotionEvent event = MotionEvent.obtain(now, now,
+ MotionEvent.ACTION_CANCEL, 0.0f, 0.0f, 0);
+
+ final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
+ final int count = listeners.size();
+ for (int i = 0; i < count; i++) {
+ listeners.get(i).onGestureCancelled(this, event);
+ }
+
+ event.recycle();
+
+ clear(false);
+ mIsGesturing = false;
+ mStrokeBuffer.clear();
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ cancelClearAnimation();
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ if (isEnabled()) {
+ boolean cancelDispatch = (mIsGesturing || (mCurrentGesture != null &&
+ mCurrentGesture.getStrokesCount() > 0)) && mInterceptEvents;
+ processEvent(event);
+
+ if (cancelDispatch) {
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ }
+
+ super.dispatchTouchEvent(event);
+ return true;
+ }
+
+ return super.dispatchTouchEvent(event);
+ }
+
+ private boolean processEvent(MotionEvent event) {
+ switch (event.getAction()) {
+ case MotionEvent.ACTION_DOWN:
+ touchDown(event);
+ invalidate();
+ return true;
+ case MotionEvent.ACTION_MOVE:
+ if (mIsListeningForGestures) {
+ Rect rect = touchMove(event);
+ if (rect != null) {
+ invalidate(rect);
+ }
+ return true;
+ }
+ break;
+ case MotionEvent.ACTION_UP:
+ if (mIsListeningForGestures) {
+ touchUp(event, false);
+ invalidate();
+ return true;
+ }
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ if (mIsListeningForGestures) {
+ touchUp(event, true);
+ invalidate();
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private void touchDown(MotionEvent event) {
+ mIsListeningForGestures = true;
+
+ float x = event.getX();
+ float y = event.getY();
+
+ mX = x;
+ mY = y;
+
+ mTotalLength = 0;
+ mIsGesturing = false;
+
+ if (mGestureStrokeType == GESTURE_STROKE_TYPE_SINGLE) {
+ if (mHandleGestureActions) setCurrentColor(mUncertainGestureColor);
+ mCurrentGesture = null;
+ mPath.rewind();
+ } else if (mCurrentGesture == null || mCurrentGesture.getStrokesCount() == 0) {
+ if (mHandleGestureActions) setCurrentColor(mUncertainGestureColor);
+ }
+
+ // if there is fading out going on, stop it.
+ if (mFadingHasStarted) {
+ cancelClearAnimation();
+ } else if (mIsFadingOut) {
+ setPaintAlpha(255);
+ mIsFadingOut = false;
+ mFadingHasStarted = false;
+ removeCallbacks(mFadingOut);
+ }
+
+ if (mCurrentGesture == null) {
+ mCurrentGesture = new Gesture();
+ }
+
+ mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime()));
+ mPath.moveTo(x, y);
+
+ final int border = mInvalidateExtraBorder;
+ mInvalidRect.set((int) x - border, (int) y - border, (int) x + border, (int) y + border);
+
+ mCurveEndX = x;
+ mCurveEndY = y;
+
+ // pass the event to handlers
+ final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
+ final int count = listeners.size();
+ for (int i = 0; i < count; i++) {
+ listeners.get(i).onGestureStarted(this, event);
+ }
+ }
+
+ private Rect touchMove(MotionEvent event) {
+ Rect areaToRefresh = null;
+
+ final float x = event.getX();
+ final float y = event.getY();
+
+ final float previousX = mX;
+ final float previousY = mY;
+
+ final float dx = Math.abs(x - previousX);
+ final float dy = Math.abs(y - previousY);
+
+ if (dx >= GestureStroke.TOUCH_TOLERANCE || dy >= GestureStroke.TOUCH_TOLERANCE) {
+ areaToRefresh = mInvalidRect;
+
+ // start with the curve end
+ final int border = mInvalidateExtraBorder;
+ areaToRefresh.set((int) mCurveEndX - border, (int) mCurveEndY - border,
+ (int) mCurveEndX + border, (int) mCurveEndY + border);
+
+ float cX = mCurveEndX = (x + previousX) / 2;
+ float cY = mCurveEndY = (y + previousY) / 2;
+
+ mPath.quadTo(previousX, previousY, cX, cY);
+
+ // union with the control point of the new curve
+ areaToRefresh.union((int) previousX - border, (int) previousY - border,
+ (int) previousX + border, (int) previousY + border);
+
+ // union with the end point of the new curve
+ areaToRefresh.union((int) cX - border, (int) cY - border,
+ (int) cX + border, (int) cY + border);
+
+ mX = x;
+ mY = y;
+ }
+
+ mStrokeBuffer.add(new GesturePoint(x, y, event.getEventTime()));
+
+ if (mHandleGestureActions && !mIsGesturing) {
+ mTotalLength += (float) Math.sqrt(dx * dx + dy * dy);
+
+ if (mTotalLength > mGestureStrokeLengthThreshold) {
+ final OrientedBoundingBox box =
+ GestureUtilities.computeOrientedBoundingBox(mStrokeBuffer);
+
+ float angle = Math.abs(box.orientation);
+ if (angle > 90) {
+ angle = 180 - angle;
+ }
+
+ if (box.squareness > mGestureStrokeSquarenessTreshold ||
+ (mOrientation == ORIENTATION_VERTICAL ?
+ angle < mGestureStrokeAngleThreshold :
+ angle > mGestureStrokeAngleThreshold)) {
+
+ mIsGesturing = true;
+ setCurrentColor(mCertainGestureColor);
+ }
+ }
+ }
+
+ // pass the event to handlers
+ final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
+ final int count = listeners.size();
+ for (int i = 0; i < count; i++) {
+ listeners.get(i).onGesture(this, event);
+ }
+
+ return areaToRefresh;
+ }
+
+ private void touchUp(MotionEvent event, boolean cancel) {
+ mIsListeningForGestures = false;
+
+ // add the stroke to the current gesture
+ mCurrentGesture.addStroke(new GestureStroke(mStrokeBuffer));
+ mStrokeBuffer.clear();
+
+ if (!cancel) {
+ // pass the event to handlers
+ final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
+ int count = listeners.size();
+ for (int i = 0; i < count; i++) {
+ listeners.get(i).onGestureEnded(this, event);
+ }
+
+ if (mHandleGestureActions) {
+ clear(mFadeEnabled, mIsGesturing);
+ }
+ } else {
+ // pass the event to handlers
+ final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
+ final int count = listeners.size();
+ for (int i = 0; i < count; i++) {
+ listeners.get(i).onGestureCancelled(this, event);
+ }
+
+ clear(false);
+ }
+
+ mIsGesturing = false;
+ }
+
+ private void fireOnGesturePerformed() {
+ final ArrayList<OnGesturePerformedListener> actionListeners =
+ mOnGesturePerformedListeners;
+ final int count = actionListeners.size();
+ for (int i = 0; i < count; i++) {
+ actionListeners.get(i).onGesturePerformed(GestureOverlayView.this,
+ mCurrentGesture);
+ }
+ }
+
+ private class FadeOutRunnable implements Runnable {
+ boolean fireActionPerformed;
+
+ public void run() {
+ if (mIsFadingOut) {
+ final long now = AnimationUtils.currentAnimationTimeMillis();
+ final long duration = now - mFadingStart;
+
+ if (duration > mFadeDuration) {
+ if (fireActionPerformed) {
+ fireOnGesturePerformed();
+ }
+
+ mIsFadingOut = false;
+ mFadingHasStarted = false;
+ mPath.rewind();
+ mCurrentGesture = null;
+ setPaintAlpha(255);
+ } else {
+ mFadingHasStarted = true;
+ float interpolatedTime = Math.max(0.0f,
+ Math.min(1.0f, duration / (float) mFadeDuration));
+ mFadingAlpha = 1.0f - mInterpolator.getInterpolation(interpolatedTime);
+ setPaintAlpha((int) (255 * mFadingAlpha));
+ postDelayed(this, FADE_ANIMATION_RATE);
+ }
+ } else {
+ fireOnGesturePerformed();
+
+ mFadingHasStarted = false;
+ mPath.rewind();
+ mCurrentGesture = null;
+ setPaintAlpha(255);
+ }
+
+ invalidate();
+ }
+ }
+
+ public static interface OnGestureListener {
+ void onGestureStarted(GestureOverlayView overlay, MotionEvent event);
+
+ void onGesture(GestureOverlayView overlay, MotionEvent event);
+
+ void onGestureEnded(GestureOverlayView overlay, MotionEvent event);
+
+ void onGestureCancelled(GestureOverlayView overlay, MotionEvent event);
+ }
+
+ public static interface OnGesturePerformedListener {
+ void onGesturePerformed(GestureOverlayView overlay, Gesture gesture);
+ }
+}
diff --git a/tests/sketch/src/com/android/gesture/GesturePoint.java b/core/java/android/gesture/GesturePoint.java
index 81e59a4..3698011 100644
--- a/tests/sketch/src/com/android/gesture/GesturePoint.java
+++ b/core/java/android/gesture/GesturePoint.java
@@ -14,7 +14,10 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
+
+import java.io.DataInputStream;
+import java.io.IOException;
/**
* A timed point of a gesture stroke
@@ -31,4 +34,13 @@ public class GesturePoint {
this.y = y;
timestamp = t;
}
+
+ static GesturePoint deserialize(DataInputStream in) throws IOException {
+ // Read X and Y
+ final float x = in.readFloat();
+ final float y = in.readFloat();
+ // Read timestamp
+ final long timeStamp = in.readLong();
+ return new GesturePoint(x, y, timeStamp);
+ }
}
diff --git a/tests/sketch/src/com/android/gesture/GestureStroke.java b/core/java/android/gesture/GestureStroke.java
index 3555010..0d7bc2d 100644
--- a/tests/sketch/src/com/android/gesture/GestureStroke.java
+++ b/core/java/android/gesture/GestureStroke.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 The Android Open Source Project
+ * 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.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
import android.graphics.Canvas;
import android.graphics.Matrix;
@@ -22,15 +22,17 @@ import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.RectF;
-import org.xmlpull.v1.XmlSerializer;
-
import java.io.IOException;
+import java.io.DataOutputStream;
+import java.io.DataInputStream;
import java.util.ArrayList;
/**
* A gesture stroke started on a touch down and ended on a touch up.
*/
public class GestureStroke {
+ static final float TOUCH_TOLERANCE = 3;
+
public final RectF boundingBox;
public final float length;
@@ -87,37 +89,49 @@ public class GestureStroke {
*/
void draw(Canvas canvas, Paint paint) {
if (mCachedPath == null) {
- final float[] localPoints = points;
- final int count = localPoints.length;
+ makePath();
+ }
- Path path = null;
+ canvas.drawPath(mCachedPath, paint);
+ }
+
+ public Path getPath() {
+ if (mCachedPath == null) {
+ makePath();
+ }
+
+ return mCachedPath;
+ }
+
+ private void makePath() {
+ final float[] localPoints = points;
+ final int count = localPoints.length;
+
+ Path path = null;
- float mX = 0;
- float mY = 0;
+ float mX = 0;
+ float mY = 0;
- for (int i = 0; i < count; i += 2) {
- float x = localPoints[i];
- float y = localPoints[i + 1];
- if (path == null) {
- path = new Path();
- path.moveTo(x, y);
+ for (int i = 0; i < count; i += 2) {
+ float x = localPoints[i];
+ float y = localPoints[i + 1];
+ if (path == null) {
+ path = new Path();
+ path.moveTo(x, y);
+ mX = x;
+ mY = y;
+ } else {
+ float dx = Math.abs(x - mX);
+ float dy = Math.abs(y - mY);
+ if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
+ path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
- } else {
- float dx = Math.abs(x - mX);
- float dy = Math.abs(y - mY);
- if (dx >= 3 || dy >= 3) {
- path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
- mX = x;
- mY = y;
- }
}
}
-
- mCachedPath = path;
}
- canvas.drawPath(mCachedPath, paint);
+ mCachedPath = path;
}
/**
@@ -126,16 +140,16 @@ public class GestureStroke {
* @param width the width of the bounding box of the target path
* @param height the height of the bounding box of the target path
* @param numSample the number of points needed
+ *
* @return the path
*/
public Path toPath(float width, float height, int numSample) {
final float[] pts = GestureUtilities.temporalSampling(this, numSample);
final RectF rect = boundingBox;
- final float scale = height / rect.height();
final Matrix matrix = new Matrix();
matrix.setTranslate(-rect.left, -rect.top);
- matrix.postScale(scale, scale);
+ matrix.postScale(width / rect.width(), height / rect.height());
matrix.mapPoints(pts);
float mX = 0;
@@ -156,7 +170,7 @@ public class GestureStroke {
} else {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
- if (dx >= GestureOverlay.TOUCH_TOLERANCE || dy >= GestureOverlay.TOUCH_TOLERANCE) {
+ if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
path.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
@@ -167,81 +181,48 @@ public class GestureStroke {
return path;
}
- /**
- * Save the gesture stroke as XML
- *
- * @param namespace
- * @param serializer
- * @throws IOException
- */
- void toXML(String namespace, XmlSerializer serializer) throws IOException {
- serializer.startTag(namespace, GestureConstants.XML_TAG_STROKE);
- serializer.text(toString());
- serializer.endTag(namespace, GestureConstants.XML_TAG_STROKE);
+ void serialize(DataOutputStream out) throws IOException {
+ final float[] pts = points;
+ final long[] times = timestamps;
+ final int count = points.length;
+
+ // Write number of points
+ out.writeInt(count / 2);
+
+ for (int i = 0; i < count; i += 2) {
+ // Write X
+ out.writeFloat(pts[i]);
+ // Write Y
+ out.writeFloat(pts[i + 1]);
+ // Write timestamp
+ out.writeLong(times[i / 2]);
+ }
}
- /**
- * Create a gesture stroke from a string
- *
- * @param str
- * @return the gesture stroke
- */
- public static GestureStroke createFromString(String str) {
- final ArrayList<GesturePoint> points = new ArrayList<GesturePoint>(
- GestureConstants.STROKE_POINT_BUFFER_SIZE);
-
- int endIndex;
- int startIndex = 0;
-
- while ((endIndex =
- str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1)) != -1) {
-
- // parse x
- String token = str.substring(startIndex, endIndex);
- float x = Float.parseFloat(token);
- startIndex = endIndex + 1;
-
- // parse y
- endIndex = str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1);
- token = str.substring(startIndex, endIndex);
- float y = Float.parseFloat(token);
- startIndex = endIndex + 1;
-
- // parse t
- endIndex = str.indexOf(GestureConstants.STRING_STROKE_DELIIMITER, startIndex + 1);
- token = str.substring(startIndex, endIndex);
- long time = Long.parseLong(token);
- startIndex = endIndex + 1;
-
- points.add(new GesturePoint(x, y, time));
+ static GestureStroke deserialize(DataInputStream in) throws IOException {
+ // Number of points
+ final int count = in.readInt();
+
+ final ArrayList<GesturePoint> points = new ArrayList<GesturePoint>(count);
+ for (int i = 0; i < count; i++) {
+ points.add(GesturePoint.deserialize(in));
}
return new GestureStroke(points);
- }
+ }
/**
- * Convert the stroke to string
+ * Invalidate the cached path that is used to render the stroke
*/
- @Override
- public String toString() {
- final StringBuilder str = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
- final float[] pts = points;
- final long[] times = timestamps;
- final int count = points.length;
-
- for (int i = 0; i < count; i += 2) {
- str.append(pts[i]).append(GestureConstants.STRING_STROKE_DELIIMITER);
- str.append(pts[i + 1]).append(GestureConstants.STRING_STROKE_DELIIMITER);
- str.append(times[i / 2]).append(GestureConstants.STRING_STROKE_DELIIMITER);
- }
-
- return str.toString();
+ public void clearPath() {
+ if (mCachedPath != null) mCachedPath.rewind();
}
-
+
/**
- * Invalidate the cached path that is used for rendering the stroke
+ * Compute an oriented bounding box of the stroke
+ * @return OrientedBoundingBox
*/
- public void invalidate() {
- mCachedPath = null;
+ public OrientedBoundingBox computeOrientedBoundingBox() {
+ return GestureUtilities.computeOrientedBoundingBox(points);
}
}
diff --git a/tests/sketch/src/com/android/gesture/GestureUtilities.java b/core/java/android/gesture/GestureUtilities.java
index 2798616..0f9253d 100755
--- a/tests/sketch/src/com/android/gesture/GestureUtilities.java
+++ b/core/java/android/gesture/GestureUtilities.java
@@ -14,19 +14,20 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
import android.graphics.RectF;
import android.graphics.Matrix;
+import android.util.Log;
import java.util.ArrayList;
import java.util.Arrays;
import java.io.Closeable;
import java.io.IOException;
-import static com.android.gesture.GestureConstants.*;
+import static android.gesture.GestureConstants.*;
-public final class GestureUtilities {
+final class GestureUtilities {
private static final int TEMPORAL_SAMPLING_RATE = 16;
private GestureUtilities() {
@@ -42,7 +43,7 @@ public final class GestureUtilities {
try {
stream.close();
} catch (IOException e) {
- android.util.Log.e(LOG_TAG, "Could not close stream", e);
+ Log.e(LOG_TAG, "Could not close stream", e);
}
}
}
@@ -56,24 +57,25 @@ public final class GestureUtilities {
float sx = targetPatchSize / rect.width();
float sy = targetPatchSize / rect.height();
float scale = sx < sy ? sx : sy;
- android.graphics.Matrix trans = new android.graphics.Matrix();
+
+ Matrix trans = new Matrix();
trans.setScale(scale, scale);
- android.graphics.Matrix translate1 = new android.graphics.Matrix();
- translate1.setTranslate(-rect.centerX(), -rect.centerY());
- trans.preConcat(translate1);
- android.graphics.Matrix translate2 = new android.graphics.Matrix();
- translate2.setTranslate(targetPatchSize / 2, targetPatchSize / 2);
- trans.postConcat(translate2);
-
- ArrayList<GestureStroke> strokes = gesture.getStrokes();
- int count = strokes.size();
+ trans.preTranslate(-rect.centerX(), -rect.centerY());
+ trans.postTranslate(targetPatchSize / 2, targetPatchSize / 2);
+
+ final ArrayList<GestureStroke> strokes = gesture.getStrokes();
+ final int count = strokes.size();
+
int size;
float xpos;
float ypos;
+
for (int index = 0; index < count; index++) {
- GestureStroke stroke = strokes.get(index);
+ final GestureStroke stroke = strokes.get(index);
size = stroke.points.length;
- float[] pts = new float[size];
+
+ final float[] pts = new float[size];
+
trans.mapPoints(pts, 0, stroke.points, 0, size / 2);
float segmentEndX = -1;
float segmentEndY = -1;
@@ -348,33 +350,31 @@ public final class GestureUtilities {
/**
* Calculate the cosine distance between two instances
*
- * @param in1
- * @param in2
+ * @param vector1
+ * @param vector2
* @return the distance between 0 and Math.PI
*/
- static double cosineDistance(Instance in1, Instance in2) {
+ static double cosineDistance(float[] vector1, float[] vector2) {
float sum = 0;
- float[] vector1 = in1.vector;
- float[] vector2 = in2.vector;
int len = vector1.length;
for (int i = 0; i < len; i++) {
sum += vector1[i] * vector2[i];
}
- return Math.acos(sum / (in1.magnitude * in2.magnitude));
+ return Math.acos(sum);
}
- public static OrientedBoundingBox computeOrientedBoundingBox(ArrayList<GesturePoint> pts) {
+ static OrientedBoundingBox computeOrientedBoundingBox(ArrayList<GesturePoint> pts) {
GestureStroke stroke = new GestureStroke(pts);
float[] points = temporalSampling(stroke, TEMPORAL_SAMPLING_RATE);
return computeOrientedBoundingBox(points);
}
- public static OrientedBoundingBox computeOrientedBoundingBox(float[] points) {
+ static OrientedBoundingBox computeOrientedBoundingBox(float[] points) {
float[] meanVector = computeCentroid(points);
return computeOrientedBoundingBox(points, meanVector);
}
- public static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) {
+ static OrientedBoundingBox computeOrientedBoundingBox(float[] points, float[] centroid) {
Matrix tr = new Matrix();
tr.setTranslate(-centroid[0], -centroid[1]);
tr.mapPoints(points);
@@ -388,7 +388,7 @@ public final class GestureUtilities {
} else { // -PI<alpha<PI
angle = (float) Math.atan2(targetVector[1], targetVector[0]);
angle = (float) (180 * angle / Math.PI);
- android.graphics.Matrix trans = new android.graphics.Matrix();
+ Matrix trans = new Matrix();
trans.setRotate(-angle);
trans.mapPoints(points);
}
diff --git a/tests/sketch/src/com/android/gesture/Instance.java b/core/java/android/gesture/Instance.java
index 011d1fc..7922fab 100755
--- a/tests/sketch/src/com/android/gesture/Instance.java
+++ b/core/java/android/gesture/Instance.java
@@ -14,7 +14,9 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
+
+import android.graphics.Matrix;
/**
* An instance represents a sample if the label is available or a query if the
@@ -23,7 +25,7 @@ package com.android.gesture;
class Instance {
private static final int SEQUENCE_SAMPLE_SIZE = 16;
- private static final int PATCH_SAMPLE_SIZE = 8;
+ private static final int PATCH_SAMPLE_SIZE = 16;
private final static float[] ORIENTATIONS = {
0, 45, 90, 135, 180, -0, -45, -90, -135, -180
@@ -35,22 +37,28 @@ class Instance {
// the label can be null
final String label;
- // the length of the vector
- final float magnitude;
-
// the id of the instance
final long id;
-
+
private Instance(long id, float[] sample, String sampleName) {
this.id = id;
vector = sample;
label = sampleName;
+ }
+
+ private void normalize() {
+ float[] sample = vector;
float sum = 0;
+
int size = sample.length;
for (int i = 0; i < size; i++) {
sum += sample[i] * sample[i];
}
- magnitude = (float) Math.sqrt(sum);
+
+ float magnitude = (float) Math.sqrt(sum);
+ for (int i = 0; i < size; i++) {
+ sample[i] /= magnitude;
+ }
}
/**
@@ -60,21 +68,25 @@ class Instance {
* @param label
* @return the instance
*/
- static Instance createInstance(GestureLibrary gesturelib, Gesture gesture, String label) {
+ static Instance createInstance(int samplingType, Gesture gesture, String label) {
float[] pts;
- if (gesturelib.getGestureType() == GestureLibrary.SEQUENCE_SENSITIVE) {
- pts = temporalSampler(gesturelib, gesture);
+ Instance instance;
+ if (samplingType == GestureLibrary.SEQUENCE_SENSITIVE) {
+ pts = temporalSampler(samplingType, gesture);
+ instance = new Instance(gesture.getID(), pts, label);
+ instance.normalize();
} else {
pts = spatialSampler(gesture);
+ instance = new Instance(gesture.getID(), pts, label);
}
- return new Instance(gesture.getID(), pts, label);
+ return instance;
}
-
+
private static float[] spatialSampler(Gesture gesture) {
return GestureUtilities.spatialSampling(gesture, PATCH_SAMPLE_SIZE);
}
- private static float[] temporalSampler(GestureLibrary gesturelib, Gesture gesture) {
+ private static float[] temporalSampler(int samplingType, Gesture gesture) {
float[] pts = GestureUtilities.temporalSampling(gesture.getStrokes().get(0),
SEQUENCE_SAMPLE_SIZE);
float[] center = GestureUtilities.computeCentroid(pts);
@@ -82,7 +94,7 @@ class Instance {
orientation *= 180 / Math.PI;
float adjustment = -orientation;
- if (gesturelib.getOrientationStyle() == GestureLibrary.ORIENTATION_SENSITIVE) {
+ if (samplingType == GestureLibrary.ORIENTATION_SENSITIVE) {
int count = ORIENTATIONS.length;
for (int i = 0; i < count; i++) {
float delta = ORIENTATIONS[i] - orientation;
@@ -92,12 +104,11 @@ class Instance {
}
}
- android.graphics.Matrix m = new android.graphics.Matrix();
+ Matrix m = new Matrix();
m.setTranslate(-center[0], -center[1]);
- android.graphics.Matrix rotation = new android.graphics.Matrix();
- rotation.setRotate(adjustment);
- m.postConcat(rotation);
+ m.postRotate(adjustment);
m.mapPoints(pts);
+
return pts;
}
diff --git a/tests/sketch/src/com/android/gesture/InstanceLearner.java b/core/java/android/gesture/InstanceLearner.java
index 335719a..1739cdc 100644
--- a/tests/sketch/src/com/android/gesture/InstanceLearner.java
+++ b/core/java/android/gesture/InstanceLearner.java
@@ -14,10 +14,11 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
import android.util.Config;
import android.util.Log;
+import static android.gesture.GestureConstants.*;
import java.util.ArrayList;
import java.util.Collections;
@@ -30,25 +31,22 @@ import java.util.TreeMap;
*/
class InstanceLearner extends Learner {
-
- private static final String LOGTAG = "InstanceLearner";
-
@Override
- ArrayList<Prediction> classify(GestureLibrary lib, Instance instance) {
+ ArrayList<Prediction> classify(int gestureType, float[] vector) {
ArrayList<Prediction> predictions = new ArrayList<Prediction>();
ArrayList<Instance> instances = getInstances();
int count = instances.size();
TreeMap<String, Double> label2score = new TreeMap<String, Double>();
for (int i = 0; i < count; i++) {
Instance sample = instances.get(i);
- if (sample.vector.length != instance.vector.length) {
+ if (sample.vector.length != vector.length) {
continue;
}
double distance;
- if (lib.getGestureType() == GestureLibrary.SEQUENCE_SENSITIVE) {
- distance = GestureUtilities.cosineDistance(sample, instance);
+ if (gestureType == GestureLibrary.SEQUENCE_SENSITIVE) {
+ distance = GestureUtilities.cosineDistance(sample.vector, vector);
} else {
- distance = GestureUtilities.squaredEuclideanDistance(sample.vector, instance.vector);
+ distance = GestureUtilities.squaredEuclideanDistance(sample.vector, vector);
}
double weight;
if (distance == 0) {
@@ -63,19 +61,15 @@ class InstanceLearner extends Learner {
}
double sum = 0;
- Iterator<String> lableIterator = label2score.keySet().iterator();
- while (lableIterator.hasNext()) {
- String name = lableIterator.next();
+ for (String name : label2score.keySet()) {
double score = label2score.get(name);
sum += score;
predictions.add(new Prediction(name, score));
}
// normalize
- Iterator<Prediction> predictionIterator = predictions.iterator();
- while (predictionIterator.hasNext()) {
- Prediction name = predictionIterator.next();
- name.score /= sum;
+ for (Prediction prediction : predictions) {
+ prediction.score /= sum;
}
Collections.sort(predictions, new Comparator<Prediction>() {
@@ -92,14 +86,6 @@ class InstanceLearner extends Learner {
}
});
- if (Config.DEBUG) {
- predictionIterator = predictions.iterator();
- while (predictionIterator.hasNext()) {
- Prediction name = predictionIterator.next();
- Log.v(LOGTAG, "prediction [" + name.name + " = " + name.score + "]");
- }
- }
-
return predictions;
}
}
diff --git a/tests/sketch/src/com/android/gesture/Learner.java b/core/java/android/gesture/Learner.java
index b4183d2..feacde5 100755
--- a/tests/sketch/src/com/android/gesture/Learner.java
+++ b/core/java/android/gesture/Learner.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
import java.util.ArrayList;
@@ -79,5 +79,5 @@ abstract class Learner {
instances.removeAll(toDelete);
}
- abstract ArrayList<Prediction> classify(GestureLibrary library, Instance instance);
+ abstract ArrayList<Prediction> classify(int gestureType, float[] vector);
}
diff --git a/core/java/android/gesture/LetterRecognizer.java b/core/java/android/gesture/LetterRecognizer.java
new file mode 100644
index 0000000..b26b3f2
--- /dev/null
+++ b/core/java/android/gesture/LetterRecognizer.java
@@ -0,0 +1,280 @@
+/*
+ * 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 android.gesture;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.util.Log;
+
+import java.io.BufferedInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+
+import static android.gesture.GestureConstants.LOG_TAG;
+
+public class LetterRecognizer {
+ public final static int RECOGNIZER_LATIN_LOWERCASE = 0;
+ static final String GESTURE_FILE_NAME = "letters.gestures";
+
+ private final static int ADJUST_RANGE = 3;
+
+ private SigmoidUnit[] mHiddenLayer;
+ private SigmoidUnit[] mOutputLayer;
+
+ private final String[] mClasses;
+
+ private final int mPatchSize;
+
+ private GestureLibrary mGestureLibrary;
+
+ private final Comparator<Prediction> mComparator = new PredictionComparator();
+
+ private static class SigmoidUnit {
+ final float[] mWeights;
+
+ SigmoidUnit(float[] weights) {
+ mWeights = weights;
+ }
+
+ private float compute(float[] inputs) {
+ float sum = 0;
+
+ final int count = inputs.length;
+ final float[] weights = mWeights;
+
+ for (int i = 0; i < count; i++) {
+ sum += inputs[i] * weights[i];
+ }
+ sum += weights[weights.length - 1];
+
+ return 1.0f / (float) (1 + Math.exp(-sum));
+ }
+ }
+
+ public static LetterRecognizer getLetterRecognizer(Context context, int type) {
+ switch (type) {
+ case RECOGNIZER_LATIN_LOWERCASE: {
+ return createFromResource(context, com.android.internal.R.raw.latin_lowercase);
+ }
+ }
+ return null;
+ }
+
+ private LetterRecognizer(int numOfInput, int numOfHidden, String[] classes) {
+ mPatchSize = (int) Math.sqrt(numOfInput);
+ mHiddenLayer = new SigmoidUnit[numOfHidden];
+ mClasses = classes;
+ mOutputLayer = new SigmoidUnit[classes.length];
+ }
+
+ public ArrayList<Prediction> recognize(Gesture gesture) {
+ return recognize(gesture, null);
+ }
+
+ public ArrayList<Prediction> recognize(Gesture gesture, ArrayList<Prediction> predictions) {
+ float[] query = GestureUtilities.spatialSampling(gesture, mPatchSize);
+ predictions = classify(query, predictions);
+ adjustPrediction(gesture, predictions);
+ return predictions;
+ }
+
+ private ArrayList<Prediction> classify(float[] vector, ArrayList<Prediction> predictions) {
+ if (predictions == null) {
+ predictions = new ArrayList<Prediction>();
+ } else {
+ predictions.clear();
+ }
+
+ final float[] intermediateOutput = compute(mHiddenLayer, vector);
+ final float[] output = compute(mOutputLayer, intermediateOutput);
+
+ double sum = 0;
+
+ final String[] classes = mClasses;
+ final int count = classes.length;
+
+ for (int i = 0; i < count; i++) {
+ double score = output[i];
+ sum += score;
+ predictions.add(new Prediction(classes[i], score));
+ }
+
+ for (int i = 0; i < count; i++) {
+ predictions.get(i).score /= sum;
+ }
+
+ Collections.sort(predictions, mComparator);
+
+ return predictions;
+ }
+
+ private float[] compute(SigmoidUnit[] layer, float[] input) {
+ final float[] output = new float[layer.length];
+ final int count = layer.length;
+
+ for (int i = 0; i < count; i++) {
+ output[i] = layer[i].compute(input);
+ }
+
+ return output;
+ }
+
+ private static LetterRecognizer createFromResource(Context context, int resourceID) {
+ final Resources resources = context.getResources();
+
+ DataInputStream in = null;
+ LetterRecognizer classifier = null;
+
+ try {
+ in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID),
+ GestureConstants.IO_BUFFER_SIZE));
+
+ final int version = in.readShort();
+
+ switch (version) {
+ case 1:
+ classifier = readV1(in);
+ break;
+ }
+
+ } catch (IOException e) {
+ Log.d(LOG_TAG, "Failed to load handwriting data:", e);
+ } finally {
+ GestureUtilities.closeStream(in);
+ }
+
+ return classifier;
+ }
+
+ private static LetterRecognizer readV1(DataInputStream in) throws IOException {
+
+ final int iCount = in.readInt();
+ final int hCount = in.readInt();
+ final int oCount = in.readInt();
+
+ final String[] classes = new String[oCount];
+ for (int i = 0; i < classes.length; i++) {
+ classes[i] = in.readUTF();
+ }
+
+ final LetterRecognizer classifier = new LetterRecognizer(iCount, hCount, classes);
+ final SigmoidUnit[] hiddenLayer = new SigmoidUnit[hCount];
+ final SigmoidUnit[] outputLayer = new SigmoidUnit[oCount];
+
+ for (int i = 0; i < hCount; i++) {
+ final float[] weights = new float[iCount + 1];
+ for (int j = 0; j <= iCount; j++) {
+ weights[j] = in.readFloat();
+ }
+ hiddenLayer[i] = new SigmoidUnit(weights);
+ }
+
+ for (int i = 0; i < oCount; i++) {
+ final float[] weights = new float[hCount + 1];
+ for (int j = 0; j <= hCount; j++) {
+ weights[j] = in.readFloat();
+ }
+ outputLayer[i] = new SigmoidUnit(weights);
+ }
+
+ classifier.mHiddenLayer = hiddenLayer;
+ classifier.mOutputLayer = outputLayer;
+
+ return classifier;
+ }
+
+ /**
+ * TODO: Publish this API once we figure out where we should save the personzlied
+ * gestures, and how to do so across all apps
+ *
+ * @hide
+ */
+ public boolean save() {
+ if (mGestureLibrary != null) {
+ return mGestureLibrary.save();
+ }
+ return false;
+ }
+
+ /**
+ * TODO: Publish this API once we figure out where we should save the personzlied
+ * gestures, and how to do so across all apps
+ *
+ * @hide
+ */
+ public void setPersonalizationEnabled(boolean enabled) {
+ if (enabled) {
+ mGestureLibrary = new GestureLibrary(GESTURE_FILE_NAME);
+ mGestureLibrary.setSequenceType(GestureLibrary.SEQUENCE_INVARIANT);
+ mGestureLibrary.load();
+ } else {
+ mGestureLibrary = null;
+ }
+ }
+
+ /**
+ * TODO: Publish this API once we figure out where we should save the personzlied
+ * gestures, and how to do so across all apps
+ *
+ * @hide
+ */
+ public void addExample(String letter, Gesture example) {
+ if (mGestureLibrary != null) {
+ mGestureLibrary.addGesture(letter, example);
+ }
+ }
+
+ private void adjustPrediction(Gesture query, ArrayList<Prediction> predictions) {
+ if (mGestureLibrary != null) {
+ final ArrayList<Prediction> results = mGestureLibrary.recognize(query);
+ final HashMap<String, Prediction> topNList = new HashMap<String, Prediction>();
+
+ for (int j = 0; j < ADJUST_RANGE; j++) {
+ Prediction prediction = predictions.remove(0);
+ topNList.put(prediction.name, prediction);
+ }
+
+ final int count = results.size();
+ for (int j = count - 1; j >= 0 && !topNList.isEmpty(); j--) {
+ final Prediction item = results.get(j);
+ final Prediction original = topNList.get(item.name);
+ if (original != null) {
+ predictions.add(0, original);
+ topNList.remove(item.name);
+ }
+ }
+ }
+ }
+
+ private static class PredictionComparator implements Comparator<Prediction> {
+ public int compare(Prediction object1, Prediction object2) {
+ double score1 = object1.score;
+ double score2 = object2.score;
+ if (score1 > score2) {
+ return -1;
+ } else if (score1 < score2) {
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+ }
+}
diff --git a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java b/core/java/android/gesture/OrientedBoundingBox.java
index a07d125..f1335ee 100644
--- a/tests/sketch/src/com/android/gesture/OrientedBoundingBox.java
+++ b/core/java/android/gesture/OrientedBoundingBox.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
import android.graphics.Matrix;
import android.graphics.Path;
@@ -47,6 +47,11 @@ public class OrientedBoundingBox {
}
}
+ /**
+ * Currently used for debugging purpose only.
+ *
+ * @hide
+ */
public Path toPath() {
Path path = new Path();
float[] point = new float[2];
diff --git a/tests/sketch/src/com/android/gesture/Prediction.java b/core/java/android/gesture/Prediction.java
index 92d3ba4..ce6ad57 100755
--- a/tests/sketch/src/com/android/gesture/Prediction.java
+++ b/core/java/android/gesture/Prediction.java
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
public class Prediction {
public final String name;
diff --git a/core/java/android/hardware/ISensorService.aidl b/core/java/android/hardware/ISensorService.aidl
index 04af2ae..67180bd 100644
--- a/core/java/android/hardware/ISensorService.aidl
+++ b/core/java/android/hardware/ISensorService.aidl
@@ -17,13 +17,13 @@
package android.hardware;
-import android.os.ParcelFileDescriptor;
+import android.os.Bundle;
/**
* {@hide}
*/
interface ISensorService
{
- ParcelFileDescriptor getDataChanel();
+ Bundle getDataChannel();
boolean enableSensor(IBinder listener, String name, int sensor, int enable);
}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index 67df23b..bf945ec 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -18,7 +18,9 @@ package android.hardware;
import android.content.Context;
import android.os.Binder;
+import android.os.Bundle;
import android.os.Looper;
+import android.os.Parcelable;
import android.os.ParcelFileDescriptor;
import android.os.Process;
import android.os.RemoteException;
@@ -280,8 +282,8 @@ public class SensorManager
void startLocked(ISensorService service) {
try {
if (mThread == null) {
- ParcelFileDescriptor fd = service.getDataChanel();
- mThread = new Thread(new SensorThreadRunnable(fd),
+ Bundle dataChannel = service.getDataChannel();
+ mThread = new Thread(new SensorThreadRunnable(dataChannel),
SensorThread.class.getName());
mThread.start();
}
@@ -291,10 +293,52 @@ public class SensorManager
}
private class SensorThreadRunnable implements Runnable {
- private ParcelFileDescriptor mSensorDataFd;
- SensorThreadRunnable(ParcelFileDescriptor fd) {
- mSensorDataFd = fd;
+ private Bundle mDataChannel;
+ SensorThreadRunnable(Bundle dataChannel) {
+ mDataChannel = dataChannel;
}
+
+ private boolean open() {
+ if (mDataChannel == null) {
+ Log.e(TAG, "mDataChannel == NULL, exiting");
+ synchronized (sListeners) {
+ mThread = null;
+ }
+ return false;
+ }
+
+ // this thread is guaranteed to be unique
+ Parcelable[] pfds = mDataChannel.getParcelableArray("fds");
+ FileDescriptor[] fds;
+ if (pfds != null) {
+ int length = pfds.length;
+ fds = new FileDescriptor[length];
+ for (int i = 0; i < length; i++) {
+ ParcelFileDescriptor pfd = (ParcelFileDescriptor)pfds[i];
+ fds[i] = pfd.getFileDescriptor();
+ }
+ } else {
+ fds = null;
+ }
+ int[] ints = mDataChannel.getIntArray("ints");
+ sensors_data_open(fds, ints);
+ if (pfds != null) {
+ try {
+ // close our copies of the file descriptors,
+ // since we are just passing these to the JNI code and not using them here.
+ for (int i = pfds.length - 1; i >= 0; i--) {
+ ParcelFileDescriptor pfd = (ParcelFileDescriptor)pfds[i];
+ pfd.close();
+ }
+ } catch (IOException e) {
+ // *shrug*
+ Log.e(TAG, "IOException: ", e);
+ }
+ }
+ mDataChannel = null;
+ return true;
+ }
+
public void run() {
//Log.d(TAG, "entering main sensor thread");
final float[] values = new float[3];
@@ -302,23 +346,9 @@ public class SensorManager
final long timestamp[] = new long[1];
Process.setThreadPriority(Process.THREAD_PRIORITY_DISPLAY);
- if (mSensorDataFd == null) {
- Log.e(TAG, "mSensorDataFd == NULL, exiting");
- synchronized (sListeners) {
- mThread = null;
- }
+ if (!open()) {
return;
}
- // this thread is guaranteed to be unique
- sensors_data_open(mSensorDataFd.getFileDescriptor());
- try {
- mSensorDataFd.close();
- } catch (IOException e) {
- // *shrug*
- Log.e(TAG, "IOException: ", e);
- }
- mSensorDataFd = null;
-
while (true) {
// wait for an event
@@ -1469,7 +1499,7 @@ public class SensorManager
// Used within this module from outside SensorManager, don't make private
static native int sensors_data_init();
static native int sensors_data_uninit();
- static native int sensors_data_open(FileDescriptor fd);
+ static native int sensors_data_open(FileDescriptor[] fds, int[] ints);
static native int sensors_data_close();
static native int sensors_data_poll(float[] values, int[] status, long[] timestamp);
}
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index 8a0fd58..358a546 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -69,6 +69,20 @@ public abstract class BatteryStats implements Parcelable {
public static final int WIFI_MULTICAST_ENABLED = 7;
/**
+ * A constant indicating an audio turn on timer
+ *
+ * {@hide}
+ */
+ public static final int AUDIO_TURNED_ON = 7;
+
+ /**
+ * A constant indicating a video turn on timer
+ *
+ * {@hide}
+ */
+ public static final int VIDEO_TURNED_ON = 8;
+
+ /**
* Include all of the data in the stats, including previously saved data.
*/
public static final int STATS_TOTAL = 0;
@@ -164,7 +178,7 @@ public abstract class BatteryStats implements Parcelable {
* @return a time in microseconds
*/
public abstract long getTotalTimeLocked(long batteryRealtime, int which);
-
+
/**
* Temporary for debugging.
*/
@@ -234,11 +248,17 @@ public abstract class BatteryStats implements Parcelable {
public abstract void noteScanWifiLockReleasedLocked();
public abstract void noteWifiMulticastEnabledLocked();
public abstract void noteWifiMulticastDisabledLocked();
+ public abstract void noteAudioTurnedOnLocked();
+ public abstract void noteAudioTurnedOffLocked();
+ public abstract void noteVideoTurnedOnLocked();
+ public abstract void noteVideoTurnedOffLocked();
public abstract long getWifiTurnedOnTime(long batteryRealtime, int which);
public abstract long getFullWifiLockTime(long batteryRealtime, int which);
public abstract long getScanWifiLockTime(long batteryRealtime, int which);
public abstract long getWifiMulticastTime(long batteryRealtime,
int which);
+ public abstract long getAudioTurnedOnTime(long batteryRealtime, int which);
+ public abstract long getVideoTurnedOnTime(long batteryRealtime, int which);
/**
* Note that these must match the constants in android.os.LocalPowerManager.
diff --git a/core/java/android/os/Build.java b/core/java/android/os/Build.java
index 101336b..963875d 100644
--- a/core/java/android/os/Build.java
+++ b/core/java/android/os/Build.java
@@ -38,6 +38,9 @@ public class Build {
/** The name of the underlying board, like "goldfish". */
public static final String BOARD = getString("ro.product.board");
+ /** The name of the instruction set (CPU type + ABI convention) of native code. */
+ public static final String CPU_ABI = getString("ro.product.cpu.abi");
+
/** The manufacturer of the product/hardware. */
public static final String MANUFACTURER = getString("ro.product.manufacturer");
diff --git a/core/java/android/os/Bundle.java b/core/java/android/os/Bundle.java
index b669fa2..a91655f 100644
--- a/core/java/android/os/Bundle.java
+++ b/core/java/android/os/Bundle.java
@@ -78,6 +78,10 @@ public final class Bundle implements Parcelable, Cloneable {
readFromParcel(parcelledData);
}
+ /* package */ Bundle(Parcel parcelledData, int length) {
+ readFromParcelInner(parcelledData, length);
+ }
+
/**
* Constructs a new, empty Bundle that uses a specific ClassLoader for
* instantiating Parcelable and Serializable objects.
@@ -155,13 +159,14 @@ public final class Bundle implements Parcelable, Cloneable {
return;
}
- mParcelledData.setDataPosition(0);
- Bundle b = mParcelledData.readBundleUnpacked(mClassLoader);
- mMap = b.mMap;
-
- mHasFds = mParcelledData.hasFileDescriptors();
- mFdsKnown = true;
-
+ int N = mParcelledData.readInt();
+ if (N < 0) {
+ return;
+ }
+ if (mMap == null) {
+ mMap = new HashMap<String, Object>();
+ }
+ mParcelledData.readMapInternal(mMap, N, mClassLoader);
mParcelledData.recycle();
mParcelledData = null;
}
@@ -1427,7 +1432,25 @@ public final class Bundle implements Parcelable, Cloneable {
* @param parcel The parcel to copy this bundle to.
*/
public void writeToParcel(Parcel parcel, int flags) {
- parcel.writeBundle(this);
+ if (mParcelledData != null) {
+ int length = mParcelledData.dataSize();
+ parcel.writeInt(length);
+ parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+ parcel.appendFrom(mParcelledData, 0, length);
+ } else {
+ parcel.writeInt(-1); // dummy, will hold length
+ parcel.writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
+
+ int oldPos = parcel.dataPosition();
+ parcel.writeMapInternal(mMap);
+ int newPos = parcel.dataPosition();
+
+ // Backpatch length
+ parcel.setDataPosition(oldPos - 8);
+ int length = newPos - oldPos;
+ parcel.writeInt(length);
+ parcel.setDataPosition(newPos);
+ }
}
/**
@@ -1436,8 +1459,33 @@ public final class Bundle implements Parcelable, Cloneable {
* @param parcel The parcel to overwrite this bundle from.
*/
public void readFromParcel(Parcel parcel) {
- mParcelledData = parcel;
- mHasFds = mParcelledData.hasFileDescriptors();
+ int length = parcel.readInt();
+ if (length < 0) {
+ throw new RuntimeException("Bad length in parcel: " + length);
+ }
+ readFromParcelInner(parcel, length);
+ }
+
+ void readFromParcelInner(Parcel parcel, int length) {
+ int magic = parcel.readInt();
+ if (magic != 0x4C444E42) {
+ //noinspection ThrowableInstanceNeverThrown
+ String st = Log.getStackTraceString(new RuntimeException());
+ Log.e("Bundle", "readBundle: bad magic number");
+ Log.e("Bundle", "readBundle: trace = " + st);
+ }
+
+ // Advance within this Parcel
+ int offset = parcel.dataPosition();
+ parcel.setDataPosition(offset + length);
+
+ Parcel p = Parcel.obtain();
+ p.setDataPosition(0);
+ p.appendFrom(parcel, offset, length);
+ p.setDataPosition(0);
+
+ mParcelledData = p;
+ mHasFds = p.hasFileDescriptors();
mFdsKnown = true;
}
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 9a71f6e..6cfccee 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -457,7 +457,7 @@ public final class Parcel {
* Flatten a Map into the parcel at the current dataPosition(),
* growing dataCapacity() if needed. The Map keys must be String objects.
*/
- private void writeMapInternal(Map<String,Object> val) {
+ /* package */ void writeMapInternal(Map<String,Object> val) {
if (val == null) {
writeInt(-1);
return;
@@ -480,23 +480,7 @@ public final class Parcel {
return;
}
- if (val.mParcelledData != null) {
- int length = val.mParcelledData.dataSize();
- appendFrom(val.mParcelledData, 0, length);
- } else {
- writeInt(-1); // dummy, will hold length
- int oldPos = dataPosition();
- writeInt(0x4C444E42); // 'B' 'N' 'D' 'L'
-
- writeMapInternal(val.mMap);
- int newPos = dataPosition();
-
- // Backpatch length
- setDataPosition(oldPos - 4);
- int length = newPos - oldPos;
- writeInt(length);
- setDataPosition(newPos);
- }
+ val.writeToParcel(this, 0);
}
/**
@@ -1352,27 +1336,12 @@ public final class Parcel {
* Returns null if the previously written Bundle object was null.
*/
public final Bundle readBundle(ClassLoader loader) {
- int offset = dataPosition();
int length = readInt();
if (length < 0) {
return null;
}
- int magic = readInt();
- if (magic != 0x4C444E42) {
- //noinspection ThrowableInstanceNeverThrown
- String st = Log.getStackTraceString(new RuntimeException());
- Log.e("Bundle", "readBundle: bad magic number");
- Log.e("Bundle", "readBundle: trace = " + st);
- }
-
- // Advance within this Parcel
- setDataPosition(offset + length + 4);
-
- Parcel p = new Parcel(0);
- p.setDataPosition(0);
- p.appendFrom(this, offset, length + 4);
- p.setDataPosition(0);
- final Bundle bundle = new Bundle(p);
+
+ final Bundle bundle = new Bundle(this, length);
if (loader != null) {
bundle.setClassLoader(loader);
}
@@ -1380,33 +1349,6 @@ public final class Parcel {
}
/**
- * Read and return a new Bundle object from the parcel at the current
- * dataPosition(). Returns null if the previously written Bundle object was
- * null. The returned bundle will have its contents fully unpacked using
- * the given ClassLoader.
- */
- /* package */ Bundle readBundleUnpacked(ClassLoader loader) {
- int length = readInt();
- if (length == -1) {
- return null;
- }
- int magic = readInt();
- if (magic != 0x4C444E42) {
- //noinspection ThrowableInstanceNeverThrown
- String st = Log.getStackTraceString(new RuntimeException());
- Log.e("Bundle", "readBundleUnpacked: bad magic number");
- Log.e("Bundle", "readBundleUnpacked: trace = " + st);
- }
- Bundle m = new Bundle(loader);
- int N = readInt();
- if (N < 0) {
- return null;
- }
- readMapInternal(m.mMap, N, loader);
- return m;
- }
-
- /**
* Read and return a byte[] object from the parcel.
*/
public final native byte[] createByteArray();
@@ -1998,7 +1940,7 @@ public final class Parcel {
private native void init(int obj);
private native void destroy();
- private void readMapInternal(Map outVal, int N,
+ /* package */ void readMapInternal(Map outVal, int N,
ClassLoader loader) {
while (N > 0) {
Object key = readValue(loader);
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index b6f96c4..51d1951 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -737,7 +737,7 @@ public final class MediaStore
name.endsWith(", a") || name.endsWith(",a")) {
name = name.substring(0, name.lastIndexOf(','));
}
- name = name.replaceAll("[\\[\\]\\(\\)'.,?!]", "").trim();
+ name = name.replaceAll("[\\[\\]\\(\\)\"'.,?!]", "").trim();
if (name.length() > 0) {
// Insert a separator between the characters to avoid
// matches on a partial character. If we ever change
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index 3d023f7..0dc2570 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -100,6 +100,8 @@ public class SurfaceView extends View {
static final int KEEP_SCREEN_ON_MSG = 1;
static final int GET_NEW_SURFACE_MSG = 2;
+ int mWindowType = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+
boolean mIsCreating = false;
final Handler mHandler = new Handler() {
@@ -285,6 +287,15 @@ public class SurfaceView extends View {
super.dispatchDraw(canvas);
}
+ /**
+ * Hack to allow special layering of windows. The type is one of the
+ * types in WindowManager.LayoutParams. This is a hack so:
+ * @hide
+ */
+ public void setWindowType(int type) {
+ mWindowType = type;
+ }
+
private void updateWindow(boolean force) {
if (!mHaveFrame) {
return;
@@ -342,7 +353,7 @@ public class SurfaceView extends View {
if (mWindow == null) {
mWindow = new MyWindow(this);
- mLayout.type = WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
+ mLayout.type = mWindowType;
mLayout.gravity = Gravity.LEFT|Gravity.TOP;
mSession.add(mWindow, mLayout,
mVisible ? VISIBLE : GONE, mContentInsets);
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 1f72eea..bcb97ed 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -538,21 +538,48 @@ import java.util.WeakHashMap;
* take care of redrawing the appropriate views until the animation completes.
* </p>
*
+ * @attr ref android.R.styleable#View_background
+ * @attr ref android.R.styleable#View_clickable
+ * @attr ref android.R.styleable#View_contentDescription
+ * @attr ref android.R.styleable#View_drawingCacheQuality
+ * @attr ref android.R.styleable#View_duplicateParentState
+ * @attr ref android.R.styleable#View_id
+ * @attr ref android.R.styleable#View_fadingEdge
+ * @attr ref android.R.styleable#View_fadingEdgeLength
* @attr ref android.R.styleable#View_fitsSystemWindows
+ * @attr ref android.R.styleable#View_isScrollContainer
+ * @attr ref android.R.styleable#View_focusable
+ * @attr ref android.R.styleable#View_focusableInTouchMode
+ * @attr ref android.R.styleable#View_hapticFeedbackEnabled
+ * @attr ref android.R.styleable#View_keepScreenOn
+ * @attr ref android.R.styleable#View_longClickable
+ * @attr ref android.R.styleable#View_minHeight
+ * @attr ref android.R.styleable#View_minWidth
* @attr ref android.R.styleable#View_nextFocusDown
* @attr ref android.R.styleable#View_nextFocusLeft
* @attr ref android.R.styleable#View_nextFocusRight
* @attr ref android.R.styleable#View_nextFocusUp
+ * @attr ref android.R.styleable#View_onClick
+ * @attr ref android.R.styleable#View_padding
+ * @attr ref android.R.styleable#View_paddingBottom
+ * @attr ref android.R.styleable#View_paddingLeft
+ * @attr ref android.R.styleable#View_paddingRight
+ * @attr ref android.R.styleable#View_paddingTop
+ * @attr ref android.R.styleable#View_saveEnabled
* @attr ref android.R.styleable#View_scrollX
* @attr ref android.R.styleable#View_scrollY
- * @attr ref android.R.styleable#View_scrollbarTrackHorizontal
- * @attr ref android.R.styleable#View_scrollbarThumbHorizontal
* @attr ref android.R.styleable#View_scrollbarSize
+ * @attr ref android.R.styleable#View_scrollbarStyle
* @attr ref android.R.styleable#View_scrollbars
+ * @attr ref android.R.styleable#View_scrollbarTrackHorizontal
+ * @attr ref android.R.styleable#View_scrollbarThumbHorizontal
* @attr ref android.R.styleable#View_scrollbarThumbVertical
* @attr ref android.R.styleable#View_scrollbarTrackVertical
* @attr ref android.R.styleable#View_scrollbarAlwaysDrawHorizontalTrack
* @attr ref android.R.styleable#View_scrollbarAlwaysDrawVerticalTrack
+ * @attr ref android.R.styleable#View_soundEffectsEnabled
+ * @attr ref android.R.styleable#View_tag
+ * @attr ref android.R.styleable#View_visibility
*
* @see android.view.ViewGroup
*/
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index bf04dcd..8b0629c 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -53,6 +53,15 @@ import java.util.ArrayList;
* <p>
* Also see {@link LayoutParams} for layout attributes.
* </p>
+ *
+ * @attr ref android.R.styleable#ViewGroup_clipChildren
+ * @attr ref android.R.styleable#ViewGroup_clipToPadding
+ * @attr ref android.R.styleable#ViewGroup_layoutAnimation
+ * @attr ref android.R.styleable#ViewGroup_animationCache
+ * @attr ref android.R.styleable#ViewGroup_persistentDrawingCache
+ * @attr ref android.R.styleable#ViewGroup_alwaysDrawnWithCache
+ * @attr ref android.R.styleable#ViewGroup_addStatesFromChildren
+ * @attr ref android.R.styleable#ViewGroup_descendantFocusability
*/
public abstract class ViewGroup extends View implements ViewParent, ViewManager {
private static final boolean DBG = false;
@@ -2342,7 +2351,8 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager
final boolean drawAnimation = (child.mPrivateFlags & DRAW_ANIMATION) == DRAW_ANIMATION;
// Check whether the child that requests the invalidate is fully opaque
- final boolean isOpaque = child.isOpaque();
+ final boolean isOpaque = child.isOpaque() && !drawAnimation &&
+ child.getAnimation() != null;
// Mark the child as dirty, using the appropriate flag
// Make sure we do not set both flags at the same time
final int opaqueFlag = isOpaque ? DIRTY_OPAQUE : DIRTY;
diff --git a/core/java/android/view/Window.java b/core/java/android/view/Window.java
index b0e738c..d7457a0 100644
--- a/core/java/android/view/Window.java
+++ b/core/java/android/view/Window.java
@@ -376,8 +376,14 @@ public abstract class Window {
String title;
if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA) {
title="Media";
+ } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY) {
+ title="MediaOvr";
} else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_PANEL) {
title="Panel";
+ } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_SUB_PANEL) {
+ title="SubPanel";
+ } else if (wp.type == WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG) {
+ title="AtchDlg";
} else {
title=Integer.toString(wp.type);
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 72ef0ad..ec2069c 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -210,6 +210,15 @@ public interface WindowManager extends ViewManager {
public static final int TYPE_APPLICATION_ATTACHED_DIALOG = FIRST_SUB_WINDOW+3;
/**
+ * Window type: window for showing overlays on top of media windows.
+ * These windows are displayed between TYPE_APPLICATION_MEDIA and the
+ * application window. They should be translucent to be useful. This
+ * is a big ugly hack so:
+ * @hide
+ */
+ public static final int TYPE_APPLICATION_MEDIA_OVERLAY = FIRST_SUB_WINDOW+4;
+
+ /**
* End of types of sub-windows.
*/
public static final int LAST_SUB_WINDOW = 1999;
diff --git a/core/java/android/webkit/WebSettings.java b/core/java/android/webkit/WebSettings.java
index 105eacd..dcba943 100644
--- a/core/java/android/webkit/WebSettings.java
+++ b/core/java/android/webkit/WebSettings.java
@@ -123,7 +123,7 @@ public class WebSettings {
private String mSerifFontFamily = "serif";
private String mCursiveFontFamily = "cursive";
private String mFantasyFontFamily = "fantasy";
- private String mDefaultTextEncoding = "Latin-1";
+ private String mDefaultTextEncoding;
private String mUserAgent;
private boolean mUseDefaultUserAgent;
private String mAcceptLanguage;
@@ -240,6 +240,8 @@ public class WebSettings {
WebSettings(Context context) {
mEventHandler = new EventHandler();
mContext = context;
+ mDefaultTextEncoding = context.getString(com.android.internal.
+ R.string.default_text_encoding);
if (sLockForLocaleSettings == null) {
sLockForLocaleSettings = new Object();
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 1ca59b2..ccb876f 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -41,12 +41,17 @@ import android.view.ViewConfiguration;
import android.view.ViewDebug;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
+import android.view.KeyCharacterMap;
import android.view.inputmethod.BaseInputConnection;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputConnectionWrapper;
import android.view.inputmethod.InputMethodManager;
import android.view.ContextMenu.ContextMenuInfo;
+import android.gesture.GestureOverlayView;
+import android.gesture.Gesture;
+import android.gesture.LetterRecognizer;
+import android.gesture.Prediction;
import com.android.internal.R;
@@ -54,7 +59,9 @@ import java.util.ArrayList;
import java.util.List;
/**
- * Common code shared between ListView and GridView
+ * Base class that can be used to implement virtualized lists of items. A list does
+ * not have a spatial definition here. For instance, subclases of this class can
+ * display the content of the list in a grid, in a carousel, as stack, etc.
*
* @attr ref android.R.styleable#AbsListView_listSelector
* @attr ref android.R.styleable#AbsListView_drawSelectorOnTop
@@ -65,6 +72,7 @@ import java.util.List;
* @attr ref android.R.styleable#AbsListView_cacheColorHint
* @attr ref android.R.styleable#AbsListView_fastScrollEnabled
* @attr ref android.R.styleable#AbsListView_smoothScrollbar
+ * @attr ref android.R.styleable#AbsListView_gestures
*/
public abstract class AbsListView extends AdapterView<ListAdapter> implements TextWatcher,
ViewTreeObserver.OnGlobalLayoutListener, Filter.FilterListener,
@@ -93,6 +101,31 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
public static final int TRANSCRIPT_MODE_ALWAYS_SCROLL = 2;
/**
+ * Disables gestures.
+ *
+ * @see #setGestures(int)
+ * @see #GESTURES_JUMP
+ * @see #GESTURES_FILTER
+ */
+ public static final int GESTURES_NONE = 0;
+ /**
+ * When a letter gesture is recognized the list jumps to a matching position.
+ *
+ * @see #setGestures(int)
+ * @see #GESTURES_NONE
+ * @see #GESTURES_FILTER
+ */
+ public static final int GESTURES_JUMP = 1;
+ /**
+ * When a letter gesture is recognized the letter is added to the filter.
+ *
+ * @see #setGestures(int)
+ * @see #GESTURES_NONE
+ * @see #GESTURES_JUMP
+ */
+ public static final int GESTURES_FILTER = 2;
+
+ /**
* Indicates that we are not in the middle of a touch gesture
*/
static final int TOUCH_MODE_REST = -1;
@@ -427,8 +460,22 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
*/
private FastScroller mFastScroller;
- private int mTouchSlop;
+ /**
+ * Indicates the type of gestures to use: GESTURES_NONE, GESTURES_FILTER or GESTURES_NONE
+ */
+ private int mGestures;
+
+ // Used to implement the gestures overlay
+ private GestureOverlayView mGesturesOverlay;
+ private PopupWindow mGesturesPopup;
+ private ViewTreeObserver.OnGlobalLayoutListener mGesturesLayoutListener;
+ private boolean mGlobalLayoutListenerAddedGestures;
+ private boolean mInstallGesturesOverlay;
+ private boolean mPreviousGesturing;
+
+ private boolean mGlobalLayoutListenerAddedFilter;
+ private int mTouchSlop;
private float mDensityScale;
private InputConnection mDefInputConnection;
@@ -535,10 +582,199 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
boolean smoothScrollbar = a.getBoolean(R.styleable.AbsListView_smoothScrollbar, true);
setSmoothScrollbarEnabled(smoothScrollbar);
-
+
+ int defaultGestures = GESTURES_NONE;
+ if (useTextFilter) {
+ defaultGestures = GESTURES_FILTER;
+ } else if (enableFastScroll) {
+ defaultGestures = GESTURES_JUMP;
+ }
+ int gestures = a.getInt(R.styleable.AbsListView_gestures, defaultGestures);
+ setGestures(gestures);
+
a.recycle();
}
+ private void initAbsListView() {
+ // Setting focusable in touch mode will set the focusable property to true
+ setFocusableInTouchMode(true);
+ setWillNotDraw(false);
+ setAlwaysDrawnWithCacheEnabled(false);
+ setScrollingCacheEnabled(true);
+
+ mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
+ mDensityScale = getContext().getResources().getDisplayMetrics().density;
+ }
+
+ /**
+ * <p>Sets the type of gestures to use with this list. When gestures are enabled,
+ * that is if the <code>gestures</code> parameter is not {@link #GESTURES_NONE},
+ * the user can draw characters on top of this view. When a character is
+ * recognized and matches a known character, the list will either:</p>
+ * <ul>
+ * <li>Jump to the appropriate position ({@link #GESTURES_JUMP})</li>
+ * <li>Add the character to the current filter ({@link #GESTURES_FILTER})</li>
+ * </ul>
+ * <p>Using {@link #GESTURES_JUMP} requires {@link #isFastScrollEnabled()} to
+ * be true. Using {@link #GESTURES_FILTER} requires {@link #isTextFilterEnabled()}
+ * to be true.</p>
+ *
+ * @param gestures The type of gestures to enable for this list:
+ * {@link #GESTURES_NONE}, {@link #GESTURES_JUMP} or {@link #GESTURES_FILTER}
+ *
+ * @see #GESTURES_NONE
+ * @see #GESTURES_JUMP
+ * @see #GESTURES_FILTER
+ * @see #getGestures()
+ */
+ public void setGestures(int gestures) {
+ switch (gestures) {
+ case GESTURES_JUMP:
+ if (!mFastScrollEnabled) {
+ throw new IllegalStateException("Jump gestures can only be used with "
+ + "fast scroll enabled");
+ }
+ break;
+ case GESTURES_FILTER:
+ if (!mTextFilterEnabled) {
+ throw new IllegalStateException("Filter gestures can only be used with "
+ + "text filtering enabled");
+ }
+ break;
+ }
+
+ final int oldGestures = mGestures;
+ mGestures = gestures;
+
+ // Install overlay later
+ if (oldGestures == GESTURES_NONE && gestures != GESTURES_NONE) {
+ mInstallGesturesOverlay = true;
+ // Uninstall overlay
+ } else if (oldGestures != GESTURES_NONE && gestures == GESTURES_NONE) {
+ uninstallGesturesOverlay();
+ }
+ }
+
+ /**
+ * Indicates what gestures are enabled on this view.
+ *
+ * @return {@link #GESTURES_NONE}, {@link #GESTURES_JUMP} or {@link #GESTURES_FILTER}
+ *
+ * @see #GESTURES_NONE
+ * @see #GESTURES_JUMP
+ * @see #GESTURES_FILTER
+ * @see #setGestures(int)
+ */
+ @ViewDebug.ExportedProperty(mapping = {
+ @ViewDebug.IntToString(from = GESTURES_NONE, to = "NONE"),
+ @ViewDebug.IntToString(from = GESTURES_JUMP, to = "JUMP"),
+ @ViewDebug.IntToString(from = GESTURES_FILTER, to = "FILTER")
+ })
+ public int getGestures() {
+ return mGestures;
+ }
+
+ private void dismissGesturesPopup() {
+ if (mGesturesPopup != null) {
+ mGesturesPopup.dismiss();
+ }
+ }
+
+ private void showGesturesPopup() {
+ // Make sure we have a window before showing the popup
+ if (getWindowVisibility() == View.VISIBLE) {
+ installGesturesOverlay();
+ positionGesturesPopup();
+ }
+ }
+
+ private void positionGesturesPopup() {
+ final int[] xy = new int[2];
+ getLocationOnScreen(xy);
+ if (!mGesturesPopup.isShowing()) {
+ mGesturesPopup.showAtLocation(this, Gravity.LEFT | Gravity.TOP, xy[0], xy[1]);
+ } else {
+ mGesturesPopup.update(xy[0], xy[1], -1, -1);
+ }
+ }
+
+ private void installGesturesOverlay() {
+ mInstallGesturesOverlay = false;
+
+ if (mGesturesPopup == null) {
+ final Context c = getContext();
+ final LayoutInflater layoutInflater = (LayoutInflater)
+ c.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ mGesturesOverlay = (GestureOverlayView)
+ layoutInflater.inflate(R.layout.list_gestures_overlay, null);
+
+ final PopupWindow p = new PopupWindow(c);
+ p.setFocusable(false);
+ p.setTouchable(false);
+ p.setInputMethodMode(PopupWindow.INPUT_METHOD_NOT_NEEDED);
+ p.setContentView(mGesturesOverlay);
+ p.setWidth(getWidth());
+ p.setHeight(getHeight());
+ p.setBackgroundDrawable(null);
+
+ if (mGesturesLayoutListener == null) {
+ mGesturesLayoutListener = new ViewTreeObserver.OnGlobalLayoutListener() {
+ public void onGlobalLayout() {
+ if (isShown()) {
+ showGesturesPopup();
+ } else if (mGesturesPopup.isShowing()) {
+ dismissGesturesPopup();
+ }
+ }
+ };
+ }
+ getViewTreeObserver().addOnGlobalLayoutListener(mGesturesLayoutListener);
+ mGlobalLayoutListenerAddedGestures = true;
+
+ mGesturesPopup = p;
+
+ mGesturesOverlay.removeAllOnGestureListeners();
+ mGesturesOverlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
+ mGesturesOverlay.addOnGesturePerformedListener(new GesturesProcessor());
+
+ mPreviousGesturing = false;
+ }
+ }
+
+ private void uninstallGesturesOverlay() {
+ dismissGesturesPopup();
+ mGesturesPopup = null;
+ if (mGesturesLayoutListener != null) {
+ getViewTreeObserver().removeGlobalOnLayoutListener(mGesturesLayoutListener);
+ }
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (mGestures != GESTURES_NONE) {
+ if (ev.getAction() != MotionEvent.ACTION_DOWN || mFastScroller == null ||
+ !mFastScroller.isPointInside(ev.getX(), ev.getY())) {
+
+ mGesturesOverlay.dispatchTouchEvent(ev);
+
+ final boolean isGesturing = mGesturesOverlay.isGesturing();
+
+ if (!isGesturing) {
+ mPreviousGesturing = isGesturing;
+ return super.dispatchTouchEvent(ev);
+ } else if (!mPreviousGesturing){
+ mPreviousGesturing = isGesturing;
+ final MotionEvent event = MotionEvent.obtain(ev);
+ event.setAction(MotionEvent.ACTION_CANCEL);
+ super.dispatchTouchEvent(event);
+ return true;
+ }
+ }
+ }
+
+ return super.dispatchTouchEvent(ev);
+ }
+
/**
* Enables fast scrolling by letting the user quickly scroll through lists by
* dragging the fast scroll thumb. The adapter attached to the list may want
@@ -712,17 +948,6 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
- private void initAbsListView() {
- // Setting focusable in touch mode will set the focusable property to true
- setFocusableInTouchMode(true);
- setWillNotDraw(false);
- setAlwaysDrawnWithCacheEnabled(false);
- setScrollingCacheEnabled(true);
-
- mTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
- mDensityScale = getContext().getResources().getDisplayMetrics().density;
- }
-
private void useDefaultSelector() {
setSelector(getResources().getDrawable(
com.android.internal.R.drawable.list_selector_background));
@@ -908,11 +1133,8 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
private boolean acceptFilter() {
- if (!mTextFilterEnabled || !(getAdapter() instanceof Filterable) ||
- ((Filterable) getAdapter()).getFilter() == null) {
- return false;
- }
- return true;
+ return mTextFilterEnabled && getAdapter() instanceof Filterable &&
+ ((Filterable) getAdapter()).getFilter() != null;
}
/**
@@ -1096,6 +1318,10 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
listPadding.bottom = mSelectionBottomPadding + mPaddingBottom;
}
+ /**
+ * Subclasses should NOT override this method but
+ * {@link #layoutChildren()} instead.
+ */
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
@@ -1111,17 +1337,27 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
protected boolean setFrame(int left, int top, int right, int bottom) {
final boolean changed = super.setFrame(left, top, right, bottom);
- // Reposition the popup when the frame has changed. This includes
- // translating the widget, not just changing its dimension. The
- // filter popup needs to follow the widget.
- if (mFiltered && changed && getWindowVisibility() == View.VISIBLE && mPopup != null &&
- mPopup.isShowing()) {
- positionPopup();
+ if (changed) {
+ // Reposition the popup when the frame has changed. This includes
+ // translating the widget, not just changing its dimension. The
+ // filter popup needs to follow the widget.
+ final boolean visible = getWindowVisibility() == View.VISIBLE;
+ if (mFiltered && visible && mPopup != null && mPopup.isShowing()) {
+ positionPopup();
+ }
+
+ if (mGestures != GESTURES_NONE && visible && mGesturesPopup != null &&
+ mGesturesPopup.isShowing()) {
+ positionGesturesPopup();
+ }
}
return changed;
}
+ /**
+ * Subclasses must override this method to layout their children.
+ */
protected void layoutChildren() {
}
@@ -1324,9 +1560,17 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
mDataChanged = true;
rememberSyncState();
}
+
if (mFastScroller != null) {
mFastScroller.onSizeChanged(w, h, oldw, oldh);
}
+
+ if (mInstallGesturesOverlay) {
+ installGesturesOverlay();
+ positionGesturesPopup();
+ } else if (mGesturesPopup != null) {
+ mGesturesPopup.update(w, h);
+ }
}
/**
@@ -1510,6 +1754,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final ViewTreeObserver treeObserver = getViewTreeObserver();
if (treeObserver != null) {
treeObserver.addOnTouchModeChangeListener(this);
+ if (mTextFilterEnabled && mPopup != null && !mGlobalLayoutListenerAddedFilter) {
+ treeObserver.addOnGlobalLayoutListener(this);
+ }
+ if (mGestures != GESTURES_NONE && mGesturesPopup != null &&
+ !mGlobalLayoutListenerAddedGestures) {
+ treeObserver.addOnGlobalLayoutListener(mGesturesLayoutListener);
+ }
}
}
@@ -1520,6 +1771,14 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
final ViewTreeObserver treeObserver = getViewTreeObserver();
if (treeObserver != null) {
treeObserver.removeOnTouchModeChangeListener(this);
+ if (mTextFilterEnabled && mPopup != null) {
+ treeObserver.removeGlobalOnLayoutListener(this);
+ mGlobalLayoutListenerAddedFilter = false;
+ }
+ if (mGesturesLayoutListener != null && mGesturesPopup != null) {
+ mGlobalLayoutListenerAddedGestures = false;
+ treeObserver.removeGlobalOnLayoutListener(mGesturesLayoutListener);
+ }
}
}
@@ -1534,6 +1793,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
removeCallbacks(mFlingRunnable);
// Always hide the type filter
dismissPopup();
+ dismissGesturesPopup();
if (touchMode == TOUCH_MODE_OFF) {
// Remember the last selected element
@@ -1544,6 +1804,9 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
// Show the type filter only if a filter is in effect
showPopup();
}
+ if (mGestures != GESTURES_NONE) {
+ showGesturesPopup();
+ }
// If we changed touch mode since the last time we had focus
if (touchMode != mLastTouchMode && mLastTouchMode != TOUCH_MODE_UNKNOWN) {
@@ -1867,13 +2130,13 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
@Override
public boolean onTouchEvent(MotionEvent ev) {
-
if (mFastScroller != null) {
boolean intercepted = mFastScroller.onTouchEvent(ev);
if (intercepted) {
return true;
}
}
+
final int action = ev.getAction();
final int x = (int) ev.getX();
final int y = (int) ev.getY();
@@ -2775,7 +3038,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
/**
* Removes the filter window
*/
- void dismissPopup() {
+ private void dismissPopup() {
if (mPopup != null) {
mPopup.dismiss();
}
@@ -3017,6 +3280,7 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
p.setBackgroundDrawable(null);
mPopup = p;
getViewTreeObserver().addOnGlobalLayoutListener(this);
+ mGlobalLayoutListenerAddedFilter = true;
}
if (animateEntrance) {
mPopup.setAnimationStyle(com.android.internal.R.style.Animation_TypingFilter);
@@ -3583,4 +3847,76 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
+
+ private class GesturesProcessor implements GestureOverlayView.OnGesturePerformedListener {
+
+ private static final double SCORE_THRESHOLD = 0.1;
+
+ private LetterRecognizer mRecognizer;
+ private ArrayList<Prediction> mPredictions;
+ private final KeyCharacterMap mKeyMap;
+ private final char[] mHolder;
+
+ GesturesProcessor() {
+ mRecognizer = LetterRecognizer.getLetterRecognizer(getContext(),
+ LetterRecognizer.RECOGNIZER_LATIN_LOWERCASE);
+ if (mGestures == GESTURES_FILTER) {
+ mKeyMap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD);
+ mHolder = new char[1];
+ } else {
+ mKeyMap = null;
+ mHolder = null;
+ }
+ }
+
+ public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
+ mPredictions = mRecognizer.recognize(gesture, mPredictions);
+ if (!mPredictions.isEmpty()) {
+ final Prediction prediction = mPredictions.get(0);
+ if (prediction.score > SCORE_THRESHOLD) {
+ switch (mGestures) {
+ case GESTURES_JUMP:
+ processJump(prediction);
+ break;
+ case GESTURES_FILTER:
+ processFilter(prediction);
+ break;
+ }
+ }
+ }
+ }
+
+ private void processJump(Prediction prediction) {
+ final Object[] sections = mFastScroller.getSections();
+ if (sections != null) {
+ final String name = prediction.name;
+ final int count = sections.length;
+
+ int index = -1;
+ for (int i = 0; i < count; i++) {
+ if (name.equalsIgnoreCase((String) sections[i])) {
+ index = i;
+ break;
+ }
+ }
+
+ if (index != -1) {
+ final SectionIndexer indexer = mFastScroller.getSectionIndexer();
+ final int position = indexer.getPositionForSection(index);
+ setSelection(position);
+ }
+ }
+ }
+
+ private void processFilter(Prediction prediction) {
+ mHolder[0] = prediction.name.charAt(0);
+ final KeyEvent[] events = mKeyMap.getEvents(mHolder);
+ if (events != null) {
+ for (KeyEvent event : events) {
+ sendToTextFilter(event.getKeyCode(), event.getRepeatCount(),
+ event);
+ }
+ }
+ }
+ }
}
diff --git a/core/java/android/widget/ExpandableListView.java b/core/java/android/widget/ExpandableListView.java
index 0fc8f49..5360621 100644
--- a/core/java/android/widget/ExpandableListView.java
+++ b/core/java/android/widget/ExpandableListView.java
@@ -1083,6 +1083,11 @@ public class ExpandableListView extends ListView {
@Override
public void onRestoreInstanceState(Parcelable state) {
+ if (!(state instanceof SavedState)) {
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
diff --git a/core/java/android/widget/FastScroller.java b/core/java/android/widget/FastScroller.java
index 3368477..cd965fc 100644
--- a/core/java/android/widget/FastScroller.java
+++ b/core/java/android/widget/FastScroller.java
@@ -134,7 +134,7 @@ class FastScroller {
mScrollCompleted = true;
- getSections();
+ getSectionsFromIndexer();
mOverlayPos = new RectF();
mScrollFade = new ScrollFade();
@@ -250,7 +250,18 @@ class FastScroller {
}
}
- private void getSections() {
+ SectionIndexer getSectionIndexer() {
+ return mSectionIndexer;
+ }
+
+ Object[] getSections() {
+ if (mListAdapter == null && mList != null) {
+ getSectionsFromIndexer();
+ }
+ return mSections;
+ }
+
+ private void getSectionsFromIndexer() {
Adapter adapter = mList.getAdapter();
mSectionIndexer = null;
if (adapter instanceof HeaderViewListAdapter) {
@@ -391,8 +402,7 @@ class FastScroller {
boolean onInterceptTouchEvent(MotionEvent ev) {
if (mState > STATE_NONE && ev.getAction() == MotionEvent.ACTION_DOWN) {
- if (ev.getX() > mList.getWidth() - mThumbW && ev.getY() >= mThumbY &&
- ev.getY() <= mThumbY + mThumbH) {
+ if (isPointInside(ev.getX(), ev.getY())) {
setState(STATE_DRAGGING);
return true;
}
@@ -404,20 +414,20 @@ class FastScroller {
if (mState == STATE_NONE) {
return false;
}
- if (me.getAction() == MotionEvent.ACTION_DOWN) {
- if (me.getX() > mList.getWidth() - mThumbW
- && me.getY() >= mThumbY
- && me.getY() <= mThumbY + mThumbH) {
-
+
+ final int action = me.getAction();
+
+ if (action == MotionEvent.ACTION_DOWN) {
+ if (isPointInside(me.getX(), me.getY())) {
setState(STATE_DRAGGING);
if (mListAdapter == null && mList != null) {
- getSections();
+ getSectionsFromIndexer();
}
cancelFling();
return true;
}
- } else if (me.getAction() == MotionEvent.ACTION_UP) {
+ } else if (action == MotionEvent.ACTION_UP) {
if (mState == STATE_DRAGGING) {
setState(STATE_VISIBLE);
final Handler handler = mHandler;
@@ -425,7 +435,7 @@ class FastScroller {
handler.postDelayed(mScrollFade, 1000);
return true;
}
- } else if (me.getAction() == MotionEvent.ACTION_MOVE) {
+ } else if (action == MotionEvent.ACTION_MOVE) {
if (mState == STATE_DRAGGING) {
final int viewHeight = mList.getHeight();
// Jitter
@@ -448,7 +458,11 @@ class FastScroller {
}
return false;
}
-
+
+ boolean isPointInside(float x, float y) {
+ return x > mList.getWidth() - mThumbW && y >= mThumbY && y <= mThumbY + mThumbH;
+ }
+
public class ScrollFade implements Runnable {
long mStartTime;
diff --git a/core/java/android/widget/FrameLayout.java b/core/java/android/widget/FrameLayout.java
index 80fbf9e..3afd5d4 100644
--- a/core/java/android/widget/FrameLayout.java
+++ b/core/java/android/widget/FrameLayout.java
@@ -353,25 +353,24 @@ public class FrameLayout extends ViewGroup {
if (mForeground != null) {
final Drawable foreground = mForeground;
+
if (mForegroundBoundsChanged) {
mForegroundBoundsChanged = false;
- if (foreground != null) {
- final Rect selfBounds = mSelfBounds;
- final Rect overlayBounds = mOverlayBounds;
-
- final int w = mRight-mLeft;
- final int h = mBottom-mTop;
-
- if (mForegroundInPadding) {
- selfBounds.set(0, 0, w, h);
- } else {
- selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
- }
+ final Rect selfBounds = mSelfBounds;
+ final Rect overlayBounds = mOverlayBounds;
- Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
- foreground.getIntrinsicHeight(), selfBounds, overlayBounds);
- foreground.setBounds(overlayBounds);
+ final int w = mRight-mLeft;
+ final int h = mBottom-mTop;
+
+ if (mForegroundInPadding) {
+ selfBounds.set(0, 0, w, h);
+ } else {
+ selfBounds.set(mPaddingLeft, mPaddingTop, w - mPaddingRight, h - mPaddingBottom);
}
+
+ Gravity.apply(mForegroundGravity, foreground.getIntrinsicWidth(),
+ foreground.getIntrinsicHeight(), selfBounds, overlayBounds);
+ foreground.setBounds(overlayBounds);
}
foreground.draw(canvas);
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index 6686f75..10d8f55 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -2852,6 +2852,9 @@ public class ListView extends AbsListView {
final boolean areAllItemsSelectable = mAreAllItemsSelectable;
final ListAdapter adapter = mAdapter;
final boolean isOpaque = isOpaque();
+ if (isOpaque && mDividerPaint == null) {
+ mDividerPaint = new Paint();
+ }
final Paint paint = mDividerPaint;
if (!mStackFromBottom) {
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 975277b..68764a5 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -1072,6 +1072,20 @@ public class PopupWindow {
mWindowManager.updateViewLayout(mPopupView, p);
}
}
+
+ /**
+ * <p>Updates the dimension of the popup window. Calling this function
+ * also updates the window with the current popup state as described
+ * for {@link #update()}.</p>
+ *
+ * @param width the new width
+ * @param height the new height
+ */
+ public void update(int width, int height) {
+ WindowManager.LayoutParams p = (WindowManager.LayoutParams)
+ mPopupView.getLayoutParams();
+ update(p.x, p.y, width, height, false);
+ }
/**
* <p>Updates the position and the dimension of the popup window. Width and
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 40a72a4..5c75af2c 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -127,6 +127,8 @@ import java.util.ArrayList;
* @attr ref android.R.styleable#TextView_textColor
* @attr ref android.R.styleable#TextView_textColorHighlight
* @attr ref android.R.styleable#TextView_textColorHint
+ * @attr ref android.R.styleable#TextView_textAppearance
+ * @attr ref android.R.styleable#TextView_textColorLink
* @attr ref android.R.styleable#TextView_textSize
* @attr ref android.R.styleable#TextView_textScaleX
* @attr ref android.R.styleable#TextView_typeface
@@ -164,13 +166,22 @@ import java.util.ArrayList;
* @attr ref android.R.styleable#TextView_capitalize
* @attr ref android.R.styleable#TextView_autoText
* @attr ref android.R.styleable#TextView_editable
+ * @attr ref android.R.styleable#TextView_freezesText
+ * @attr ref android.R.styleable#TextView_ellipsize
* @attr ref android.R.styleable#TextView_drawableTop
* @attr ref android.R.styleable#TextView_drawableBottom
* @attr ref android.R.styleable#TextView_drawableRight
* @attr ref android.R.styleable#TextView_drawableLeft
+ * @attr ref android.R.styleable#TextView_drawablePadding
* @attr ref android.R.styleable#TextView_lineSpacingExtra
* @attr ref android.R.styleable#TextView_lineSpacingMultiplier
* @attr ref android.R.styleable#TextView_marqueeRepeatLimit
+ * @attr ref android.R.styleable#TextView_inputType
+ * @attr ref android.R.styleable#TextView_imeOptions
+ * @attr ref android.R.styleable#TextView_privateImeOptions
+ * @attr ref android.R.styleable#TextView_imeActionLabel
+ * @attr ref android.R.styleable#TextView_imeActionId
+ * @attr ref android.R.styleable#TextView_editorExtras
*/
@RemoteView
public class TextView extends View implements ViewTreeObserver.OnPreDrawListener {
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index bf9bc4e..a448ac6 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -37,10 +37,8 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
-import java.util.Set;
/**
* All information we are collecting about things that can happen that impact
@@ -55,7 +53,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 35;
+ private static final int VERSION = 36;
private final File mFile;
private final File mBackupFile;
@@ -105,6 +103,12 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mPhoneOn;
StopwatchTimer mPhoneOnTimer;
+ boolean mAudioOn;
+ StopwatchTimer mAudioOnTimer;
+
+ boolean mVideoOn;
+ StopwatchTimer mVideoOnTimer;
+
int mPhoneSignalStrengthBin = -1;
final StopwatchTimer[] mPhoneSignalStrengthsTimer =
new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
@@ -142,9 +146,9 @@ public final class BatteryStatsImpl extends BatteryStats {
*/
int mDischargeStartLevel;
int mDischargeCurrentLevel;
-
+
long mLastWriteTime = 0; // Milliseconds
-
+
/*
* Holds a SamplingTimer associated with each kernel wakelock name being tracked.
*/
@@ -320,6 +324,13 @@ public final class BatteryStatsImpl extends BatteryStats {
*/
long mUnpluggedTime;
+ /**
+ * Constructs from a parcel.
+ * @param type
+ * @param unpluggables
+ * @param powerType
+ * @param in
+ */
Timer(int type, ArrayList<Unpluggable> unpluggables, Parcel in) {
mType = type;
@@ -632,7 +643,6 @@ public final class BatteryStatsImpl extends BatteryStats {
* was actually held for an interesting duration.
*/
long mAcquireTime;
-
StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
ArrayList<Unpluggable> unpluggables, Parcel in) {
@@ -1071,7 +1081,51 @@ public final class BatteryStatsImpl extends BatteryStats {
mWifiOnUid = -1;
}
}
+
+ public void noteAudioOnLocked(int uid) {
+ if (!mAudioOn) {
+ mAudioOn = true;
+ mAudioOnTimer.startRunningLocked(this);
+ }
+ Uid u = mUidStats.get(uid);
+ if (u != null) {
+ u.noteAudioTurnedOnLocked();
+ }
+ }
+ public void noteAudioOffLocked(int uid) {
+ if (mAudioOn) {
+ mAudioOn = false;
+ mAudioOnTimer.stopRunningLocked(this);
+ }
+ Uid u = mUidStats.get(uid);
+ if (u != null) {
+ u.noteAudioTurnedOffLocked();
+ }
+ }
+
+ public void noteVideoOnLocked(int uid) {
+ if (!mVideoOn) {
+ mVideoOn = true;
+ mVideoOnTimer.startRunningLocked(this);
+ }
+ Uid u = mUidStats.get(uid);
+ if (u != null) {
+ u.noteVideoTurnedOnLocked();
+ }
+ }
+
+ public void noteVideoOffLocked(int uid) {
+ if (mVideoOn) {
+ mVideoOn = false;
+ mVideoOnTimer.stopRunningLocked(this);
+ }
+ Uid u = mUidStats.get(uid);
+ if (u != null) {
+ u.noteVideoTurnedOffLocked();
+ }
+ }
+
public void noteWifiRunningLocked() {
if (!mWifiRunning) {
mWifiRunning = true;
@@ -1151,7 +1205,7 @@ public final class BatteryStatsImpl extends BatteryStats {
return mScreenBrightnessTimer[brightnessBin].getTotalTimeLocked(
batteryRealtime, which);
}
-
+
@Override public int getInputEventCount(int which) {
return mInputEventCounter.getCountLocked(which);
}
@@ -1159,7 +1213,7 @@ public final class BatteryStatsImpl extends BatteryStats {
@Override public long getPhoneOnTime(long batteryRealtime, int which) {
return mPhoneOnTimer.getTotalTimeLocked(batteryRealtime, which);
}
-
+
@Override public long getPhoneSignalStrengthTime(int strengthBin,
long batteryRealtime, int which) {
return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
@@ -1226,9 +1280,15 @@ public final class BatteryStatsImpl extends BatteryStats {
boolean mScanWifiLockOut;
StopwatchTimer mScanWifiLockTimer;
-
+
boolean mWifiMulticastEnabled;
StopwatchTimer mWifiMulticastTimer;
+
+ boolean mAudioTurnedOn;
+ StopwatchTimer mAudioTurnedOnTimer;
+
+ boolean mVideoTurnedOn;
+ StopwatchTimer mVideoTurnedOnTimer;
Counter[] mUserActivityCounters;
@@ -1259,6 +1319,8 @@ public final class BatteryStatsImpl extends BatteryStats {
mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables);
mWifiMulticastTimer = new StopwatchTimer(WIFI_MULTICAST_ENABLED,
null, mUnpluggables);
+ mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables);
+ mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables);
}
@Override
@@ -1343,6 +1405,38 @@ public final class BatteryStatsImpl extends BatteryStats {
}
@Override
+ public void noteVideoTurnedOnLocked() {
+ if (!mVideoTurnedOn) {
+ mVideoTurnedOn = true;
+ mVideoTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
+ }
+ }
+
+ @Override
+ public void noteVideoTurnedOffLocked() {
+ if (mVideoTurnedOn) {
+ mVideoTurnedOn = false;
+ mVideoTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
+ }
+ }
+
+ @Override
+ public void noteAudioTurnedOnLocked() {
+ if (!mAudioTurnedOn) {
+ mAudioTurnedOn = true;
+ mAudioTurnedOnTimer.startRunningLocked(BatteryStatsImpl.this);
+ }
+ }
+
+ @Override
+ public void noteAudioTurnedOffLocked() {
+ if (mAudioTurnedOn) {
+ mAudioTurnedOn = false;
+ mAudioTurnedOnTimer.stopRunningLocked(BatteryStatsImpl.this);
+ }
+ }
+
+ @Override
public void noteFullWifiLockReleasedLocked() {
if (mFullWifiLockOut) {
mFullWifiLockOut = false;
@@ -1386,7 +1480,17 @@ public final class BatteryStatsImpl extends BatteryStats {
public long getWifiTurnedOnTime(long batteryRealtime, int which) {
return mWifiTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
}
-
+
+ @Override
+ public long getAudioTurnedOnTime(long batteryRealtime, int which) {
+ return mAudioTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
+ }
+
+ @Override
+ public long getVideoTurnedOnTime(long batteryRealtime, int which) {
+ return mVideoTurnedOnTimer.getTotalTimeLocked(batteryRealtime, which);
+ }
+
@Override
public long getFullWifiLockTime(long batteryRealtime, int which) {
return mFullWifiLockTimer.getTotalTimeLocked(batteryRealtime, which);
@@ -1437,7 +1541,7 @@ public final class BatteryStatsImpl extends BatteryStats {
return mCurrentTcpBytesSent + (mStartedTcpBytesSent >= 0
? (NetStat.getUidTxBytes(mUid) - mStartedTcpBytesSent) : 0);
}
-
+
void writeToParcelLocked(Parcel out, long batteryRealtime) {
out.writeInt(mWakelockStats.size());
for (Map.Entry<String, Uid.Wakelock> wakelockEntry : mWakelockStats.entrySet()) {
@@ -1475,6 +1579,8 @@ public final class BatteryStatsImpl extends BatteryStats {
out.writeLong(mTcpBytesSentAtLastUnplug);
mWifiTurnedOnTimer.writeToParcel(out, batteryRealtime);
mFullWifiLockTimer.writeToParcel(out, batteryRealtime);
+ mAudioTurnedOnTimer.writeToParcel(out, batteryRealtime);
+ mVideoTurnedOnTimer.writeToParcel(out, batteryRealtime);
mScanWifiLockTimer.writeToParcel(out, batteryRealtime);
mWifiMulticastTimer.writeToParcel(out, batteryRealtime);
if (mUserActivityCounters == null) {
@@ -1534,6 +1640,10 @@ public final class BatteryStatsImpl extends BatteryStats {
mWifiTurnedOnTimer = new StopwatchTimer(WIFI_TURNED_ON, null, mUnpluggables, in);
mFullWifiLockOut = false;
mFullWifiLockTimer = new StopwatchTimer(FULL_WIFI_LOCK, null, mUnpluggables, in);
+ mAudioTurnedOn = false;
+ mAudioTurnedOnTimer = new StopwatchTimer(AUDIO_TURNED_ON, null, mUnpluggables, in);
+ mVideoTurnedOn = false;
+ mVideoTurnedOnTimer = new StopwatchTimer(VIDEO_TURNED_ON, null, mUnpluggables, in);
mScanWifiLockOut = false;
mScanWifiLockTimer = new StopwatchTimer(SCAN_WIFI_LOCK, null, mUnpluggables, in);
mWifiMulticastEnabled = false;
@@ -2327,7 +2437,7 @@ public final class BatteryStatsImpl extends BatteryStats {
StopwatchTimer t = getSensorTimerLocked(Sensor.GPS, false);
if (t != null) {
t.stopRunningLocked(BatteryStatsImpl.this);
- }
+ }
}
public BatteryStatsImpl getBatteryStats() {
@@ -2764,6 +2874,10 @@ public final class BatteryStatsImpl extends BatteryStats {
u.mWifiTurnedOnTimer.readSummaryFromParcelLocked(in);
u.mFullWifiLockOut = false;
u.mFullWifiLockTimer.readSummaryFromParcelLocked(in);
+ u.mAudioTurnedOn = false;
+ u.mAudioTurnedOnTimer.readSummaryFromParcelLocked(in);
+ u.mVideoTurnedOn = false;
+ u.mVideoTurnedOnTimer.readSummaryFromParcelLocked(in);
u.mScanWifiLockOut = false;
u.mScanWifiLockTimer.readSummaryFromParcelLocked(in);
u.mWifiMulticastEnabled = false;
@@ -3063,6 +3177,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int ikw = 0; ikw < NKW; ikw++) {
if (in.readInt() != 0) {
String wakelockName = in.readString();
+ in.readInt(); // Extra 0/1 written by Timer.writeTimerToParcel
SamplingTimer kwlt = new SamplingTimer(mUnpluggables, mOnBattery, in);
mKernelWakelockStats.put(wakelockName, kwlt);
}
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
new file mode 100644
index 0000000..f08dddd
--- /dev/null
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -0,0 +1,185 @@
+/*
+ * 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.internal.os;
+
+
+import android.content.Context;
+import android.content.res.XmlResourceParser;
+
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.util.HashMap;
+
+/**
+ * Reports power consumption values for various device activities. Reads values from an XML file.
+ * Customize the XML file for different devices.
+ * [hidden]
+ */
+public class PowerProfile {
+
+ /**
+ * No power consumption, or accounted for elsewhere.
+ */
+ public static final String POWER_NONE = "none";
+
+ /**
+ * Power consumption when CPU is in power collapse mode.
+ */
+ public static final String POWER_CPU_IDLE = "cpu.idle";
+
+ /**
+ * Power consumption when CPU is running at normal speed.
+ */
+ public static final String POWER_CPU_NORMAL = "cpu.normal";
+
+ /**
+ * Power consumption when CPU is running at full speed.
+ */
+ public static final String POWER_CPU_FULL = "cpu.full";
+
+ /**
+ * Power consumption when WiFi driver is scanning for networks.
+ */
+ public static final String POWER_WIFI_SCAN = "wifi.scan";
+
+ /**
+ * Power consumption when WiFi driver is on.
+ */
+ public static final String POWER_WIFI_ON = "wifi.on";
+
+ /**
+ * Power consumption when WiFi driver is transmitting/receiving.
+ */
+ public static final String POWER_WIFI_ACTIVE = "wifi.active";
+
+ /**
+ * Power consumption when GPS is on.
+ */
+ public static final String POWER_GPS_ON = "gps.on";
+
+ /**
+ * Power consumption when Bluetooth driver is on.
+ */
+ public static final String POWER_BLUETOOTH_ON = "bluetooth.on";
+
+ /**
+ * Power consumption when Bluetooth driver is transmitting/receiving.
+ */
+ public static final String POWER_BLUETOOTH_ACTIVE = "bluetooth.active";
+
+ /**
+ * Power consumption when screen is on, not including the backlight power.
+ */
+ public static final String POWER_SCREEN_ON = "screen.on";
+
+ /**
+ * Power consumption when cell radio is on but not on a call.
+ */
+ public static final String POWER_RADIO_ON = "radio.on";
+
+ /**
+ * Power consumption when talking on the phone.
+ */
+ public static final String POWER_RADIO_ACTIVE = "radio.active";
+
+ /**
+ * Power consumption at full backlight brightness. If the backlight is at
+ * 50% brightness, then this should be multiplied by 0.5
+ */
+ public static final String POWER_SCREEN_FULL = "screen.full";
+
+ /**
+ * Power consumed by the audio hardware when playing back audio content. This is in addition
+ * to the CPU power, probably due to a DSP and / or amplifier.
+ */
+ public static final String POWER_AUDIO = "dsp.audio";
+
+ /**
+ * Power consumed by any media hardware when playing back video content. This is in addition
+ * to the CPU power, probably due to a DSP.
+ */
+ public static final String POWER_VIDEO = "dsp.video";
+
+ static final HashMap<String, Double> sPowerMap = new HashMap<String, Double>();
+
+ private static final String TAG_DEVICE = "device";
+ private static final String TAG_ITEM = "item";
+ private static final String ATTR_NAME = "name";
+
+ public PowerProfile(Context context, CharSequence profile) {
+ // Read the XML file for the given profile (normally only one per
+ // device)
+ if (sPowerMap.size() == 0) {
+ readPowerValuesFromXml(context, profile);
+ }
+ }
+
+ private void readPowerValuesFromXml(Context context, CharSequence profile) {
+ // FIXME
+ //int id = context.getResources().getIdentifier(profile.toString(), "xml",
+ // "com.android.internal");
+ int id = com.android.internal.R.xml.power_profile_default;
+ XmlResourceParser parser = context.getResources().getXml(id);
+
+ try {
+ XmlUtils.beginDocument(parser, TAG_DEVICE);
+
+ while (true) {
+ XmlUtils.nextElement(parser);
+
+ String element = parser.getName();
+ if (element == null || !(element.equals(TAG_ITEM))) {
+ break;
+ }
+
+ String name = parser.getAttributeValue(null, ATTR_NAME);
+ if (parser.next() == XmlPullParser.TEXT) {
+ String power = parser.getText();
+ double value = 0;
+ try {
+ value = Double.valueOf(power);
+ } catch (NumberFormatException nfe) {
+ }
+ sPowerMap.put(name, value);
+ }
+ }
+ } catch (XmlPullParserException e) {
+ throw new RuntimeException(e);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ } finally {
+ parser.close();
+ }
+ }
+
+ /**
+ * Returns the average current in mA consumed by the subsystem
+ * @param type the subsystem type
+ * @return the average current in milliAmps.
+ */
+ public double getAveragePower(String type) {
+ if (sPowerMap.containsKey(type)) {
+ return sPowerMap.get(type);
+ } else {
+ return 0;
+ }
+ }
+}
diff --git a/core/jni/android_hardware_SensorManager.cpp b/core/jni/android_hardware_SensorManager.cpp
index 75aa458..3e27978 100644
--- a/core/jni/android_hardware_SensorManager.cpp
+++ b/core/jni/android_hardware_SensorManager.cpp
@@ -14,9 +14,13 @@
* limitations under the License.
*/
-#define LOG_TAG "Sensors"
+#define LOG_TAG "SensorManager"
+
+#define LOG_NDEBUG 0
+#include "utils/Log.h"
#include <hardware/sensors.h>
+#include <cutils/native_handle.h>
#include "jni.h"
#include "JNIHelp.h"
@@ -106,12 +110,33 @@ sensors_data_uninit(JNIEnv *env, jclass clazz)
}
static jint
-sensors_data_open(JNIEnv *env, jclass clazz, jobject fdo)
+sensors_data_open(JNIEnv *env, jclass clazz, jobjectArray fdArray, jintArray intArray)
{
jclass FileDescriptor = env->FindClass("java/io/FileDescriptor");
- jfieldID offset = env->GetFieldID(FileDescriptor, "descriptor", "I");
- int fd = env->GetIntField(fdo, offset);
- return sSensorDevice->data_open(sSensorDevice, fd); // doesn't take ownership of fd
+ jfieldID fieldOffset = env->GetFieldID(FileDescriptor, "descriptor", "I");
+ int numFds = (fdArray ? env->GetArrayLength(fdArray) : 0);
+ int numInts = (intArray ? env->GetArrayLength(intArray) : 0);
+ native_handle_t* handle = native_handle_create(numFds, numInts);
+ int offset = 0;
+
+ for (int i = 0; i < numFds; i++) {
+ jobject fdo = env->GetObjectArrayElement(fdArray, i);
+ if (fdo) {
+ handle->data[offset++] = env->GetIntField(fdo, fieldOffset);
+ } else {
+ handle->data[offset++] = -1;
+ }
+ }
+ if (numInts > 0) {
+ jint* ints = env->GetIntArrayElements(intArray, 0);
+ for (int i = 0; i < numInts; i++) {
+ handle->data[offset++] = ints[i];
+ }
+ env->ReleaseIntArrayElements(intArray, ints, 0);
+ }
+
+ // doesn't take ownership of the native handle
+ return sSensorDevice->data_open(sSensorDevice, handle);
}
static jint
@@ -157,7 +182,7 @@ static JNINativeMethod gMethods[] = {
(void*)sensors_module_get_next_sensor },
{"sensors_data_init", "()I", (void*)sensors_data_init },
{"sensors_data_uninit", "()I", (void*)sensors_data_uninit },
- {"sensors_data_open", "(Ljava/io/FileDescriptor;)I", (void*)sensors_data_open },
+ {"sensors_data_open", "([Ljava/io/FileDescriptor;[I)I", (void*)sensors_data_open },
{"sensors_data_close", "()I", (void*)sensors_data_close },
{"sensors_data_poll", "([F[I[J)I", (void*)sensors_data_poll },
};
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index b5f3a0f..fbaef5f 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -220,12 +220,6 @@
android:label="@string/permlab_installLocationProvider"
android:description="@string/permdesc_installLocationProvider" />
- <!-- Allows an application to install a location collector into the Location Manager -->
- <permission android:name="android.permission.INSTALL_LOCATION_COLLECTOR"
- android:protectionLevel="signatureOrSystem"
- android:label="@string/permlab_installLocationCollector"
- android:description="@string/permdesc_installLocationCollector" />
-
<!-- ======================================= -->
<!-- Permissions for accessing networks -->
<!-- ======================================= -->
diff --git a/core/res/res/drawable/search_spinner.xml b/core/res/res/drawable/search_spinner.xml
new file mode 100644
index 0000000..34c163d
--- /dev/null
+++ b/core/res/res/drawable/search_spinner.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2008, The Android Open Source Project
+**
+** Licensed under the Apache License, Version 2.0 (the "License");
+** you may not use this file except in compliance with the License.
+** You may obtain a copy of the License at
+**
+** http://www.apache.org/licenses/LICENSE-2.0
+**
+** Unless required by applicable law or agreed to in writing, software
+** distributed under the License is distributed on an "AS IS" BASIS,
+** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+** See the License for the specific language governing permissions and
+** limitations under the License.
+*/
+-->
+<animation-list
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:oneshot="false">
+ <item android:drawable="@drawable/search_spinner_anim1" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim2" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim3" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim4" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim5" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim6" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim7" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim8" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim9" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim10" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim11" android:duration="150" />
+ <item android:drawable="@drawable/search_spinner_anim12" android:duration="150" />
+</animation-list>
+
diff --git a/core/res/res/drawable/search_spinner_anim1.png b/core/res/res/drawable/search_spinner_anim1.png
new file mode 100755
index 0000000..e55b60d
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim1.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim10.png b/core/res/res/drawable/search_spinner_anim10.png
new file mode 100755
index 0000000..9611d97
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim10.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim11.png b/core/res/res/drawable/search_spinner_anim11.png
new file mode 100755
index 0000000..4261704
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim11.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim12.png b/core/res/res/drawable/search_spinner_anim12.png
new file mode 100755
index 0000000..0602314
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim12.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim2.png b/core/res/res/drawable/search_spinner_anim2.png
new file mode 100755
index 0000000..05d58e0
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim2.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim3.png b/core/res/res/drawable/search_spinner_anim3.png
new file mode 100755
index 0000000..69fa9c1
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim3.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim4.png b/core/res/res/drawable/search_spinner_anim4.png
new file mode 100755
index 0000000..9201bac
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim4.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim5.png b/core/res/res/drawable/search_spinner_anim5.png
new file mode 100755
index 0000000..f0c7101
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim5.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim6.png b/core/res/res/drawable/search_spinner_anim6.png
new file mode 100755
index 0000000..99d1d4e
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim6.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim7.png b/core/res/res/drawable/search_spinner_anim7.png
new file mode 100755
index 0000000..8ca3358
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim7.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim8.png b/core/res/res/drawable/search_spinner_anim8.png
new file mode 100755
index 0000000..408d723
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim8.png
Binary files differ
diff --git a/core/res/res/drawable/search_spinner_anim9.png b/core/res/res/drawable/search_spinner_anim9.png
new file mode 100755
index 0000000..42a2c65
--- /dev/null
+++ b/core/res/res/drawable/search_spinner_anim9.png
Binary files differ
diff --git a/core/res/res/layout/google_web_content_helper_layout.xml b/core/res/res/layout/google_web_content_helper_layout.xml
index 40f84bf..546c458 100644
--- a/core/res/res/layout/google_web_content_helper_layout.xml
+++ b/core/res/res/layout/google_web_content_helper_layout.xml
@@ -18,10 +18,28 @@
android:foregroundGravity="center"
android:measureAllChildren="false">
- <!-- Include the indeterminate progress dialog's layout. -->
- <include
- android:id="@+id/progressContainer"
- layout="@android:layout/progress_dialog" />
+ <LinearLayout android:id="@+id/progressContainer"
+ android:orientation="horizontal"
+ android:layout_gravity="center"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:baselineAligned="false"
+ android:paddingLeft="8dip"
+ android:paddingTop="10dip"
+ android:paddingRight="8dip"
+ android:paddingBottom="10dip">
+
+ <ProgressBar android:id="@android:id/progress"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:max="10000"
+ android:layout_marginRight="12dip" />
+
+ <TextView android:id="@+id/message"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical" />
+ </LinearLayout>
<WebView
android:id="@+id/web"
diff --git a/core/res/res/layout/list_gestures_overlay.xml b/core/res/res/layout/list_gestures_overlay.xml
new file mode 100644
index 0000000..54d72c8
--- /dev/null
+++ b/core/res/res/layout/list_gestures_overlay.xml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
diff --git a/core/res/res/layout/search_bar.xml b/core/res/res/layout/search_bar.xml
index b512490..7b7f8a6 100644
--- a/core/res/res/layout/search_bar.xml
+++ b/core/res/res/layout/search_bar.xml
@@ -71,6 +71,7 @@
android:layout_weight="1.0"
android:paddingLeft="8dip"
android:paddingRight="6dip"
+ android:drawablePadding="2dip"
android:singleLine="true"
android:inputType="text|textAutoComplete"
android:dropDownWidth="fill_parent"
diff --git a/core/res/res/layout/search_dropdown_item_icons_2line.xml b/core/res/res/layout/search_dropdown_item_icons_2line.xml
index 0d07490..2710b3b 100644
--- a/core/res/res/layout/search_dropdown_item_icons_2line.xml
+++ b/core/res/res/layout/search_dropdown_item_icons_2line.xml
@@ -67,13 +67,10 @@
android:textAppearance="?android:attr/textAppearanceSearchResultTitle"
android:singleLine="true"
android:layout_width="fill_parent"
- android:layout_height="29dip"
- android:paddingTop="4dip"
- android:gravity="center_vertical"
- android:layout_alignParentTop="true"
+ android:layout_height="wrap_content"
+ android:layout_centerVertical="true"
android:layout_toRightOf="@android:id/icon1"
android:layout_toLeftOf="@android:id/icon2"
- android:layout_above="@android:id/text2"
- android:layout_alignWithParentIfMissing="true" />
+ android:layout_above="@android:id/text2" />
</RelativeLayout>
diff --git a/core/res/res/raw/latin_lowercase b/core/res/res/raw/latin_lowercase
index 9c747d6..fd67333 100644
--- a/core/res/res/raw/latin_lowercase
+++ b/core/res/res/raw/latin_lowercase
Binary files differ
diff --git a/core/res/res/values-ja/donottranslate.xml b/core/res/res/values-ja/donottranslate.xml
new file mode 100644
index 0000000..f7c3566
--- /dev/null
+++ b/core/res/res/values-ja/donottranslate.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Default text encoding for WebSettings. -->
+ <string name="default_text_encoding">Shift_JIS</string>
+</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 052ab35..cda7431 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -324,6 +324,8 @@
<attr name="expandableListViewStyle" format="reference" />
<!-- Default Gallery style. -->
<attr name="galleryStyle" format="reference" />
+ <!-- Default GestureOverlayView style. -->
+ <attr name="gestureOverlayViewStyle" format="reference" />
<!-- Default GridView style. -->
<attr name="gridViewStyle" format="reference" />
<!-- The style resource to use for an ImageButton -->
@@ -1379,6 +1381,19 @@
will use only the number of items in the adapter and the number of items visible
on screen to determine the scrollbar's properties. -->
<attr name="smoothScrollbar" format="boolean" />
+ <!-- Defines the type of gesture to enable for the widget. -->
+ <attr name="gestures">
+ <!-- No gesture -->
+ <enum name="none" value="0" />
+ <!-- Gestures jump to a specific position in the content. This requires
+ fast scroll to be enabled. If fast scroll is enabled from XML,
+ jump gestures will be enabled automatically. -->
+ <enum name="jump" value="1" />
+ <!-- Gestures filter the content. This requires text filtering to be enabled.
+ If text filtering is enabled from XML, filter gestures will be enabled
+ automatically. -->
+ <enum name="filter" value="2" />
+ </attr>
</declare-styleable>
<declare-styleable name="AbsSpinner">
<!-- Reference to an array resource that will populate the Spinner. For static content,
@@ -1581,7 +1596,7 @@
<!-- Height of the divider. Will use the intrinsic height of the divider if this
is not specified. -->
<attr name="dividerHeight" format="dimension" />
- <!-- Defines the choice behavior for the List. By default, Lists do not have
+ <!-- Defines the choice behavior for the ListView. By default, lists do not have
any choice behavior. By setting the choiceMode to singleChoice, the List
allows up to one item to be in a chosen state. By setting the choiceMode to
multipleChoice, the list allows any number of items to be chosen. -->
@@ -2061,6 +2076,44 @@
<attr name="animateOnClick" format="boolean" />
</declare-styleable>
+ <!-- GestureOverlayView specific attributes. These attributes are used to configure
+ a GestureOverlayView from XML. -->
+ <declare-styleable name="GestureOverlayView">
+ <!-- Width of the stroke used to draw the gesture. -->
+ <attr name="gestureStrokeWidth" format="float" />
+ <!-- Color used to draw a gesture. -->
+ <attr name="gestureColor" format="color" />
+ <!-- Color used to draw the user's strokes until we are sure it's a gesture. -->
+ <attr name="uncertainGestureColor" format="color" />
+ <!-- Time, in milliseconds, to wait before the gesture fades out after the user
+ is done drawing it. -->
+ <attr name="fadeOffset" format="integer" />
+ <!-- Duration, in milliseconds, of the fade out effect after the user is done
+ drawing a gesture. -->
+ <attr name="fadeDuration" format="integer" />
+ <!-- Defines the type of strokes that define a gesture. -->
+ <attr name="gestureStrokeType">
+ <!-- A gesture is made of only one stroke. -->
+ <enum name="single" value="0" />
+ <!-- A gesture is made of multiple strokes. -->
+ <enum name="multiple" value="1" />
+ </attr>
+ <!-- Minimum length of a stroke before it is recognized as a gesture. -->
+ <attr name="gestureStrokeLengthThreshold" format="float" />
+ <!-- Squareness threshold of a stroke before it is recognized as a gesture. -->
+ <attr name="gestureStrokeSquarenessThreshold" format="float" />
+ <!-- Minimum curve angle a stroke must contain before it is recognized as a gesture. -->
+ <attr name="gestureStrokeAngleThreshold" format="float" />
+ <!-- Defines whether the overlay should intercept the motion events when a gesture
+ is recognized. -->
+ <attr name="eventsInterceptionEnabled" format="boolean" />
+ <!-- Defines whether the gesture will automatically fade out after being recognized. -->
+ <attr name="fadeEnabled" format="boolean" />
+ <!-- Indicates whether horizontal (when the orientation is vertical) or vertical
+ (when orientation is horizontal) strokes automatically define a gesture. -->
+ <attr name="orientation" />
+ </declare-styleable>
+
<!-- ======================================= -->
<!-- Widget package parent layout attributes -->
<!-- ======================================= -->
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 83ac8e2..7215685 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -34,4 +34,8 @@
<!-- The duration (in milliseconds) of a long animation. -->
<integer name="config_longAnimTime">300</integer>
+
+ <!-- Flag indicating whether Last Name comes before First Name.
+ This becomes true in Japan, for example.-->
+ <bool name="config_lastname_comes_before_firstname">false</bool>
</resources>
diff --git a/core/res/res/values/donottranslate.xml b/core/res/res/values/donottranslate.xml
new file mode 100644
index 0000000..6def3bf
--- /dev/null
+++ b/core/res/res/values/donottranslate.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/* //device/apps/common/assets/res/any/strings.xml
+**
+** 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.
+*/
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Default text encoding for WebSettings. -->
+ <string name="default_text_encoding">Latin-1</string>
+</resources>
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 07bb759..621270e 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1101,7 +1101,19 @@
<public type="attr" name="maxSdkVersion" />
<public type="attr" name="testOnly" />
<public type="attr" name="contentDescription" />
-
+ <public type="attr" name="gestureStrokeWidth" />
+ <public type="attr" name="gestureColor" />
+ <public type="attr" name="uncertainGestureColor" />
+ <public type="attr" name="fadeOffset" />
+ <public type="attr" name="fadeDuration" />
+ <public type="attr" name="gestures" />
+ <public type="attr" name="gestureStrokeType" />
+ <public type="attr" name="gestureStrokeLengthThreshold" />
+ <public type="attr" name="gestureStrokeSquarenessThreshold" />
+ <public type="attr" name="gestureStrokeAngleThreshold" />
+ <public type="attr" name="eventsInterceptionEnabled" />
+ <public type="attr" name="fadeEnabled" />
+
<public-padding type="attr" name="donut_resource_pad" end="0x0101029f" />
<public-padding type="id" name="donut_resource_pad" end="0x01020040" />
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 0f146e5..8b2689b 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -769,13 +769,7 @@
<!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permdesc_installLocationProvider">Create mock location sources for testing.
Malicious applications can use this to override the location and/or status returned by real
- location sources such as GPS or Network providers.</string>
-
- <!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permlab_installLocationCollector">permission to install a location collector</string>
- <!-- Description of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
- <string name="permdesc_installLocationCollector">Create mock location sources for testing.
- Malicious applications can use this to monitor and report your location to an external source.</string>
+ location sources such as GPS or Network providers or monitor and report your location to an external source.</string>
<!-- Title of an application permission, listed so the user can choose whether they want to allow the application to do this. -->
<string name="permlab_accessFineLocation">fine (GPS) location</string>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 8160c9c..490abde 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -171,6 +171,23 @@
<item name="android:fadingEdge">vertical</item>
</style>
+ <style name="Widget.GestureOverlayView">
+ <item name="android:gestureStrokeWidth">12.0</item>
+ <item name="android:gestureColor">#ffffff00</item>
+ <item name="android:uncertainGestureColor">#48ffff00</item>
+ <item name="android:fadeOffset">420</item>
+ <item name="android:fadeDuration">150</item>
+ <item name="android:gestureStrokeLengthThreshold">30.0</item>
+ <item name="android:gestureStrokeSquarenessThreshold">0.275</item>
+ <item name="android:gestureStrokeAngleThreshold">40.0</item>
+ <item name="android:eventsInterceptionEnabled">true</item>
+ </style>
+
+ <style name="Widget.GestureOverlayView.White">
+ <item name="android:gestureColor">#ff00ff00</item>
+ <item name="android:uncertainGestureColor">#4800ff00</item>
+ </style>
+
<style name="Widget.Button">
<item name="android:background">@android:drawable/btn_default</item>
<item name="android:focusable">true</item>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b168fb8..00dc6fa 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -142,7 +142,8 @@
<item name="editTextStyle">@android:style/Widget.EditText</item>
<item name="expandableListViewStyle">@android:style/Widget.ExpandableListView</item>
<item name="galleryStyle">@android:style/Widget.Gallery</item>
- <item name="gridViewStyle">@android:style/Widget.GridView</item>
+ <item name="gestureOverlayViewStyle">@android:style/Widget.GestureOverlayView</item>
+ <item name="gridViewStyle">@android:style/Widget.GridView</item>
<item name="imageButtonStyle">@android:style/Widget.ImageButton</item>
<item name="imageWellStyle">@android:style/Widget.ImageWell</item>
<item name="listViewStyle">@android:style/Widget.ListView</item>
@@ -225,6 +226,7 @@
<item name="textCheckMark">@android:drawable/indicator_check_mark_light</item>
<item name="textCheckMarkInverse">@android:drawable/indicator_check_mark_dark</item>
+ <item name="gestureOverlayViewStyle">@android:style/Widget.GestureOverlayView.White</item>
<item name="listViewStyle">@android:style/Widget.ListView.White</item>
<item name="listDivider">@drawable/divider_horizontal_bright</item>
<item name="listSeparatorTextViewStyle">@android:style/Widget.TextView.ListSeparator.White</item>
diff --git a/core/res/res/xml/power_profile_default.xml b/core/res/res/xml/power_profile_default.xml
new file mode 100644
index 0000000..d265b46
--- /dev/null
+++ b/core/res/res/xml/power_profile_default.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** 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.
+*/
+-->
+
+<device name="Android">
+ <item name="none">0</item>
+ <item name="screen.on">30</item>
+ <item name="bluetooth.active">103</item>
+ <item name="bluetooth.on">5</item>
+ <item name="screen.full">144</item>
+ <item name="wifi.on">23</item>
+ <item name="wifi.active">200</item>
+ <item name="wifi.scan">200</item>
+ <item name="cpu.idle">1.6</item>
+ <item name="cpu.normal">100</item>
+ <item name="cpu.full">140</item>
+ <item name="dsp.audio">70</item>
+ <item name="dsp.video">100</item>
+ <item name="radio.on">3</item>
+ <item name="radio.active">175</item>
+</device>
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index 526b6d9..33d6b3b 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -133,12 +133,13 @@
<assign-permission name="android.permission.READ_FRAME_BUFFER" uid="shell" />
<assign-permission name="android.permission.DEVICE_POWER" uid="shell" />
<assign-permission name="android.permission.INSTALL_LOCATION_PROVIDER" uid="shell" />
- <assign-permission name="android.permission.INSTALL_LOCATION_COLLECTOR" uid="shell" />
<assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="media" />
<assign-permission name="android.permission.ACCESS_DRM" uid="media" />
<assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="media" />
+ <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" />
+
<!-- This is a list of all the libraries available for application
code to link against. -->
diff --git a/data/fonts/DroidSansJapanese.ttf b/data/fonts/DroidSansJapanese.ttf
index ca79221..412fa3d 100755
--- a/data/fonts/DroidSansJapanese.ttf
+++ b/data/fonts/DroidSansJapanese.ttf
Binary files differ
diff --git a/docs/html/guide/appendix/media-formats.jd b/docs/html/guide/appendix/media-formats.jd
index a3cc0ff..db5a15e 100644
--- a/docs/html/guide/appendix/media-formats.jd
+++ b/docs/html/guide/appendix/media-formats.jd
@@ -2,8 +2,9 @@ page.title=Android Supported Media Formats
@jd:body
<p>The <a href="#core">Core Media Formats</a> table below describes the media format support built into the Android platform. Note that any given mobile device may provide support for additional formats or file types not listed in the table. </p>
-<p>For your convenience, the table <a href="#g1">T-Mobile G1 Media Formats</a> describes additional media format details for the T-Mobile G1 device. </p>
+<p>For your convenience, the table <a href="#g1">T-Mobile G1 Media Formats</a> describes additional media formats and characteristics provided by the T-Mobile G1 device. Other devices may support additional formats not listed on this page. </p>
+<p>As an application developer, you are free to make use of any media codec that is available on any Android-powered device, including those provided by the Android platform and those that are device-specific.</p>
<h2 id="core">Core Media Formats</h2>
@@ -130,7 +131,7 @@ page.title=Android Supported Media Formats
<td style="text-align: center;">X</td>
<td style="text-align: center;">X</td>
<td>&nbsp;</td>
-<td>3GPP (.3gp)</td>
+<td>3GPP (.3gp) and MPEG-4 (.mp4)</td>
</tr>
<tr>
@@ -151,9 +152,9 @@ page.title=Android Supported Media Formats
</tbody></table>
-<h2 id="g1">T-Mobile G1 Media Formats</h2>
+<h2 id="g1">T-Mobile G1 Media Formats and Characteristics</h2>
-<p>In addition to the core media formats supported in the Android platform, the T-Mobile G1 also supports the formats listed below.</p>
+<p>The table below lists media formats supported by the T-Mobile G1 in addition to those provided as part of the Android platform. This table also details G1-specific performance characteristics of some Android core media formats.</p>
<table>
<tbody>
@@ -163,7 +164,7 @@ page.title=Android Supported Media Formats
<th>Format</th>
<th>Encoder</th>
<th>Decoder</th>
-<th>Details</th>
+<th>Comment</th>
<th>File Type(s) Supported</th>
</tr>
@@ -178,13 +179,13 @@ page.title=Android Supported Media Formats
<li>L2: &lt;=161 kbps &lt;=48 kHz</li>
<li>L3: &lt;385 kbps &lt;=48 kHz</li>
</ul>
-Mono and stereo profiles with 16-bits per sample. Decoder does not support WMA Pro, Lossless, or Speech codecs.
+Mono and stereo profiles with 16-bits per sample. Decoder does not support WMA Pro, Lossless, or Speech codecs.
</td>
<td>Windows Media Audio (.wma)</td>
</tr>
<tr>
-<td rowspan="3">Video</td>
+<td rowspan="2">Video</td>
<td>WMV</td>
<td>&nbsp;</td>
<td style="text-align: center;">X</td>
@@ -193,22 +194,16 @@ Mono and stereo profiles with 16-bits per sample. Decoder does not support WMA P
</tr>
<tr>
-<td>H.263</td>
-<td style="text-align: center;">X</td>
-<td style="text-align: center;">X</td>
-<td>&nbsp;</td>
-<td>3GPP (.3gp) and MPEG-4 (.mp4)</td>
-</tr>
-
-<tr>
<td>H.264&nbsp;AVC</td>
<td>&nbsp;</td>
<td style="text-align: center;">X</td>
-<td>Limited to baseline profile up to 480x320, and 600 kbps average bitrate for the video stream.</td>
+<td>On the G1, this decoder is limited to baseline profile up to 480x320, and 600 kbps average bitrate for the video stream.</td>
<td>3GPP (.3gp) and MPEG-4 (.mp4)</td>
</tr>
</tbody></table>
-<p>Note that Windows Media codecs are not part of the Android platform and require special licensing from Microsoft or an authorized developer such as Packet Video.</p>
+
+
+
diff --git a/docs/html/guide/developing/eclipse-adt.jd b/docs/html/guide/developing/eclipse-adt.jd
index 75f3d78..3b3bb38 100644
--- a/docs/html/guide/developing/eclipse-adt.jd
+++ b/docs/html/guide/developing/eclipse-adt.jd
@@ -38,15 +38,15 @@ manifest and resource files.</li>
<p>To begin developing Android applications in the Eclipse IDE with ADT, you first need to
download the Eclipse IDE and then download and install the ADT plugin. To do so, follow the
-steps given in <a href="{@docRoot}sdk/1.5_r1/installing.html#installingplugin">Installing
+steps given in <a href="{@docRoot}sdk/{@sdkCurrent}/installing.html#installingplugin">Installing
the ADT Plugin</a>.</p>
<p>If you are already developing applications using a version of ADT earlier than 0.9, make
sure to upgrade to the latest version before continuing. See the guide to
-<a href="{@docRoot}sdk/1.5_r1/upgrading.html#UpdateAdt">Update Your Eclipse ADT Plugin</a>.</p>
+<a href="{@docRoot}sdk/{@sdkCurrent}/upgrading.html#UpdateAdt">Updating Your Eclipse ADT Plugin</a>.</p>
<p class="note"><strong>Note:</strong> This guide assumes you are using the latest version of
-the ADT plugin (0.9). While most of the information covered also applies to previous
+the ADT plugin. While most of the information covered also applies to previous
versions, if you are using an older version, you may want to consult this document from
the set of documentation included in your SDK package (instead of the online version).</p>
@@ -138,9 +138,9 @@ folders and files in your new project:</p>
<p><em>Wait!</em> Before you can run your application on the Android Emulator,
you <strong>must</strong> create an Android Virtual Device (AVD).
An AVD is a configuration that specifies the Android platform to be used on the emulator.
-You can read more about AVDs in the <a href="{@docRoot}guide/developing/index.html#avd">Developing
-Overview</a>, but if you just want to get started, follow the simple guide below to create
-an AVD.</p>
+You can read more in the <a href="{@docRoot}guide/developing/tools/avd.html">Android Virtual
+Devices</a> document, but if you just want to get started, follow the simple guide below to
+create an AVD.</p>
<p>If you will be running your applications only on actual device hardware, you do not
need an AVD &mdash; see
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 883170a..ea326b0 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -116,10 +116,10 @@ home=true
'sdk': {
'layout':"imgLeft",
'icon':"sdk-small.png",
- 'name':"SDK 1.5 r1",
+ 'name':"SDK 1.5 r2",
'img':"sdk-large.png",
- 'title':"Android 1.5 SDK r1",
- 'desc': "<p>The final version of the Android 1.5 SDK is now available. It includes new APIs for Android 1.5, updated developer tools, multiple platform versions, and a Google APIs add-on.</p><p><a href='{@docRoot}sdk/1.5_r1/index.html'>Download Android 1.5 SDK</a></p>"
+ 'title':"Android 1.5 SDK",
+ 'desc': "<p>Android 1.5 SDK is now available. It includes new APIs for Android 1.5, updated developer tools, multiple platform versions, and a Google APIs add-on.</p><p><a href='{@docRoot}sdk/1.5_r2/index.html'>Download Android 1.5 SDK</a></p>"
},
'mapskey': {
diff --git a/docs/html/sdk/1.5_r2/index.jd b/docs/html/sdk/1.5_r2/index.jd
new file mode 100644
index 0000000..15342a4
--- /dev/null
+++ b/docs/html/sdk/1.5_r2/index.jd
@@ -0,0 +1,87 @@
+sdk.version=1.5
+sdk.rel.id=2
+sdk.date=May 2009
+
+sdk.win_download=android-sdk-windows-1.5_r2.zip
+sdk.win_bytes=178346828
+sdk.win_checksum=ba54ac6bda45921d442b74b6de6ff6a9
+
+sdk.mac_download=android-sdk-mac_x86-1.5_r2.zip
+sdk.mac_bytes=169945128
+sdk.mac_checksum=f4e06a5194410243f213d0177713d6c9
+
+sdk.linux_download=android-sdk-linux_x86-1.5_r2.zip
+sdk.linux_bytes=165035130
+sdk.linux_checksum=1d3c3d099e95a31c43a7b3e6ae307ed3
+
+page.title=Android 1.5 SDK, Release 2
+@jd:body
+
+<p>For more information on this SDK release, read the
+<a href="{@docRoot}sdk/RELEASENOTES.html#1.5_r2">Release Notes</a>.</p>
+
+<h2>SDK Contents</h2>
+
+<h4>Development tools</h4>
+
+<p>The SDK includes a full set of tools for developing and debugging application code and designing an application UI. You can read about the tools in the
+<a href="{@docRoot}guide/developing/tools/index.html">Dev Guide</a> and access them in the <code>&lt;sdk&gt;/tools/</code> directory.
+
+<p>The tools package in this SDK includes updates from those provided in the previous SDK. The tools also require a different project structure. To use the new tools, you need to migrate your applications to the new development environment. For more information about how to migrate, see <a href="{@docRoot}sdk/1.5_r2/upgrading.html">Upgrading the SDK</a>.
+
+<p>For more information about the new tools features, see the <a href="{@docRoot}sdk/RELEASENOTES.html">SDK Release Notes</a>.
+
+<h4 id="system_images">Android Platforms</h4>
+
+<p>This SDK includes multiple Android platform versions that you use to develop applications. For each version, both a fully compliant Android library and system image are provided. The table below lists the platform versions included in this SDK. For more information about a platform version &mdash; features, applications included, localizations, API changes, and so on &mdash; see its Version Notes. </p>
+
+<table style="margin-right:1em;" width="80%">
+<tr>
+<th><nobr>Platform</nobr></th><th><nobr>API Level</nobr></th><th>Notes</th><th>Description</th>
+</tr>
+
+<tr>
+<td width="5%"><nobr>Android 1.5</nobr></td>
+<td width="5%">3</td>
+<td width="5%"><nobr><a href="{@docRoot}sdk/android-1.5.html">Version Notes</a></nobr></td>
+<td>Includes a standard Android 1.5 library and system image with a set of development applications. Does not include any external libraries (such as the Maps external library).</td>
+</tr>
+<tr>
+<td width="5%"><nobr>Android 1.1</nobr></td>
+<td width="5%">2</td>
+<td width="5%"><nobr><a href="{@docRoot}sdk/android-1.1.html">Version Notes</a></nobr></td>
+<td>Includes a compliant Android 1.1 library and system image with a set of development applications. Also includes the Maps external library (due to legacy build system issues).</td>
+</tr>
+</table>
+
+<h4 id="system_images">SDK Add-Ons</h4>
+
+<p>An SDK add-on provides a development environment for an Android external library or a customized (but fully compliant) Android system image. This SDK includes the SDK add-on listed below. The Android system API Level required by the add-on is noted.</p>
+
+<table style="margin-right:1em;" width="80%">
+<tr>
+<th><nobr>Add-On</nobr></th><th><nobr>API Level</nobr></th><th>Notes</th><th>Description</th>
+</tr>
+<tr>
+<td width="5%"><nobr>Google APIs</nobr></td>
+<td width="5%">3</td>
+<td width="5%">&nbsp;</td>
+<td>Includes the com.google.android.maps external library, a compliant
+system image, a {@link android.location.Geocoder Geocoder}
+backend service implementation, documentation, and sample code. </td>
+</tr>
+</table>
+
+<h4>Sample Code and Applications</h4>
+
+<p>You can look at a variety of tutorials and samples in the <a href="{@docRoot}guide/samples/index.html">Dev Guide</a> and access the sample code itself
+in the <code>&lt;sdk&gt;/platforms/android-1.5/samples/</code> directory of the SDK package. Note the new location &mdash; the SDK now includes multiple platform versions that you can develop against and each has its own sample code directory. </p>
+
+<h4>Documentation</h4>
+
+<p>The SDK package includes a full set of local documentation. To view it, open the <code>&lt;sdk&gt;/documentation.html</code> file in a web browser. If you are developing in an IDE such as Eclipse, you can also view the reference documentation directly in the IDE. </p>
+
+<p>The most current documentation is always available on the Android Developers site:</p>
+
+<p style="margin-left:2em;"><a href="http://developer.android.com/index.html">http://developer.android.com/</a></p>
+
diff --git a/docs/html/sdk/1.5_r2/installing.jd b/docs/html/sdk/1.5_r2/installing.jd
new file mode 100644
index 0000000..69b2c1b
--- /dev/null
+++ b/docs/html/sdk/1.5_r2/installing.jd
@@ -0,0 +1,332 @@
+sdk.version=1.5
+sdk.rel.id=2
+sdk.date=April 2009
+
+page.title=Installing the Android SDK
+@jd:body
+
+
+<p>This page describes how to install the Android SDK and set up your
+development environment. If you haven't downloaded the SDK, you can
+do so from the
+<a href="{@docRoot}sdk/1.5_r2/index.html">Download</a> page. Once you've downloaded
+the SDK, return here.</p>
+
+<p>If you encounter any problems during installation, see the
+<a href="#installnotes">Installation Notes</a> at the bottom of
+this page.</p>
+
+<h4 style="margin-top">Upgrading?</h4>
+<p>If you have already developed applications using an earlier version
+of the SDK, please read
+<a href="{@docRoot}sdk/1.5_r2/upgrading.html"><strong>Upgrading the
+SDK</strong></a></b>, instead.
+</p>
+
+
+<h2 id="setup">Preparing for Installation</h2>
+
+<p>Before you begin, take a moment to confirm that your development machine meets the
+<a href="{@docRoot}sdk/1.5_r2/requirements.html">System Requirements</a>.
+</p>
+
+<p>If you will be developing on Eclipse with the Android Development
+Tools (ADT) Plugin &mdash; the recommended path if you are new to
+Android &mdash; make sure that you have a suitable version of Eclipse
+installed on your computer (3.3 or newer). If you need to install Eclipse, you can
+download it from this location: </p>
+
+<p style="margin-left:2em;"><a href=
+"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a
+></p>
+
+<p>A Java or RCP version of Eclipse is recommended. </p>
+
+<h2 id="installingsdk">Installing the SDK</h2>
+
+<p>After downloading the SDK, unpack the .zip archive to a suitable location on your machine.
+By default, the SDK files are unpacked into a directory named
+<code>android_sdk_<em>&lt;platform</em>&gt;_<em>&lt;release&gt;</em></code>.
+The directory contains a local copy of the documentation (accessible by opening
+<code>documentation.html</code> in your browser) and the subdirectories
+<code>tools/</code>, <code>add-ons/</code>, <code>platforms/</code>, and others. Inside
+each subdirectory of <code>platforms/</code> you'll find <code>samples/</code>, which includes
+code samples that are specific to each version of the platform.</p>
+
+<p>Make a note of the name and location of the unpacked SDK directory on your system &mdash; you
+will need to refer to the SDK directory later, when setting up the Android plugin or when
+using the SDK tools.</p>
+
+<p>Optionally, you may want to add the location of the SDK's primary <code>tools</code> directory
+to your system PATH. The primary <code>tools/</code> directory is located at the root of the
+SDK folder. Adding <code>tools</code> to your path lets you run Android Debug Bridge (adb) and
+the other command line <a href="{@docRoot}guide/developing/tools/index.html">tools</a> without
+needing to supply the full path to the tools directory. </p>
+<ul>
+ <li>On Linux, edit your <code>~/.bash_profile</code> or <code>~/.bashrc</code> file. Look
+ for a line that sets the PATH environment variable and add the
+ full path to the <code>tools/</code> directory to it. If you don't
+ see a line setting the path, you can add one:</li>
+
+ <ul><code>export PATH=${PATH}:<em>&lt;your_sdk_dir&gt;</em>/tools</code></ul>
+
+ <li>On a Mac, look in your home directory for <code>.bash_profile</code> and
+ proceed as for Linux. You can create the <code>.bash_profile</code> if
+ you haven't already set one up on your machine. </li>
+
+ <li>On Windows, right-click on My Computer, and select Properties.
+ Under the Advanced tab, hit the Environment Variables button, and in the
+ dialog that comes up, double-click on Path (under System Variables). Add the full path to the
+ <code>tools/</code> directory to the path. </li>
+ </ul>
+
+<p>Note that, if you update your SDK in the future, you
+should remember to update your PATH settings to point to the new location, if different.</p>
+
+<p>If you will be using the Eclipse IDE as your development environment,
+the next section describes how to install the Android Development Tools plugin and set up Eclipse.
+If you choose not to use Eclipse, you can
+develop Android applications in an IDE of your choice and then compile, debug and deploy using
+the tools included in the SDK (skip to <a href="#next">Next Steps</a>).</p>
+
+
+<h2 id="installingplugin">Installing the ADT Plugin for Eclipse</h2>
+
+<p>Android offers a custom plugin for the Eclipse IDE, called Android
+Development Tools (ADT), that is designed to give you a powerful,
+integrated environment in which to build Android applications. It
+extends the capabilites of Eclipse to let you quickly set up new Android
+projects, create an application UI, add components based on the Android
+Framework API, debug your applications using the Android SDK tools, and even export
+signed (or unsigned) APKs in order to distribute your application.</p>
+
+<p>In general, using Eclipse with ADT is a highly recommended
+approach to Android development and is the fastest way to get started.
+(If you prefer to work in an IDE other than Eclipse,
+you do not need to install Eclipse or ADT, instead, you can directly
+use the SDK tools to build and debug your application.)</p>
+
+<p>Once you have Eclipse installed, as described in <a href="#setup">Preparing for
+Installation</a>, follow the steps below to
+download the ADT plugin and install it in your respective Eclipse
+environment. </p>
+
+<table style="font-size:100%">
+<tr><th>Eclipse 3.3 (Europa)</th><th>Eclipse 3.4 (Ganymede)</th></tr>
+<tr>
+<td width="45%">
+<!-- 3.3 steps -->
+<ol>
+ <li>Start Eclipse, then select <strong>Help</strong> &gt; <strong>Software Updates</strong>
+&gt; <strong>Find and Install...</strong>. </li>
+ <li>In the dialog that appears, select <strong>Search for new features to install</strong>
+and click <strong>Next</strong>. </li>
+ <li>Click <strong>New Remote Site</strong>. </li>
+ <li>In the resulting dialog box, enter a name for the remote site (e.g. "Android Plugin") and
+ enter the URL:
+ <pre>https://dl-ssl.google.com/android/eclipse/</pre>
+ <p>If you have trouble aqcuiring the plugin, try using "http" in the URL,
+ instead of "https" (https is preferred for security reasons).</p>
+ <p>Click <strong>OK</strong>.</p> </li>
+ <li>You should now see the new site added to the search list (and checked).
+ Click <strong>Finish</strong>. </li>
+ <li>In the subsequent Search Results dialog box, select the checkbox for the
+ "Android Plugin".
+ This will select the nested tools: "Android DDMS" and "Android Development Tools".
+ Click <strong>Next</strong>.</li>
+ <li>Read and accept the license agreement, then click <strong>Next</strong>. </li>
+ <li>On the following Installation window, click <strong>Finish</strong>. </li>
+ <li>The ADT plugin is not digitally signed. Accept the installation anyway
+ by clicking <strong>Install All</strong>. </li>
+ <li>Restart Eclipse. </li>
+</ol>
+
+</td>
+<td>
+
+<!-- 3.4 steps -->
+<ol>
+ <li>Start Eclipse, then select <strong>Help</strong> &gt; <strong>Software Updates...</strong>.</li>
+ <li>In the dialog that appears, click the <strong>Available Software</strong> tab. </li>
+ <li>Click <strong>Add Site...</strong> </li>
+ <li>Enter the Location:
+ <pre>https://dl-ssl.google.com/android/eclipse/</pre>
+ <p>If you have trouble aqcuiring the plugin, try using "http" in the Location URL,
+ instead of "https" (https is preferred for security reasons).</p>
+ <p>Click <strong>OK</strong>.</p></li>
+ <li>Back in the Available Software view, you should see the plugin listed by the URL,
+ with "Developer Tools" nested within it. Select the checkbox next to
+ Developer Tools and click <strong>Install...</strong></li>
+ <li>On the subsequent Install window, "Android DDMS" and "Android Development Tools"
+ should both be checked. Click <strong>Next</strong>. </li>
+ <li>Read and accept the license agreement, then click <strong>Finish</strong>.</li>
+ <li>Restart Eclipse. </li>
+</ol>
+
+</td>
+</tr>
+</table>
+
+<p>Now modify your Eclipse preferences to point to the Android SDK directory:</p>
+<ol>
+ <li>Select <strong>Window</strong> &gt; <strong>Preferences...</strong> to open the Preferences
+ panel (Mac: <strong>Eclipse</strong> &gt; <strong>Preferences</strong>).</li>
+ <li>Select <strong>Android</strong> from the left panel. </li>
+ <li>For the <em>SDK Location</em> in the main panel, click <strong>Browse...</strong> and
+locate your downloaded SDK directory. </li>
+ <li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li>
+</ol>
+
+<p>Done! If you haven't encountered any problems, then you're ready to
+begin developing Android applications. See the
+<a href="#next">Next Steps</a> section for suggestions on how to start. </p>
+
+
+<h3 id="troubleshooting">Troubleshooting ADT Installation</h3>
+<p>
+If you are having trouble downloading the ADT plugin after following the steps above, here are
+some suggestions: </p>
+
+<ul>
+ <li>If Eclipse can not find the remote update site containing the ADT plugin, try changing
+ the remote site URL to use http, rather than https. That is, set the Location for the remote site to:
+ <pre>http://dl-ssl.google.com/android/eclipse/</pre></li>
+ <li>If you are behind a firewall (such as a corporate firewall), make
+ sure that you have properly configured your proxy settings in Eclipse.
+ In Eclipse 3.3/3.4, you can configure proxy information from the main
+ Eclipse menu in <strong>Window</strong> (on Mac, <strong>Eclipse</strong>) &gt;
+ <strong>Preferences</strong> &gt; <strong>General</strong> &gt;
+ <strong>Network Connections</strong>.</li>
+</ul>
+<p>
+If you are still unable to use Eclipse to download the ADT plugin as a remote update site, you
+can download the ADT zip file to your local machine and manually install the it:
+</p>
+<ol>
+ <li><a href="{@docRoot}sdk/adt_download.html">Download the ADT zip file</a> (do not unpack it).</li>
+ <li>Follow steps 1 and 2 in the default install instructions (above).</li>
+ <li>In Eclipse 3.3, click <strong>New Archive Site...</strong>. <br/>
+ In Eclipse 3.4, click <strong>Add Site...</strong>, then <strong>Archive...</strong></li>
+ <li>Browse and select the downloaded zip file.</li>
+ <li>Follow the remaining procedures, above, starting from steps 5.</li>
+</ol>
+<p>To update your plugin once you've installed using the zip file, you will have to
+follow these steps again instead of the default update instructions.</p>
+
+<h4>Other install errors</h4>
+
+<p>Note that there are features of ADT that require some optional
+Eclipse components (for example, WST). If you encounter an error when
+installing ADT, your Eclipse installion might not include these components.
+For information about how to quickly add the necessary components to your
+Eclipse installation, see the troubleshooting topic
+<a href="{@docRoot}guide/appendix/faq/troubleshooting.html#installeclipsecomponents">ADT
+Installation Error: "requires plug-in org.eclipse.wst.sse.ui"</a>.</p>
+
+<h4>For Linux users</h4>
+<p>If you encounter this error when installing the ADT Plugin for Eclipse:
+<pre>
+An error occurred during provisioning.
+Cannot connect to keystore.
+JKS</pre>
+<p>
+...then your development machine lacks a suitable Java VM. Installing Sun
+Java 6 will resolve this issue and you can then reinstall the ADT
+Plugin.</p>
+
+
+<h2 id="next">Next Steps</h2>
+<p>Once you have completed installation, you are ready to
+begin developing applications. Here are a few ways you can get started: </p>
+
+<p><strong>Learn about Android</strong></p>
+<ul>
+ <li>Take a look at the <a href="{@docRoot}guide/index.html">Dev
+ Guide</a> and the types of information it provides</li>
+ <li>Read an introduction to Android as a platform in <a
+ href="{@docRoot}guide/basics/what-is-android.html">What is
+ Android?</a></li>
+ <li>Learn about the Android framework and how applications run on it in
+ <a href="{@docRoot}guide/topics/fundamentals.html">Application
+ Fundamentals</a></li>
+ <li>Take a look at the Android framework API specification in the <a
+ href="{@docRoot}reference/packages.html">Reference</a> tab</li>
+</ul>
+
+<p><strong>Explore the SDK</strong></p>
+<ul>
+ <li>Get an overview of the <a
+ href="{@docRoot}guide/developing/tools/index.html">development
+ tools</a> that are available to you</li>
+ <li>Read how to develop <a
+ href="{@docRoot}guide/developing/eclipse-adt.html">in Eclipse/ADT</a> or
+ <a href="{@docRoot}guide/developing/other-ide.html">in other IDEs</a>
+ </li>
+</ul>
+
+<p><strong>Explore some code</strong></p>
+<ul>
+ <li>Set up a <a href="{@docRoot}guide/tutorials/hello-world.html">Hello
+ World application</a> (highly recommended, especially for Eclipse users)</li>
+ <li>Follow the <a href="{@docRoot}guide/tutorials/notepad/index.html">
+ Notepad Tutorial</a> to build a full Android application </li>
+ <li>Create a new project for one of the other sample applications
+ included in <code><em>&lt;sdk&gt;</em>/platforms/<em>&lt;platfrom&gt;</em>/samples</code>,
+ then compile and run it in your development environment</li>
+</ul>
+
+<p><strong>Visit the Android developer groups</strong></p>
+<ul>
+ <li>Take a look at the <a
+ href="{@docRoot}community/index.html">Community</a> tab to see a list of
+ Android developers groups. In particular, you might want to look at the
+ <a href="http://groups.google.com/group/android-developers">Android
+ Developers</a> group to get a sense for what the Android developer
+ community is like.</li>
+</ul>
+
+
+<h2 id="installnotes">Installation Notes</h2>
+
+<h3>Ubuntu Linux Notes</h3>
+
+<ul>
+ <li>If you need help installing and configuring Java on your
+ development machine, you might find these resources helpful:
+ <ul>
+ <li><a href="https://help.ubuntu.com/community/Java">https://help.ubuntu.com/community/Java </a></li>
+ <li><a href="https://help.ubuntu.com/community/Java">https://help.ubuntu.com/community/JavaInstallation</a></li>
+ </ul>
+ </li>
+ <li>Here are the steps to install Java and Eclipse, prior to installing
+ the Android SDK and ADT Plugin.
+ <ol>
+ <li>If you are running a 64-bit distribution on your development
+ machine, you need to install the <code>ia32-libs</code> package using
+ <code>apt-get:</code>:
+ <pre>apt-get install ia32-libs</pre>
+ </li>
+ <li>Next, install Java: <pre>apt-get install sun-java6-bin</pre></li>
+ <li>The Ubuntu package manager does not currently offer an Eclipse 3.3
+ version for download, so we recommend that you download Eclipse from
+ eclipse.org (<a
+ href="http://www.eclipse.org/downloads/">http://www.eclipse.org/
+ downloads/</a>). A Java or RCP version of Eclipse is recommended.</li>
+ <li>Follow the steps given in previous sections to install the SDK
+ and the ADT plugin. </li>
+ </ol>
+ </li>
+</ul>
+
+<h3>Other Linux Notes</h3>
+
+<ul>
+ <li>If JDK is already installed on your development computer, please
+ take a moment to make sure that it meets the version requirements listed
+ in the <a href="{@docRoot}sdk/1.1_r1/requirements.html">System Requirements</a>.
+ In particular, note that some Linux distributions may include JDK 1.4 or Gnu
+ Compiler for Java, both of which are not supported for Android development.</li>
+</ul>
+
+
+
diff --git a/docs/html/sdk/1.5_r2/requirements.jd b/docs/html/sdk/1.5_r2/requirements.jd
new file mode 100644
index 0000000..4ed38a7
--- /dev/null
+++ b/docs/html/sdk/1.5_r2/requirements.jd
@@ -0,0 +1,39 @@
+page.title=System Requirements
+@jd:body
+
+<p>The sections below describe the system and software requirements for developing Android applications using the Android SDK tools included in Android <?cs var:sdk.version ?> SDK, Release <?cs var:sdk.rel.id ?>. </p>
+
+<h3>Supported Operating Systems</h3>
+<ul>
+ <li>Windows XP (32-bit) or Vista (32- or 64-bit)</li>
+ <li>Mac OS X 10.4.8 or later (x86 only)</li>
+ <li>Linux (tested on Linux Ubuntu Dapper Drake)</li>
+</ul>
+
+<h3>Supported Development Environments</h3>
+<ul>
+ <li>Eclipse IDE
+ <ul>
+ <li><a href="http://www.eclipse.org/downloads/">Eclipse</a> 3.3 (Europa), 3.4 (Ganymede)
+ <ul>
+ <li>Recommended Eclipse IDE packages: Eclipse IDE for Java EE Developers, Eclipse IDE for Java Developers, Eclipse for RCP/Plug-in Developers</li>
+ <li>Eclipse <a href="http://www.eclipse.org/jdt">JDT</a> plugin (included in most Eclipse IDE packages) </li>
+ <li>Eclipse Classic IDE package is not supported.</li>
+ </ul>
+ </li>
+ <li><a href="http://java.sun.com/javase/downloads/index.jsp">JDK 5 or JDK 6</a> (JRE alone is not sufficient)</li>
+ <li><a href="installing.html#installingplugin">Android Development Tools plugin</a> (optional)</li>
+ <li><strong>Not</strong> compatible with Gnu Compiler for Java (gcj)</li>
+ </ul>
+ </li>
+ <li>Other development environments or IDEs
+ <ul>
+ <li><a href="http://java.sun.com/javase/downloads/index.jsp">JDK 5 or JDK 6</a> (JRE alone is not sufficient)</li>
+ <li><a href="http://ant.apache.org/">Apache Ant</a> 1.6.5 or later for Linux and Mac, 1.7 or later for Windows</li>
+ <li><strong>Not</strong> compatible with Gnu Compiler for Java (gcj)</li>
+ </ul>
+ </li>
+</ul>
+
+<p class="note"><strong>Note:</strong> If JDK is already installed on your development computer, please take a moment to make sure that it meets the version requirements listed above. In
+particular, note that some Linux distributions may include JDK 1.4 or Gnu Compiler for Java, both of which are not supported for Android development. </p> \ No newline at end of file
diff --git a/docs/html/sdk/1.5_r2/upgrading.jd b/docs/html/sdk/1.5_r2/upgrading.jd
new file mode 100644
index 0000000..bb5fc60
--- /dev/null
+++ b/docs/html/sdk/1.5_r2/upgrading.jd
@@ -0,0 +1,395 @@
+page.title=Upgrading the SDK
+sdk.version=1.5_r2
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>Upgrading the SDK</h2>
+ <ul>
+ <li>The Android 1.5 SDK uses a new project structure and a new ADT plugin (ADT 0.9). </li>
+ <li>To move existing projects into the SDK, you must make some minor changes in your
+ development environment.</li>
+ <li>The new ADT plugin (ADT 0.9) <em>is not compatible</em> with projects created in previous SDKs.</li>
+ <li>You need to uninstall your existing ADT plugin, before installing ADT 0.9.</li>
+ </ul>
+
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#Install">Install the SDK</a></li>
+ <li><a href="#UpdateAdt">Update Your Eclipse ADT Plugin</a></li>
+ <li><a href="#UpdateYourProjects">Update Your Projects</a>
+ <ol>
+ <li><a href="#EclipseUsers">Eclipse Users</a></li>
+ <li><a href="#AntUsers">Ant Users</a></li>
+ </ol>
+ </li>
+ <li><a href="#MigrateYourApplications">Migrate Your Applications</a>
+ <ol><li><a href="#FutureProofYourApps">Future-proof your apps</a></li></ol>
+ </li>
+ </ol>
+
+ <h2>Migrating references</h2>
+ <ol>
+ <li><a href="{@docRoot}sdk/api_diff/3/changes.html">Android 1.5 API Differences</a></li>
+ <li><a
+href="http://android-developers.blogspot.com/2009/04/future-proofing-your-apps.html">Future-Proofing
+Your Apps &raquo;</a></li>
+ <li><a
+href="http://android-developers.blogspot.com/2009/04/ui-framework-changes-in-android-15.html">UI
+framework changes in Android 1.5 &raquo;</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>This document describes how to move your development environment and existing
+Android applications from an Android 1.0 or 1.1 SDK to the Android 1.5 SDK.
+If you are migrating applications from an SDK older than 1.0, please also read the upgrading
+document available in the Android 1.0 SDK package.</p>
+
+<p>There are several compelling reasons to upgrade, such as new SDK tools
+that make developing more efficient and new APIs that allow you to expand the feature-set
+of your applications. However, even if you or your applications don't require these enhancements,
+it's important that you upgrade to ensure that your applications run properly on the
+Android 1.5 platform.</p>
+
+<p>The Android 1.5 platform will soon be deployable to devices around the world.
+If you have already released Android applications to the public, you should
+test the forward-compatibility of your applications on the latest version of the platform
+as soon as possible. It's unlikely that you'll encounter breakage in your applications, but
+in the interest of maintaining the best user experience, you should take no risks.
+So, please install the new Android SDK and test your applications on Android 1.5.</p>
+
+<p>For more information on new SDK features and system changes,
+see the <a href="{@docRoot}sdk/android-1.5.html">Android 1.5 Version Notes</a>.</p>
+
+
+<h2 id="Install">Install the SDK</h2>
+
+<p>If you haven't yet downloaded the SDK, <a href="{@docRoot}sdk/1.5_r2/index.html">download from here</a>
+and unpack it into a safe location.</p>
+
+<p><strong>Before you begin:</strong>
+If you had previously setup your PATH variable to point to the SDK tools directory,
+then you need to update it to point to the new SDK. For example, for a
+<code>.bashrc</code> or <code>.bash_profile</code> file:</p>
+<pre>export PATH=$PATH:<em>&lt;your_sdk_dir></em>/tools</pre>
+
+<p>If you don't use Eclipse for development,
+skip to <a href="#updateYourProjects">Update Your Projects</a>.</p>
+
+
+<h2 id="UpdateAdt">Update Your Eclipse ADT Plugin</h2>
+
+<p><em>If you installed ADT-0.9_pre with the early look 1.5 SDK, there have been
+additional changes, so please continue with this guide and update to the final ADT 0.9.</em></p>
+
+<p>A new ADT plugin (version 0.9) is required for the Android 1.5 SDK.
+Because the component structure has been changed since Android 1.1,
+the Android 1.5 SDK does not work with ADT 0.8 (or older) and previously installed SDKs will not
+work with ADT 0.9. However, the Android 1.5 SDK includes an Android 1.1 SDK image that you
+can build against while using ADT 0.9. </p>
+
+<p class="note">For information about using different system images (such as Android 1.1)
+while running this SDK, see Developing <a href="{@docRoot}guide/developing/eclipse-adt.html">
+In Eclipse, with ADT</a> or <a href="{@docRoot}guide/developing/other-ide.html">In
+Other IDEs</a>, as appropriate for your development environment.</p>
+
+<p>In order to upgrade your Eclipse IDE to use the new 0.9 ADT, follow the steps below
+for your respective version of Eclipse.</p>
+
+<h3 id="uninstallAdt">Uninstall your previous ADT plugin</h3>
+
+<p>You must uninstall your existing ADT plugin (0.8 or older). If you do not uninstall it,
+you will get a conflict with the Android Editors when installing the new ADT.
+(If you have already installed ADT-0.9_pre with the early look 1.5 SDK, you can skip this
+uninstall procedure and continue to <a href="#installAdt">Install the 0.9 ADT plugin</a>).</p>
+
+<table style="font-size:100%">
+<tr><th>Eclipse 3.3 (Europa)</th><th>Eclipse 3.4 (Ganymede)</th></tr>
+<tr>
+<td width="50%">
+<!-- 3.3 steps -->
+<ol>
+ <li>Select <strong>Help</strong> &gt; <strong>Software Updates</strong> &gt;
+ <strong>Manage Configuration</strong>. </li>
+ <li>Expand the list in the left panel to reveal the installed tools.</li>
+ <li>Right-click "Android Editors" and click <strong>Uninstall</strong>. Click <strong>OK</strong>
+ to confirm.</li>
+ <li>Restart Eclipse.
+ <p>(Do not uninstall "Android Development Tools".)</p></li>
+</ol>
+</td>
+<td>
+<!-- 3.4 steps -->
+<ol>
+ <li>Select <strong>Help</strong> &gt; <strong>Software Updates</strong>.</li>
+ <li>Select the <strong>Installed Software</strong> tab.</li>
+ <li>Select "Android Editors". Click <strong>Uninstall</strong>.</li>
+ <li>In the next window, be sure "Android Editors" is checked, then click <strong>Finish</strong>
+ to uninstall.</li>
+ <li>Restart Eclipse.
+ <p>(Do not uninstall "Android Development Tools".)</p></li>
+</ol>
+</td>
+</tr>
+</table>
+
+
+<h3 id="installAdt">Install the 0.9 ADT plugin</h3>
+
+<p>Only install the new plugin once you've completed the procedure to
+<a href="#uninstallAdt">Uninstall your previous ADT plugin</a>.</p>
+
+<table style="font-size:100%">
+<tr><th>Eclipse 3.3 (Europa)</th><th>Eclipse 3.4 (Ganymede)</th></tr>
+<tr>
+<td width="50%">
+<!-- 3.3 steps -->
+<ol>
+ <li>Select <strong>Help</strong> &gt; <strong>Software Updates</strong> &gt;
+ <strong>Find and Install</strong>. </li>
+ <li>Select <strong>Search for new features to install</strong>.</li>
+ <li>Select the Android plugin entry by checking the box next to it,
+ then click <strong>Finish</strong>.
+ <p>(Your original entry for the plugin should still be here. If not, see the guide
+ to <a href="{@docRoot}sdk/1.5_r2/installing.html#installingplugin">Installing the ADT Plugin</a>.)
+ </p></li>
+ <li>In the results, expand the entry for the Android plugin and
+ be sure that "Developer Tools" is checked, then click <strong>Next</strong>.
+ (This will install "Android DDMS" and "Android Development Tools".)</li>
+ <li>Read and accept the license agreement, then click <strong>Next</strong>.
+ <li>In the next window, click <strong>Finish</strong> to start installation.</li>
+ <li>The ADT plugin is not digitally signed. Accept the installation anyway by clicking
+ <strong>Install All</strong>.</li>
+ <li>Restart Eclipse.</li>
+</ol>
+</td>
+<td>
+<!-- 3.4 steps -->
+<ol>
+ <li>Select <strong>Help</strong> &gt; <strong>Software Updates</strong>.</li>
+ <li>Select the <strong>Available Software</strong> tab.</li>
+ <li>Expand the entry for the Andriod plugin (may be listed as the location URL)
+ and select "Developer Tools" by checking the box next to it, then click
+ <strong>Install</strong>.</li>
+ <li>On the next window, "Android DDMS" and "Android Development Tools"
+ should both be checked. Click <strong>Finish</strong>.</li>
+ <li>Restart Eclipse.</li>
+</ol>
+</td>
+</tr>
+</table>
+
+<p>If you encounter problems, ensure your ADT is fully uninstalled and then
+follow the guide to
+<a href="{@docRoot}sdk/1.5_r2/installing.html#installingplugin">Installing the ADT Plugin
+for Eclipse</a>.</p>
+
+<h3 id="updateEclipsePrefs">Update your Eclipse SDK Preferences</h3>
+
+<p>The last step is to update your Eclipse preferences to point to the new SDK directory:</p>
+ <ol>
+ <li>Select <strong>Window</strong> > <strong>Preferences</strong> to open the Preferences
+ panel (Mac: <strong>Eclipse</strong> > <strong>Preferences</strong>).</li>
+ <li>Select <strong>Android</strong> from the left panel.</li>
+ <li>For the <em>SDK Location</em> in the main panel, click <strong>Browse</strong>
+ and locate your SDK directory.</li>
+ <li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li>
+ </ol>
+
+
+<h2 id="UpdateYourProjects">Update Your Projects</h2>
+
+<p>You will now need to update any and all Android projects that you have
+developed using a previous version of the Android SDK.</p>
+
+
+<h3 id="EclipseUsers">Eclipse users</h3>
+
+<p>If you use Eclipse to develop applications, use the following procedure to
+update each project:</p>
+
+<ol>
+ <li>Right-click on the individual project (in the Package Explorer)
+ and select <strong>Properties</strong>.</li>
+ <li>In the properties, open the Android panel and select a "build target" to compile
+ against. This SDK offers the Android 1.1 and Android 1.5 platforms to choose from. When
+ you are initially updating your projects to the new SDK, we recommend that you select a build
+ target with the Android 1.1 platform. Click <strong>Apply</strong>, then
+ <strong>OK</strong>.</li>
+</ol>
+
+<p>The new plugin creates a <code>gen/</code> folder in your project, in which it puts the
+<code>R.java</code> file
+and all automatically generated AIDL java files. If you get an error such as
+<code>The type R is already defined</code>,
+then you probably need to delete your old <code>R.java</code> or your old auto-generated
+AIDL Java files in the <code>src/</code> folder.
+(This <em>does not</em> apply to your own hand-crafted parcelable AIDL java files.)</p>
+
+<p>Note that, with the Android 1.5 SDK, there is a new process for running
+applications in the Android Emulator.
+Specifically, you must create an Android Virtual Device (AVD) before you can launch an instance
+of the Emulator. Before attempting to run your applications with the new SDK,
+please continue with the section below to
+<a href="#MigrateYourApplications">Migrate Your Applications</a>.</p>
+
+
+<h3 id="AntUsers">Ant users</h3>
+
+<p>If you build your projects using the Ant tool (rather than with Eclipse), note the
+following changes with the new SDK tools.</p>
+
+<h4>build.xml has changed</h4>
+
+<p>You must re-create your <code>build.xml</code> file.</p>
+
+<p>If you had customized your <code>build.xml</code>, first make a copy of it:</p>
+
+<pre>
+$ cd <em>my-project</em>
+$ cp build.xml build.xml.old
+</pre>
+
+<p>Now use the new <code>android</code> tool (located in <code><em>your_sdk</em>/tools/</code>)
+to create a new <code>build.xml</code> that references
+a specific platform target:</p>
+
+<pre>$ android update project --path /path/to/my-project --target 1</pre>
+
+<p>The "target" corresponds to an Android platform library (including any add-ons, such as
+Google APIs) that you would like to build your project against. You can view a list of available
+targets (and their corresponding integer ID) with the command, <code>android list targets</code>.
+When you are initially updating your projects to the new SDK, we recommend that you select the
+first target ("1"), which uses the Android 1.1 platform library.</p>
+
+<p>A <code>gen/</code> folder will be created the first time you build and your <code>R.java</code> and
+your AIDL Java files will be generated in here. You <strong>must</strong> remove
+the old <code>R.java</code> and old auto-generated AIDL java files from the
+<code>src/</code> folder. (This
+does not apply to your own hand-crafted parcelabe AIDL java files.)</p>
+
+<p class="note"><strong>Note:</strong> The "activitycreator" tool has been replaced
+by the new "android" tool. For information on creating new projects with the android tool,
+see the documentation about <a href="{@docRoot}guide/developing/other-ide.html">Developing
+In Other IDEs</a>.</p>
+
+<p>Note that, with the Android 1.5 SDK, there is a new process for running
+applications in the Android Emulator.
+Specifically, you must create an Android Virtual Device (AVD) before you can launch an instance
+of the Emulator. Before attempting to run your applications with the new SDK,
+please continue with the section below to
+<a href="#MigrateYourApplications">Migrate Your Applications</a>.</p>
+
+
+<h2 id="MigrateYourApplications">Migrate Your Applications</h2>
+
+<p>After you have completed the process above to <a href="#UpdateYourProjects">Update Your
+Projects</a>, you are strongly encouraged to run each of your applications in an instance
+of the emulator running the Android 1.5 system image. It's possible (however, unlikely)
+that you'll encounter some breakage in your application when you run your applications on
+the Android 1.5 system image. Whether you believe your application will be affected by
+platform changes or not, it's very important that you test the application's
+forward-compatibility on Android 1.5.</p>
+
+<p>To test forward-compatibility, simply run your existing application (as-is) on an Android
+Emulator that's running the Android 1.5 system image. The following procedure will guide
+you through the process to running your existing applications on an emulator. <em>Please read
+the following guide completely before you begin</em>.</p>
+
+<p>To test your application on an emulator running Android 1.5:</p>
+<ol>
+ <li><a href="#UpdateYourProjects">Update Your Project</a> (you should have done this
+ already, in the section above).</li>
+ <li>Run your existing project, as-is, on an emulator running the Android 1.5 system image.
+ <p>As mentioned in the guide to <a href="#UpdateYourProjects">Update Your Projects</a>,
+ you should have selected a "build
+ target" of "1", which compiles your application against the Android 1.1 system image, so there
+ should be no new errors in your code.</p>
+ <p>Eclipse users: follow the
+ <a href="{@docRoot}guide/developing/eclipse-adt.html#Running">Eclipse guide to
+ Running Your Application</a>.</p>
+ <p>Ant users: follow the
+ <a href="{@docRoot}guide/developing/other-ide.html#Running">Ant guide to
+ Running Your Application</a>
+ <p>During the procedure to Running Your Application, select a "deployment target"
+ for the AVD that includes the Android 1.5 platform.
+ If your application utilizes the Google Maps APIs (i.e.,
+ MapView), be certain to select a target that includes the Google APIs.</p>
+ <p>Once you complete the procedures to run your application in your respective environment,
+ linked above, return here.</p>
+ </li>
+ <li>With your application running in the emulator, perform all regular testing on the application
+ to ensure that it functions normally (in both landscape and portrait orientations).</li>
+</ol>
+
+<p>Chances are, your application runs just fine on the Android 1.5 platform &mdash;
+new devices will be able to safely install and run your application and
+current users who update their devices will be able to continue using your application as usual.
+However, if something doesn't work the way you expect, then you might need to revisit
+your project and make any necessary changes to your code.</p>
+
+<p>You can check for code breakages caused by API changes by opening your project
+in Eclipse, changing the "build target" to one using the Android 1.5 platform,
+and see where the ADT identifies errors in your code.</p>
+
+
+<h3 id="FutureProofYourApps">Future-proof your apps</h3>
+
+<p>There have been several API additions made for this release, but there have been
+very few actual API <em>changes</em>. Only a couple (relatively unused) elements
+have been removed and a few have been deprecated, so your applications written with the
+Android 1.1 system library should work just fine. However,
+your application is more likely to encounter problems on Android 1.5
+if it performs any of the following:</p>
+
+<ul>
+ <li>Uses internal APIs. That is, APIs that are not officially supported
+ and not available in the reference documentation. Any un-official APIs are always subject
+ to change (which is why they're un-official) and some have indeed changed.
+ </li>
+ <li>Directly manipulates system settings. There are some settings (such as
+ GPS, data roaming, bluetooth and others) that used to be writable by
+ applications but have been changed so that they can only be explicitly modified by the user
+ through the system settings. Refer to {@link android.provider.Settings.Secure}
+ to see which settings are now secured and cannot be directly changed by your application.
+ </li>
+ <li>Uses View hierarchies that are unreasonably deep (more than 10 or so levels) or
+ broad (more than 30 total). View hierarchies this big have always been troublesome, but
+ Android 1.5 is much more efficient at exposing this and your application may crash.
+ </li>
+ <li>Makes assumptions about the available hardware. With new support for soft keyboards,
+ not all devices will have full QWERTY keyboards on the hardware. So if your application
+ listens for special keypress events that only occur on a keypad, then your application
+ should degrade gracefully when there is no keyboard available.
+ </li>
+ <li>Performs its own layout orientation changes based on the acceletometer (or via other
+ sensors). Some devices running Android 1.5 will automatically rotate the orientation
+ (and all devices have the option to turn on auto-rotation), so if your application also
+ attempts to rotate the orientation, it can result in strange behavior. In addition, if your
+ application uses the accelerometer to detect shaking and you do not want to rotate the
+ orientation, then you should lock the current orientation with
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html#screen">android:screenOrientation</a>.
+ </li>
+</ul>
+
+<p>Please read our blog post on <a
+href="http://android-developers.blogspot.com/2009/04/future-proofing-your-apps.html">Future-Proofing
+Your Apps</a> for more information on the issues mentioned above.</p>
+
+<p>For information
+about other changes made to Android 1.5, refer to the following documents:</p>
+<ul>
+ <li><a href="{@docRoot}sdk/api_diff/3/changes.html">Android 1.5 API Differences</a></li>
+ <li><a href="{@docRoot}sdk/android-1.5.html#api-changes">Android 1.5 Version Notes</a></li>
+ <li><a
+href="http://android-developers.blogspot.com/2009/04/ui-framework-changes-in-android-15.html">UI
+framework changes in Android 1.5 &raquo;</a></li>
+</ul>
+
+<p>If you have additional trouble updating your code, visit the
+<a href="http://groups.google.com/group/android-developers">Android Developers Group</a>
+to seek help from other Android developers.</p>
diff --git a/docs/html/sdk/RELEASENOTES.jd b/docs/html/sdk/RELEASENOTES.jd
index c44cef3..f3a1951 100644
--- a/docs/html/sdk/RELEASENOTES.jd
+++ b/docs/html/sdk/RELEASENOTES.jd
@@ -3,8 +3,16 @@ page.title=SDK Release Notes
<p>This document provides version-specific information about Android SDK
releases. For the latest known issues, please ensure that you're viewing this
-page at:
-<a href="http://developer.android.com/sdk/RELEASENOTES.html">http://developer.android.com/sdk/RELEASENOTES.html</a>.</p>
+page at <a href="http://developer.android.com/sdk/RELEASENOTES.html">http://developer.android.com/sdk/RELEASENOTES.html</a>.</p>
+
+
+<h2 id="1.5_r2">Android 1.5 SDK, Release 2</h2>
+
+<p>This SDK release provides the same developer tools as the Android 1.5 SDK,
+Release 1, but provides an updated Android 1.5 system image that includes a
+security patch for the issue described in the oCert advisory below:</p>
+
+<p style="margin-left:2em;"><a href="http://www.ocert.org/advisories/ocert-2009-006.html">http://www.ocert.org/advisories/ocert-2009-006.html</a></p>
<h2 id="1.5_r1">Android 1.5 SDK, Release 1</h2>
diff --git a/docs/html/sdk/android-1.5-highlights.jd b/docs/html/sdk/android-1.5-highlights.jd
index e6c4f88..ff64e8c 100644
--- a/docs/html/sdk/android-1.5-highlights.jd
+++ b/docs/html/sdk/android-1.5-highlights.jd
@@ -1,5 +1,4 @@
page.title=Android 1.5 Platform Highlights
-sdk.version=1.5_r1
@jd:body
<p>
diff --git a/docs/html/sdk/older_releases.jd b/docs/html/sdk/older_releases.jd
index ff57a36..3c2bbd4 100644
--- a/docs/html/sdk/older_releases.jd
+++ b/docs/html/sdk/older_releases.jd
@@ -1,37 +1,67 @@
-page.title=Older Releases
+page.title=Other SDK Releases
@jd:body
-<div class="special">
- <strong>NOTICE:</strong>
- <p>The SDKs listed on this page are "early-look" versions that were released in
+<p>This page provides a full list of older, obsolete SDK releases, including
+non-current versions of active releases and "early look" versions that were
+released before Android 1.0. The list is provided for informational purposes
+only.</p>
+
+<p>If you are just getting started developing on Android, make sure that you
+are using the <a href="{@docRoot}sdk/{@sdkCurrent}/index.html">most current SDK available</a>,
+to ensure that your applications will be compatible with the latest
+Android-powered devices.</p>
+
+<h2>Obsolete Releases</h2>
+
+<p>The table below lists Android SDK releases that have been superceded by an
+active release and that are now obsolete. If you are using one of these
+releases, please upgrade to the <a href="{@docRoot}sdk/index.html">current SDK
+release</a>.</p>
+
+ <table>
+ <tr>
+ <th>Release</td>
+ <th>Platform(s)</th>
+ <th>Date</td>
+ <th>Description</td>
+ </tr>
+ <tr>
+ <td><a href="{@docRoot}sdk/1.5_r1/index.html">Android 1.5 SDK, Release 1</a></td>
+ <td style="text-align:center;">Android 1.5<br>Android 1.1</td>
+ <td><em>April 2009</em></td>
+ <td>Replaced by Android 1.5 SDK, Release 2. <em><a href="RELEASENOTES.html#1.5_r1">Release notes</a></em></td>
+ </tr>
+ <tr class="alt">
+ <td><a href="{@docRoot}sdk/1.0_r1/index.html">Android 1.0 SDK, Release 1</a></td>
+ <td style="text-align:center;">Android 1.0</td>
+ <td><em>September 2008</em></td>
+ <td>Replaced by Android 1.0 SDK, Release 2. <em><a href="RELEASENOTES.html#1.0_r1">Release notes</a></em></td>
+ </tr>
+ </table>
+
+ <h2>Non-Compatible Releases</h2>
+
+<!-- <div class="special"> -->
+<p>The SDKs listed below are "early-look" versions that were released in
the year preceding the full release of Android 1.0 in September 2008. Because
these early-look SDKs were released before the Android 1.0 API specification was
finalized, they do not provide a compliant Android execution environment.
Consequently, applications that you develop in these SDKs will not be able to
run on any Android-powered devices.</p>
- <p>If you have an older application that you built in one of the early-look SDKs,
- you must migrate it to the Android
- 1.0 SDK (or later release) before you will be able to deploy it to
- an Android-powered device. To help with this migration, each SDK package below
- provides information about API changes from the previous version. You can find
- the migration information in the documentation included in each SDK package.</p>
-
- <p>If you are just getting started developing on Android, do not use one of these early-look
- SDKs. Instead, develop using the most <a href="{@docRoot}sdk/index.html">current
- SDK release</a> available, to ensure that your applications will be compatible
- with Android-powered devices.</p>
-</div>
-
+<p>If you have an older application that you built in one of the early-look
+SDKs, you must migrate it to the Android 1.0 SDK (or later release) before you
+will be able to deploy it to an Android-powered device. To help with this
+migration, each SDK package below provides information about API changes from
+the previous version. You can find the migration information in the
+documentation included in each SDK package.</p>
+<!-- </div> -->
-
-
- <h2>Android 0.9 SDK beta</h2>
- <p><em>August 18, 2008 - <a href="OLD_RELEASENOTES.html#0.9_beta">Release Notes</a></em></p>
+<h4>Android SDK m5-rc15</h4>
+<p><em>August 18, 2008 - <a href="OLD_RELEASENOTES.html#0.9_beta">Release Notes</a></em></p>
<table>
<tr>
- <th>Platform</th>
- <th>Package</th>
+ <th colspan="2">Package</th>
<th>Size</th>
<th>MD5 Checksum</th>
</tr>
@@ -58,15 +88,11 @@ page.title=Older Releases
</tr>
</table>
-
-
-
-<h2>Version m5-rc15</h2>
+<h4>Version m5-rc15</h4>
<p><em>March 3, 2008 - <a href="OLD_RELEASENOTES.html#m5-rc15">Release Notes</a></em></p>
<table>
<tr>
- <th>Platform</th>
- <th>Package</th>
+ <th colspan="2">Package</th>
<th>Size</th>
<th>MD5 Checksum</th>
</tr>
@@ -93,15 +119,11 @@ page.title=Older Releases
</tr>
</table>
-
-
-
- <h2>Version m5-rc14</h2>
+ <h4>Version m5-rc14</h4>
<p><em>February 12, 2008 - <a href="OLD_RELEASENOTES.html#m5-rc14">Release Notes</a></em></p>
<table>
<tr>
- <th>Platform</th>
- <th>Package</th>
+ <th colspan="2">Package</th>
<th>Size</th>
<th>MD5 Checksum</th>
</tr>
@@ -131,12 +153,11 @@ page.title=Older Releases
- <h2>Version m3-rc37a</h2>
+ <h4>Version m3-rc37a</h4>
<p><em>December 14, 2007 - <a href="OLD_RELEASENOTES.html#m3-rc37a">Release Notes</a></em></p>
<table>
<tr>
- <th>Platform</th>
- <th>Package</th>
+ <th colspan="2">Package</th>
<th>Size</th>
<th>MD5 Checksum</th>
</tr>
@@ -166,12 +187,11 @@ page.title=Older Releases
- <h2>Version m3-rc22a</h2>
+ <h4>Version m3-rc22a</h4>
<p><em>November 16, 2007 - <a href="OLD_RELEASENOTES.html#m3-rc22a">Release Notes</a></em></p>
<table>
<tr>
- <th>Platform</th>
- <th>Package</th>
+ <th colspan="2">Package</th>
<th>Size</th>
<th>MD5 Checksum</th>
</tr>
@@ -201,12 +221,11 @@ page.title=Older Releases
- <h2>Version m3-rc20a</h2>
+ <h4>Version m3-rc20a</h4>
<p><em>November 12, 2007 - <a href="OLD_RELEASENOTES.html#m3-rc20a">Release Notes</a></em></p>
<table>
<tr>
- <th>Platform</th>
- <th>Package</th>
+ <th colspan="2">Package</th>
<th>Size</th>
<th>MD5 Checksum</th>
</tr>
diff --git a/docs/html/sdk/preview/features.html b/docs/html/sdk/preview/features.html
index 392c089..a2f085c 100644
--- a/docs/html/sdk/preview/features.html
+++ b/docs/html/sdk/preview/features.html
@@ -133,10 +133,10 @@
<li>
<h2>Current SDK Release</h2>
<ul>
- <li><a href="/sdk/1.5_r1/index.html">Download</a></li>
- <li><a href="/sdk/1.5_r1/installing.html">Installing</a></li>
- <li><a href="/sdk/1.5_r1/upgrading.html">Upgrading</a></li>
- <li><a href="/sdk/1.5_r1/requirements.html">System Requirements</a></li>
+ <li><a href="/sdk/1.5_r2/index.html">Download</a></li>
+ <li><a href="/sdk/1.5_r2/installing.html">Installing</a></li>
+ <li><a href="/sdk/1.5_r2/upgrading.html">Upgrading</a></li>
+ <li><a href="/sdk/1.5_r2/requirements.html">System Requirements</a></li>
</ul>
<ul>
<li><a href="/sdk/terms.html">SDK Terms and Conditions</a></li>
@@ -154,8 +154,7 @@
<ul>
<li><a href="/sdk/1.1_r1/index.html">Android 1.1 SDK, r1</a></li>
<li><a href="/sdk/1.0_r2/index.html">Android 1.0 SDK, r2</a></li>
- <li><a href="/sdk/1.0_r1/index.html">Android 1.0 SDK, r1</a></li>
- <li><a href="/sdk/older_releases.html">Older Releases</a></li>
+ <li><a href="/sdk/older_releases.html">Other Releases</a></li>
</ul>
</li>
</ul>
@@ -185,16 +184,6 @@
</div> <!-- end body-content -->
-<script type="text/javascript">
-init(); /* initialize android-developer-docs.js */
-var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
-document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
-</script>
-<script type="text/javascript">
-var pageTracker = _gat._getTracker("UA-5831155-1");
-pageTracker._trackPageview();
-</script>
-
</body>
</html>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 4b55b56..2079dd8 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -27,18 +27,11 @@
</ul>
</li>
<li>
- <h2>Native Development Tools</h2>
- <ul>
- <li><a href="<?cs var:toroot ?>sdk/ndk/1.5-r1/index.html">Android 1.5 NDK, r1</a></li>
- </ul>
- </li>
- <li>
<h2>Previous SDK Releases</h2>
<ul>
<li><a href="<?cs var:toroot ?>sdk/1.1_r1/index.html">Android 1.1 SDK, r1</a></li>
<li><a href="<?cs var:toroot ?>sdk/1.0_r2/index.html">Android 1.0 SDK, r2</a></li>
- <li><a href="<?cs var:toroot ?>sdk/1.0_r1/index.html">Android 1.0 SDK, r1</a></li>
- <li><a href="<?cs var:toroot ?>sdk/older_releases.html">Older Releases</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/older_releases.html">Other Releases</a></li>
</ul>
</li><?cs
/if ?>
diff --git a/include/tts/TtsEngine.h b/include/tts/TtsEngine.h
new file mode 100644
index 0000000..06f3820
--- /dev/null
+++ b/include/tts/TtsEngine.h
@@ -0,0 +1,167 @@
+/*
+ * Copyright (C) 2009 Google Inc.
+ *
+ * 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.
+ */
+#include <media/AudioSystem.h>
+
+// This header defines the interface used by the Android platform
+// to access Text-To-Speech functionality in shared libraries that implement speech
+// synthesis and the management of resources associated with the synthesis.
+// An example of the implementation of this interface can be found in
+// FIXME: add path+name to implementation of default TTS engine
+// Libraries implementing this interface are used in:
+// frameworks/base/tts/jni/android_tts_SpeechSynthesis.cpp
+
+namespace android {
+
+// The callback is used by the implementation of this interface to notify its
+// client, the Android TTS service, that the last requested synthesis has been
+// completed.
+// The callback for synthesis completed takes:
+// void * - The userdata pointer set in the original synth call
+// uint32_t - Track sampling rate in Hz
+// audio_format - The AudioSystem::audio_format enum
+// int - The number of channels
+// int8_t * - A buffer of audio data only valid during the execution of the callback
+// size_t - The size of the buffer
+// Note about memory management:
+// The implementation of TtsEngine is responsible for the management of the memory
+// it allocates to store the synthesized speech. After the execution of the callback
+// to hand the synthesized data to the client of TtsEngine, the TTS engine is
+// free to reuse or free the previously allocated memory.
+// This implies that the implementation of the "synthDoneCB" callback cannot use
+// the pointer to the buffer of audio samples outside of the callback itself.
+typedef void (synthDoneCB_t)(void *, uint32_t, AudioSystem::audio_format, int, int8_t *, size_t);
+
+class TtsEngine;
+extern "C" TtsEngine* getTtsEngine();
+
+enum tts_result {
+ TTS_SUCCESS = 0,
+ TTS_FAILURE = -1,
+ TTS_FEATURE_UNSUPPORTED = -2,
+ TTS_VALUE_INVALID = -3,
+ TTS_PROPERTY_UNSUPPORTED = -4,
+ TTS_PROPERTY_SIZE_TOO_SMALL = -5
+};
+
+class TtsEngine
+{
+public:
+ // Initialize the TTS engine and returns whether initialization succeeded.
+ // @param synthDoneCBPtr synthesis callback function pointer
+ // @return TTS_SUCCESS, or TTS_FAILURE
+ virtual tts_result init(synthDoneCB_t synthDoneCBPtr);
+
+ // Shut down the TTS engine and releases all associated resources.
+ // @return TTS_SUCCESS, or TTS_FAILURE
+ virtual tts_result shutdown();
+
+ // Interrupt synthesis and flushes any synthesized data that hasn't been output yet.
+ // This will block until callbacks underway are completed.
+ // @return TTS_SUCCESS, or TTS_FAILURE
+ virtual tts_result stop();
+
+ // Load the resources associated with the specified language. The loaded language will
+ // only be used once a call to setLanguage() with the same language value is issued.
+ // Language values are based on the Android conventions for localization as described in
+ // the Android platform documentation on internationalization. This implies that language
+ // data is specified in the format xx-rYY, where xx is a two letter ISO 639-1 language code
+ // in lowercase and rYY is a two letter ISO 3166-1-alpha-2 language code in uppercase
+ // preceded by a lowercase "r".
+ // @param value pointer to the language value
+ // @param size length of the language value
+ // @return TTS_SUCCESS, or TTS_FAILURE
+ virtual tts_result loadLanguage(const char *value, const size_t size);
+
+ // Signal the engine to use the specified language. This will force the language to be
+ // loaded if it wasn't loaded previously with loadLanguage().
+ // See loadLanguage for the specification of the language.
+ // @param value pointer to the language value
+ // @param size length of the language value
+ // @return TTS_SUCCESS, or TTS_FAILURE
+ virtual tts_result setLanguage(const char *value, const size_t size);
+
+ // Retrieve the currently set language, or an empty "value" if no language has
+ // been set.
+ // @param[out] value pointer to the retrieved language value
+ // @param[inout] iosize in: stores the size available to store the language value in *value
+ // out: stores the size required to hold the language value if
+ // getLanguage() returned TTS_PROPERTY_SIZE_TOO_SMALL,
+ // unchanged otherwise.
+ // @return TTS_SUCCESS, or TTS_PROPERTY_SIZE_TOO_SMALL, or TTS_FAILURE
+ virtual tts_result getLanguage(char *value, size_t *iosize);
+
+ // Set a property for the the TTS engine
+ // "size" is the maximum size of "value" for properties "property"
+ // @param property pointer to the property name
+ // @param value pointer to the property value
+ // @param size maximum size required to store this type of property
+ // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_FAILURE,
+ // or TTS_VALUE_INVALID
+ virtual tts_result setProperty(const char *property, const char *value, const size_t size);
+
+ // Retrieve a property from the TTS engine
+ // @param property pointer to the property name
+ // @param[out] value pointer to the retrieved language value
+ // @param[inout] iosize in: stores the size available to store the property value
+ // out: stores the size required to hold the language value if
+ // getLanguage() returned TTS_PROPERTY_SIZE_TOO_SMALL,
+ // unchanged otherwise.
+ // @return TTS_PROPERTY_UNSUPPORTED, or TTS_SUCCESS, or TTS_PROPERTY_SIZE_TOO_SMALL
+ virtual tts_result getProperty(const char *property, char *value, size_t *iosize);
+
+ // Synthesize the text.
+ // When synthesis completes, the engine invokes the callback to notify the TTS framework.
+ // Note about the format of the input: the text parameter may use the following elements
+ // and their respective attributes as defined in the SSML 1.0 specification:
+ // * lang
+ // * say-as:
+ // o interpret-as
+ // * phoneme
+ // * voice:
+ // o gender,
+ // o age,
+ // o variant,
+ // o name
+ // * emphasis
+ // * break:
+ // o strength,
+ // o time
+ // * prosody:
+ // o pitch,
+ // o contour,
+ // o range,
+ // o rate,
+ // o duration,
+ // o volume
+ // * mark
+ // Differences between this text format and SSML are:
+ // * full SSML documents are not supported
+ // * namespaces are not supported
+ // Text is coded in UTF-8.
+ // @param text the UTF-8 text to synthesize
+ // @param userdata pointer to be returned when the call is invoked
+ // @return TTS_SUCCESS or TTS_FAILURE
+ virtual tts_result synthesizeText(const char *text, void *userdata);
+
+ // Synthesize IPA text. When synthesis completes, the engine must call the given callback to notify the TTS API.
+ // @param ipa the IPA data to synthesize
+ // @param userdata pointer to be returned when the call is invoked
+ // @return TTS_FEATURE_UNSUPPORTED if IPA is not supported, otherwise TTS_SUCCESS or TTS_FAILURE
+ virtual tts_result synthesizeIpa(const char *ipa, void *userdata);
+};
+
+} // namespace android
+
diff --git a/libs/surfaceflinger/Android.mk b/libs/surfaceflinger/Android.mk
index 2212436..9272983 100644
--- a/libs/surfaceflinger/Android.mk
+++ b/libs/surfaceflinger/Android.mk
@@ -6,7 +6,6 @@ LOCAL_SRC_FILES:= \
DisplayHardware/DisplayHardware.cpp \
DisplayHardware/DisplayHardwareBase.cpp \
GPUHardware/GPUHardware.cpp \
- BootAnimation.cpp \
BlurFilter.cpp.arm \
CPUGauge.cpp \
Layer.cpp \
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index 167a59b..0e998bf 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -61,6 +61,13 @@
#include "GPUHardware/GPUHardware.h"
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
#define DISPLAY_COUNT 1
namespace android {
@@ -184,7 +191,6 @@ SurfaceFlinger::SurfaceFlinger()
mDebugCpu(0),
mDebugFps(0),
mDebugBackground(0),
- mDebugNoBootAnimation(0),
mSyncObject(),
mDeplayedTransactionPending(0),
mConsoleSignals(0),
@@ -207,14 +213,11 @@ void SurfaceFlinger::init()
mDebugBackground = atoi(value);
property_get("debug.sf.showfps", value, "0");
mDebugFps = atoi(value);
- property_get("debug.sf.nobootanimation", value, "0");
- mDebugNoBootAnimation = atoi(value);
LOGI_IF(mDebugRegion, "showupdates enabled");
LOGI_IF(mDebugCpu, "showcpu enabled");
LOGI_IF(mDebugBackground, "showbackground enabled");
LOGI_IF(mDebugFps, "showfps enabled");
- LOGI_IF(mDebugNoBootAnimation, "boot animation disabled");
}
SurfaceFlinger::~SurfaceFlinger()
@@ -324,11 +327,8 @@ void SurfaceFlinger::bootFinished()
{
const nsecs_t now = systemTime();
const nsecs_t duration = now - mBootTime;
- LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
- if (mBootAnimation != 0) {
- mBootAnimation->requestExit();
- mBootAnimation.clear();
- }
+ LOGI("Boot is finished (%ld ms)", long(ns2ms(duration)) );
+ property_set("ctl.stop", "bootanim");
}
void SurfaceFlinger::onFirstRef()
@@ -456,10 +456,10 @@ status_t SurfaceFlinger::readyToRun()
if (mDebugCpu)
mCpuGauge = new CPUGauge(this, ms2ns(500));
- // the boot animation!
- if (mDebugNoBootAnimation == false)
- mBootAnimation = new BootAnimation(this);
-
+
+ // start boot animation
+ property_set("ctl.start", "bootanim");
+
return NO_ERROR;
}
@@ -1543,13 +1543,13 @@ status_t SurfaceFlinger::onTransact(
// codes that require permission check
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
+ const int uid = ipc->getCallingUid();
const int self_pid = getpid();
- if (UNLIKELY(pid != self_pid)) {
+ if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
// we're called from a different process, do the real check
if (!checkCallingPermission(
String16("android.permission.ACCESS_SURFACE_FLINGER")))
{
- const int uid = ipc->getCallingUid();
LOGE("Permission Denial: "
"can't access SurfaceFlinger pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index e023182..15913f2 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -36,7 +36,6 @@
#include <private/ui/SurfaceFlingerSynchro.h>
#include "Barrier.h"
-#include "BootAnimation.h"
#include "CPUGauge.h"
#include "Layer.h"
#include "Tokenizer.h"
@@ -347,7 +346,6 @@ private:
sp<SurfaceHeapManager> mSurfaceHeapManager;
sp<GPUHardwareInterface> mGPU;
GLuint mWormholeTexName;
- sp<BootAnimation> mBootAnimation;
nsecs_t mBootTime;
// Can only accessed from the main thread, these members
@@ -374,7 +372,6 @@ private:
int mDebugCpu;
int mDebugFps;
int mDebugBackground;
- int mDebugNoBootAnimation;
// these are thread safe
mutable Barrier mReadyToRunBarrier;
diff --git a/libs/surfaceflinger/VRamHeap.cpp b/libs/surfaceflinger/VRamHeap.cpp
index 238c602..5f633bd 100644
--- a/libs/surfaceflinger/VRamHeap.cpp
+++ b/libs/surfaceflinger/VRamHeap.cpp
@@ -35,6 +35,8 @@
#include <utils/MemoryHeapPmem.h>
#include <utils/MemoryHeapBase.h>
+#include <EGL/eglnatives.h>
+
#include "GPUHardware/GPUHardware.h"
#include "SurfaceFlinger.h"
#include "VRamHeap.h"
diff --git a/libs/ui/ISurfaceFlingerClient.cpp b/libs/ui/ISurfaceFlingerClient.cpp
index dd6a798..dab5f71 100644
--- a/libs/ui/ISurfaceFlingerClient.cpp
+++ b/libs/ui/ISurfaceFlingerClient.cpp
@@ -35,6 +35,13 @@
// ---------------------------------------------------------------------------
+/* ideally AID_GRAPHICS would be in a semi-public header
+ * or there would be a way to map a user/group name to its id
+ */
+#ifndef AID_GRAPHICS
+#define AID_GRAPHICS 1003
+#endif
+
#define LIKELY( exp ) (__builtin_expect( (exp) != 0, true ))
#define UNLIKELY( exp ) (__builtin_expect( (exp) != 0, false ))
@@ -136,13 +143,13 @@ status_t BnSurfaceFlingerClient::onTransact(
IPCThreadState* ipc = IPCThreadState::self();
const int pid = ipc->getCallingPid();
- const int self_pid = getpid();
- if (UNLIKELY(pid != self_pid)) {
+ const int uid = ipc->getCallingUid();
+ const int self_pid = getpid();
+ if (UNLIKELY(pid != self_pid && uid != AID_GRAPHICS)) {
// we're called from a different process, do the real check
if (!checkCallingPermission(
String16("android.permission.ACCESS_SURFACE_FLINGER")))
{
- const int uid = ipc->getCallingUid();
LOGE("Permission Denial: "
"can't openGlobalTransaction pid=%d, uid=%d", pid, uid);
return PERMISSION_DENIED;
diff --git a/libs/utils/Parcel.cpp b/libs/utils/Parcel.cpp
index e74ad4a..b0e3750 100644
--- a/libs/utils/Parcel.cpp
+++ b/libs/utils/Parcel.cpp
@@ -409,12 +409,16 @@ status_t Parcel::appendFrom(Parcel *parcel, size_t offset, size_t len)
mObjects[idx++] = off;
mObjectsSize++;
- const flat_binder_object* flat
+ flat_binder_object* flat
= reinterpret_cast<flat_binder_object*>(mData + off);
acquire_object(proc, *flat, this);
- // take note if the object is a file descriptor
if (flat->type == BINDER_TYPE_FD) {
+ // If this is a file descriptor, we need to dup it so the
+ // new Parcel now owns its own fd, and can declare that we
+ // officially know we have fds.
+ flat->handle = dup(flat->handle);
+ flat->cookie = (void*)1;
mHasFds = mFdsKnown = true;
}
}
diff --git a/libs/utils/backup_helper_file.cpp b/libs/utils/backup_helper_file.cpp
index 8efb3eb..7ec2ce8 100644
--- a/libs/utils/backup_helper_file.cpp
+++ b/libs/utils/backup_helper_file.cpp
@@ -26,6 +26,7 @@
#include <sys/types.h>
#include <sys/uio.h>
#include <sys/stat.h>
+#include <sys/time.h> // for utimes
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
@@ -607,14 +608,14 @@ backup_helper_test_four()
0x11, 0x00, 0x00, 0x00, 0x62, 0x79, 0x74, 0x65,
0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x70, 0x61, 0x64,
0x64, 0x69, 0x6e, 0x67, 0x33, 0xab, 0xab, 0xab,
-
+
// bytes of padding2
0x44, 0x11, 0x22, 0x33, 0xef, 0xbe, 0xad, 0xde,
0x44, 0x33, 0x22, 0x11, 0x34, 0x23, 0x12, 0x01,
0x12, 0x00, 0x00, 0x00, 0x62, 0x79, 0x74, 0x65,
0x73, 0x5f, 0x6f, 0x66, 0x5f, 0x70, 0x61, 0x64,
0x64, 0x69, 0x6e, 0x67, 0x5f, 0x32, 0xab, 0xab,
-
+
// bytes of padding3
0x44, 0x11, 0x22, 0x33, 0xef, 0xbe, 0xad, 0xde,
0x44, 0x33, 0x22, 0x11, 0x34, 0x23, 0x12, 0x01,
@@ -627,7 +628,7 @@ backup_helper_test_four()
if (err != 0) {
return err;
}
-
+
// read
fd = open(filename, O_RDONLY);
if (fd == -1) {
@@ -665,7 +666,7 @@ backup_helper_test_four()
matched = false;
}
}
-
+
return matched ? 0 : 1;
}
@@ -746,7 +747,7 @@ backup_helper_test_data_writer()
system("rm -r " SCRATCH_DIR);
mkdir(SCRATCH_DIR, 0777);
mkdir(SCRATCH_DIR "data", 0777);
-
+
fd = creat(filename, 0666);
if (fd == -1) {
fprintf(stderr, "error creating: %s\n", strerror(errno));
@@ -863,7 +864,7 @@ backup_helper_test_data_reader()
system("rm -r " SCRATCH_DIR);
mkdir(SCRATCH_DIR, 0777);
mkdir(SCRATCH_DIR "data", 0777);
-
+
fd = creat(filename, 0666);
if (fd == -1) {
fprintf(stderr, "error creating: %s\n", strerror(errno));
@@ -940,9 +941,23 @@ get_mod_time(const char* filename, struct timeval times[2])
return errno;
}
times[0].tv_sec = st.st_atime;
- times[0].tv_usec = st.st_atime_nsec / 1000;
times[1].tv_sec = st.st_mtime;
+
+ // If st_atime is a macro then struct stat64 uses struct timespec
+ // to store the access and modif time values and typically
+ // st_*time_nsec is not defined. In glibc, this is controlled by
+ // __USE_MISC.
+#ifdef __USE_MISC
+#if !defined(st_atime) || defined(st_atime_nsec)
+#error "Check if this __USE_MISC conditional is still needed."
+#endif
+ times[0].tv_usec = st.st_atim.tv_nsec / 1000;
+ times[1].tv_usec = st.st_mtim.tv_nsec / 1000;
+#else
+ times[0].tv_usec = st.st_atime_nsec / 1000;
times[1].tv_usec = st.st_mtime_nsec / 1000;
+#endif
+
return 0;
}
@@ -987,7 +1002,7 @@ backup_helper_test_files()
{
BackupDataWriter dataStream(dataStreamFD);
-
+
err = back_up_files(-1, &dataStream, newSnapshotFD, SCRATCH_DIR, files_before, 5);
if (err != 0) {
return err;
@@ -1017,7 +1032,7 @@ backup_helper_test_files()
utimes(SCRATCH_DIR "data/e", e_times);
write_text_file(SCRATCH_DIR "data/g", "g\ngg\n");
unlink(SCRATCH_DIR "data/f");
-
+
char const* files_after[] = {
"data/a", // added
"data/b", // same
@@ -1047,7 +1062,7 @@ backup_helper_test_files()
{
BackupDataWriter dataStream(dataStreamFD);
-
+
err = back_up_files(oldSnapshotFD, &dataStream, newSnapshotFD, SCRATCH_DIR,
files_after, 6);
if (err != 0) {
@@ -1058,7 +1073,7 @@ backup_helper_test_files()
close(oldSnapshotFD);
close(dataStreamFD);
close(newSnapshotFD);
-
+
return 0;
}
diff --git a/libs/utils/futex_synchro.c b/libs/utils/futex_synchro.c
index ba19520..ab48c69 100644
--- a/libs/utils/futex_synchro.c
+++ b/libs/utils/futex_synchro.c
@@ -28,6 +28,7 @@
// This futex glue code is need on desktop linux, but is already part of bionic.
#if !defined(HAVE_FUTEX_WRAPPERS)
+#include <unistd.h>
#include <sys/syscall.h>
typedef unsigned int u32;
#define asmlinkage
diff --git a/location/java/android/location/ILocationCollector.aidl b/location/java/android/location/ILocationCollector.aidl
deleted file mode 100644
index b2e1796..0000000
--- a/location/java/android/location/ILocationCollector.aidl
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.location;
-
-import android.location.Location;
-
-/**
- * Listens for GPS and cell/wifi changes and anonymously uploads to server
- * for improving quality of service of NetworkLocationProvider.
- * This service is only enabled when the user has enabled the
- * network location provider.
- *
- * {@hide}
- */
-oneway interface ILocationCollector {
- /**
- * Updates GPS location if collection is enabled
- *
- * @param location location object
- */
- void updateLocation(in Location location);
-}
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 2c214c9..caf9516 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -20,7 +20,6 @@ import android.app.PendingIntent;
import android.location.Address;
import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener;
-import android.location.ILocationCollector;
import android.location.ILocationListener;
import android.location.ILocationProvider;
import android.location.Location;
@@ -83,6 +82,5 @@ interface ILocationManager
/* for installing external Location Providers */
void installLocationProvider(String name, ILocationProvider provider);
- void installLocationCollector(ILocationCollector collector);
void installGeocodeProvider(IGeocodeProvider provider);
}
diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl
index 6c23f83..4fe0494 100644
--- a/location/java/android/location/ILocationProvider.aidl
+++ b/location/java/android/location/ILocationProvider.aidl
@@ -16,6 +16,7 @@
package android.location;
+import android.location.Location;
import android.os.Bundle;
/**
@@ -41,6 +42,7 @@ interface ILocationProvider {
void enableLocationTracking(boolean enable);
void setMinTime(long minTime);
void updateNetworkState(int state);
+ void updateLocation(in Location location);
boolean sendExtraCommand(String command, inout Bundle extras);
void addListener(int uid);
void removeListener(int uid);
diff --git a/location/java/android/location/LocationManager.java b/location/java/android/location/LocationManager.java
index 872838c..86ea66f 100644
--- a/location/java/android/location/LocationManager.java
+++ b/location/java/android/location/LocationManager.java
@@ -1279,27 +1279,6 @@ public class LocationManager {
}
/**
- * Installs a location collector.
- *
- * @param provider Binder interface for the location collector
- *
- * @return true if the command succeeds.
- *
- * Requires the android.permission.INSTALL_LOCATION_COLLECTOR permission.
- *
- * {@hide}
- */
- public boolean installLocationCollector(ILocationCollector collector) {
- try {
- mService.installLocationCollector(collector);
- return true;
- } catch (RemoteException e) {
- Log.e(TAG, "RemoteException in setLocationCollector: ", e);
- return false;
- }
- }
-
- /**
* Installs a geocoder server.
*
* @param provider Binder interface for the geocoder provider
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 9003848..725fbf9 100644
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -406,6 +406,13 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
}
/**
+ * This is called to inform us when another location provider returns a location.
+ * Someday we might use this for network location injection to aid the GPS
+ */
+ public void updateLocation(Location location) {
+ }
+
+ /**
* Returns true if the provider requires access to a
* satellite-based positioning system (e.g., GPS), false
* otherwise.
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
index b40cdca..bd7088c 100644
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ b/location/java/com/android/internal/location/LocationProviderProxy.java
@@ -219,6 +219,14 @@ public class LocationProviderProxy implements IBinder.DeathRecipient {
}
}
+ public void updateLocation(Location location) {
+ try {
+ mProvider.updateLocation(location);
+ } catch (RemoteException e) {
+ Log.e(TAG, "updateLocation failed", e);
+ }
+ }
+
public boolean sendExtraCommand(String command, Bundle extras) {
try {
return mProvider.sendExtraCommand(command, extras);
diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java
index f167a44..e2e0562 100644
--- a/location/java/com/android/internal/location/MockProvider.java
+++ b/location/java/com/android/internal/location/MockProvider.java
@@ -172,6 +172,9 @@ public class MockProvider extends ILocationProvider.Stub {
public void updateNetworkState(int state) {
}
+ public void updateLocation(Location location) {
+ }
+
public boolean sendExtraCommand(String command, Bundle extras) {
return false;
}
diff --git a/media/libmediaplayerservice/MediaRecorderClient.cpp b/media/libmediaplayerservice/MediaRecorderClient.cpp
index e0d2947..8bc410c 100644
--- a/media/libmediaplayerservice/MediaRecorderClient.cpp
+++ b/media/libmediaplayerservice/MediaRecorderClient.cpp
@@ -37,6 +37,7 @@
namespace android {
const char* cameraPermission = "android.permission.CAMERA";
+const char* recordAudioPermission = "android.permission.RECORD_AUDIO";
static bool checkPermission(const char* permissionString) {
#ifndef HAVE_ANDROID_OS
@@ -86,6 +87,9 @@ status_t MediaRecorderClient::setVideoSource(int vs)
status_t MediaRecorderClient::setAudioSource(int as)
{
LOGV("setAudioSource(%d)", as);
+ if (!checkPermission(recordAudioPermission)) {
+ return PERMISSION_DENIED;
+ }
Mutex::Autolock lock(mLock);
if (mRecorder == NULL) {
LOGE("recorder is not initialized");
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 05888e0..147a085 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -46,7 +46,6 @@ import android.location.Address;
import android.location.IGeocodeProvider;
import android.location.IGpsStatusListener;
import android.location.IGpsStatusProvider;
-import android.location.ILocationCollector;
import android.location.ILocationListener;
import android.location.ILocationManager;
import android.location.ILocationProvider;
@@ -107,8 +106,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
android.Manifest.permission.ACCESS_LOCATION_EXTRA_COMMANDS;
private static final String INSTALL_LOCATION_PROVIDER =
android.Manifest.permission.INSTALL_LOCATION_PROVIDER;
- private static final String INSTALL_LOCATION_COLLECTOR =
- android.Manifest.permission.INSTALL_LOCATION_COLLECTOR;
// Set of providers that are explicitly enabled
private final Set<String> mEnabledProviders = new HashSet<String>();
@@ -171,9 +168,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
private HashMap<String,Location> mLastKnownLocation =
new HashMap<String,Location>();
- // Location collector
- private ILocationCollector mCollector;
-
private int mNetworkState = LocationProvider.TEMPORARILY_UNAVAILABLE;
// for Settings change notification
@@ -630,16 +624,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
}
}
- public void installLocationCollector(ILocationCollector collector) {
- if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_COLLECTOR)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires INSTALL_LOCATION_COLLECTOR permission");
- }
-
- // FIXME - only support one collector
- mCollector = collector;
- }
-
public void installGeocodeProvider(IGeocodeProvider provider) {
if (mContext.checkCallingOrSelfPermission(INSTALL_LOCATION_PROVIDER)
!= PackageManager.PERMISSION_GRANTED) {
@@ -1619,23 +1603,19 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
synchronized (mLock) {
Location location = (Location) msg.obj;
+ String provider = location.getProvider();
- if (mCollector != null &&
- LocationManager.GPS_PROVIDER.equals(location.getProvider())) {
- try {
- mCollector.updateLocation(location);
- } catch (RemoteException e) {
- Log.w(TAG, "mCollector.updateLocation failed");
- mCollector = null;
+ // notify other providers of the new location
+ for (int i = mProviders.size() - 1; i >= 0; i--) {
+ LocationProviderProxy proxy = mProviders.get(i);
+ if (!provider.equals(proxy.getName())) {
+ proxy.updateLocation(location);
}
}
- String provider = location.getProvider();
- if (!isAllowedBySettingsLocked(provider)) {
- return;
+ if (isAllowedBySettingsLocked(provider)) {
+ handleLocationChangedLocked(location);
}
-
- handleLocationChangedLocked(location);
}
}
} catch (Exception e) {
@@ -1935,7 +1915,6 @@ public class LocationManagerService extends ILocationManager.Stub implements Run
synchronized (mLock) {
pw.println("Current Location Manager state:");
pw.println(" sProvidersLoaded=" + sProvidersLoaded);
- pw.println(" mCollector=" + mCollector);
pw.println(" Listeners:");
int N = mReceivers.size();
for (int i=0; i<N; i++) {
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 1471435..04e0253 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -2151,16 +2151,9 @@ class PackageManagerService extends IPackageManager.Stub {
String path = scanFile.getPath();
if (scanFileNewer) {
Log.i(TAG, path + " changed; unpacking");
- try {
- cachePackageSharedLibsLI(pkg, dataPath, scanFile);
- } catch (IOException e) {
- Log.e(TAG, "Failure extracting shared libs", e);
- if(mInstaller != null) {
- mInstaller.remove(pkgName);
- } else {
- dataPath.delete();
- }
- mLastScanError = PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
+ int err = cachePackageSharedLibsLI(pkg, dataPath, scanFile);
+ if (err != PackageManager.INSTALL_SUCCEEDED) {
+ mLastScanError = err;
return null;
}
}
@@ -2444,14 +2437,15 @@ class PackageManagerService extends IPackageManager.Stub {
return pkg;
}
- private void cachePackageSharedLibsLI(PackageParser.Package pkg,
- File dataPath, File scanFile) throws IOException {
+ private int cachePackageSharedLibsLI(PackageParser.Package pkg,
+ File dataPath, File scanFile) {
File sharedLibraryDir = new File(dataPath.getPath() + "/lib");
- final String sharedLibraryABI = "armeabi";
+ final String sharedLibraryABI = Build.CPU_ABI;
final String apkLibraryDirectory = "lib/" + sharedLibraryABI + "/";
final String apkSharedLibraryPrefix = apkLibraryDirectory + "lib";
final String sharedLibrarySuffix = ".so";
- boolean createdSharedLib = false;
+ boolean hasNativeCode = false;
+ boolean installedNativeCode = false;
try {
ZipFile zipFile = new ZipFile(scanFile);
Enumeration<ZipEntry> entries =
@@ -2460,9 +2454,15 @@ class PackageManagerService extends IPackageManager.Stub {
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
if (entry.isDirectory()) {
+ if (!hasNativeCode && entry.getName().startsWith("lib")) {
+ hasNativeCode = true;
+ }
continue;
}
String entryName = entry.getName();
+ if (entryName.startsWith("lib/")) {
+ hasNativeCode = true;
+ }
if (! (entryName.startsWith(apkSharedLibraryPrefix)
&& entryName.endsWith(sharedLibrarySuffix))) {
continue;
@@ -2473,6 +2473,9 @@ class PackageManagerService extends IPackageManager.Stub {
|| (!FileUtils.isFilenameSafe(new File(libFileName)))) {
continue;
}
+
+ installedNativeCode = true;
+
String sharedLibraryFilePath = sharedLibraryDir.getPath() +
File.separator + libFileName;
File sharedLibraryFile = new File(sharedLibraryFilePath);
@@ -2484,19 +2487,23 @@ class PackageManagerService extends IPackageManager.Stub {
}
if (mInstaller == null) {
sharedLibraryDir.mkdir();
- createdSharedLib = true;
}
cacheSharedLibLI(pkg, zipFile, entry, sharedLibraryDir,
sharedLibraryFile);
}
}
} catch (IOException e) {
- Log.e(TAG, "Failed to cache package shared libs", e);
- if(createdSharedLib) {
- sharedLibraryDir.delete();
- }
- throw e;
+ Log.w(TAG, "Failed to cache package shared libs", e);
+ return PackageManager.INSTALL_FAILED_INSUFFICIENT_STORAGE;
}
+
+ if (hasNativeCode && !installedNativeCode) {
+ Log.w(TAG, "Install failed: .apk has native code but none for arch "
+ + Build.CPU_ABI);
+ return PackageManager.INSTALL_FAILED_CPU_ABI_INCOMPATIBLE;
+ }
+
+ return PackageManager.INSTALL_SUCCEEDED;
}
private void cacheSharedLibLI(PackageParser.Package pkg,
diff --git a/services/java/com/android/server/SensorService.java b/services/java/com/android/server/SensorService.java
index b253038..ceef39f 100644
--- a/services/java/com/android/server/SensorService.java
+++ b/services/java/com/android/server/SensorService.java
@@ -19,7 +19,7 @@ package com.android.server;
import android.content.Context;
import android.hardware.ISensorService;
import android.os.Binder;
-import android.os.ParcelFileDescriptor;
+import android.os.Bundle;
import android.os.RemoteException;
import android.os.IBinder;
import android.util.Config;
@@ -101,7 +101,7 @@ class SensorService extends ISensorService.Stub {
_sensors_control_init();
}
- public ParcelFileDescriptor getDataChanel() throws RemoteException {
+ public Bundle getDataChannel() throws RemoteException {
return _sensors_control_open();
}
@@ -190,7 +190,7 @@ class SensorService extends ISensorService.Stub {
ArrayList<Listener> mListeners = new ArrayList<Listener>();
private static native int _sensors_control_init();
- private static native ParcelFileDescriptor _sensors_control_open();
+ private static native Bundle _sensors_control_open();
private static native boolean _sensors_control_activate(int sensor, boolean activate);
private static native int _sensors_control_set_delay(int ms);
private static native int _sensors_control_wake();
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index a695eba..9a4b642 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -206,6 +206,34 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
}
+ public void noteStartAudio(int uid) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteAudioOnLocked(uid);
+ }
+ }
+
+ public void noteStopAudio(int uid) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteAudioOffLocked(uid);
+ }
+ }
+
+ public void noteStartVideo(int uid) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteVideoOnLocked(uid);
+ }
+ }
+
+ public void noteStopVideo(int uid) {
+ enforceCallingPermission();
+ synchronized (mStats) {
+ mStats.noteVideoOffLocked(uid);
+ }
+ }
+
public void noteWifiRunning() {
enforceCallingPermission();
synchronized (mStats) {
diff --git a/services/jni/com_android_server_SensorService.cpp b/services/jni/com_android_server_SensorService.cpp
index 695a8a3..7390786 100644
--- a/services/jni/com_android_server_SensorService.cpp
+++ b/services/jni/com_android_server_SensorService.cpp
@@ -14,7 +14,10 @@
* limitations under the License.
*/
-#define LOG_TAG "Sensors"
+#define LOG_TAG "SensorService"
+
+#define LOG_NDEBUG 0
+#include "utils/Log.h"
#include <hardware/sensors.h>
@@ -36,6 +39,14 @@ static struct parcel_file_descriptor_offsets_t
jmethodID mConstructor;
} gParcelFileDescriptorOffsets;
+static struct bundle_descriptor_offsets_t
+{
+ jclass mClass;
+ jmethodID mConstructor;
+ jmethodID mPutIntArray;
+ jmethodID mPutParcelableArray;
+} gBundleOffsets;
+
/*
* The method below are not thread-safe and not intended to be
*/
@@ -59,21 +70,45 @@ android_init(JNIEnv *env, jclass clazz)
static jobject
android_open(JNIEnv *env, jclass clazz)
{
- int fd = sSensorDevice->open_data_source(sSensorDevice);
- // new FileDescriptor()
- jobject filedescriptor = env->NewObject(
- gFileDescriptorOffsets.mClass,
- gFileDescriptorOffsets.mConstructor);
-
- if (filedescriptor != NULL) {
- env->SetIntField(filedescriptor, gFileDescriptorOffsets.mDescriptor, fd);
- // new ParcelFileDescriptor()
- return env->NewObject(gParcelFileDescriptorOffsets.mClass,
- gParcelFileDescriptorOffsets.mConstructor,
- filedescriptor);
+ native_handle_t* handle = sSensorDevice->open_data_source(sSensorDevice);
+ if (!handle) {
+ return NULL;
}
- close(fd);
- return NULL;
+
+ // new Bundle()
+ jobject bundle = env->NewObject(
+ gBundleOffsets.mClass,
+ gBundleOffsets.mConstructor);
+
+ if (handle->numFds > 0) {
+ jobjectArray fdArray = env->NewObjectArray(handle->numFds,
+ gParcelFileDescriptorOffsets.mClass, NULL);
+ for (int i = 0; i < handle->numFds; i++) {
+ // new FileDescriptor()
+ jobject fd = env->NewObject(gFileDescriptorOffsets.mClass,
+ gFileDescriptorOffsets.mConstructor);
+ env->SetIntField(fd, gFileDescriptorOffsets.mDescriptor, handle->data[i]);
+ // new ParcelFileDescriptor()
+ jobject pfd = env->NewObject(gParcelFileDescriptorOffsets.mClass,
+ gParcelFileDescriptorOffsets.mConstructor, fd);
+ env->SetObjectArrayElement(fdArray, i, pfd);
+ }
+ // bundle.putParcelableArray("fds", fdArray);
+ env->CallVoidMethod(bundle, gBundleOffsets.mPutParcelableArray,
+ env->NewStringUTF("fds"), fdArray);
+ }
+
+ if (handle->numInts > 0) {
+ jintArray intArray = env->NewIntArray(handle->numInts);
+ env->SetIntArrayRegion(intArray, 0, handle->numInts, &handle->data[handle->numInts]);
+ // bundle.putIntArray("ints", intArray);
+ env->CallVoidMethod(bundle, gBundleOffsets.mPutIntArray,
+ env->NewStringUTF("ints"), intArray);
+ }
+
+ // delete the file handle, but don't close any file descriptors
+ native_handle_delete(handle);
+ return bundle;
}
static jboolean
@@ -99,7 +134,7 @@ android_data_wake(JNIEnv *env, jclass clazz)
static JNINativeMethod gMethods[] = {
{"_sensors_control_init", "()I", (void*) android_init },
- {"_sensors_control_open", "()Landroid/os/ParcelFileDescriptor;", (void*) android_open },
+ {"_sensors_control_open", "()Landroid/os/Bundle;", (void*) android_open },
{"_sensors_control_activate", "(IZ)Z", (void*) android_activate },
{"_sensors_control_wake", "()I", (void*) android_data_wake },
{"_sensors_control_set_delay","(I)I", (void*) android_set_delay },
@@ -116,7 +151,15 @@ int register_android_server_SensorService(JNIEnv *env)
clazz = env->FindClass("android/os/ParcelFileDescriptor");
gParcelFileDescriptorOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
- gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "(Ljava/io/FileDescriptor;)V");
+ gParcelFileDescriptorOffsets.mConstructor = env->GetMethodID(clazz, "<init>",
+ "(Ljava/io/FileDescriptor;)V");
+
+ clazz = env->FindClass("android/os/Bundle");
+ gBundleOffsets.mClass = (jclass) env->NewGlobalRef(clazz);
+ gBundleOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V");
+ gBundleOffsets.mPutIntArray = env->GetMethodID(clazz, "putIntArray", "(Ljava/lang/String;[I)V");
+ gBundleOffsets.mPutParcelableArray = env->GetMethodID(clazz, "putParcelableArray",
+ "(Ljava/lang/String;[Landroid/os/Parcelable;)V");
return jniRegisterNativeMethods(env, "com/android/server/SensorService",
gMethods, NELEM(gMethods));
diff --git a/telephony/java/com/android/internal/telephony/SmsHeader.java b/telephony/java/com/android/internal/telephony/SmsHeader.java
index d220648..7872eec 100644
--- a/telephony/java/com/android/internal/telephony/SmsHeader.java
+++ b/telephony/java/com/android/internal/telephony/SmsHeader.java
@@ -111,7 +111,10 @@ public class SmsHeader {
/**
* NOTE: as defined in the spec, ConcatRef and PortAddr
* fields should not reoccur, but if they do the last
- * occurrence is to be used.
+ * occurrence is to be used. Also, for ConcatRef
+ * elements, if the count is zero, sequence is zero, or
+ * sequence is larger than count, the entire element is to
+ * be ignored.
*/
int id = inStream.read();
int length = inStream.read();
@@ -124,7 +127,10 @@ public class SmsHeader {
concatRef.msgCount = inStream.read();
concatRef.seqNumber = inStream.read();
concatRef.isEightBits = true;
- smsHeader.concatRef = concatRef;
+ if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 &&
+ concatRef.seqNumber <= concatRef.msgCount) {
+ smsHeader.concatRef = concatRef;
+ }
break;
case ELT_ID_CONCATENATED_16_BIT_REFERENCE:
concatRef = new ConcatRef();
@@ -132,7 +138,10 @@ public class SmsHeader {
concatRef.msgCount = inStream.read();
concatRef.seqNumber = inStream.read();
concatRef.isEightBits = false;
- smsHeader.concatRef = concatRef;
+ if (concatRef.msgCount != 0 && concatRef.seqNumber != 0 &&
+ concatRef.seqNumber <= concatRef.msgCount) {
+ smsHeader.concatRef = concatRef;
+ }
break;
case ELT_ID_APPLICATION_PORT_ADDRESSING_8_BIT:
portAddrs = new PortAddrs();
diff --git a/telephony/java/com/android/internal/telephony/TelephonyEventLog.java b/telephony/java/com/android/internal/telephony/TelephonyEventLog.java
index 97f9d7d..cdce488 100644
--- a/telephony/java/com/android/internal/telephony/TelephonyEventLog.java
+++ b/telephony/java/com/android/internal/telephony/TelephonyEventLog.java
@@ -30,4 +30,6 @@ public final class TelephonyEventLog {
public static final int EVENT_LOG_CGREG_FAIL = 50107;
public static final int EVENT_LOG_DATA_STATE_RADIO_OFF = 50108;
public static final int EVENT_LOG_PDP_NETWORK_DROP = 50109;
+ public static final int EVENT_LOG_CDMA_DATA_SETUP_FAILED = 50110;
+ public static final int EVENT_LOG_CDMA_DATA_DROP = 50111;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index 64f9387..761eb8b 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -39,6 +39,7 @@ import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
+import android.telephony.cdma.CdmaCellLocation;
import android.util.EventLog;
import android.text.TextUtils;
import android.util.Log;
@@ -55,10 +56,6 @@ import com.android.internal.telephony.TelephonyEventLog;
import java.util.ArrayList;
/**
- * WINK:TODO: In GsmDataConnectionTracker there are
- * EventLog's used quite a few places maybe
- * more need to be added in this file?
- *
* {@hide}
*/
public final class CdmaDataConnectionTracker extends DataConnectionTracker {
@@ -578,7 +575,14 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
if (sentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
- // we already have NUMBER_SENT_PACKETS sent without ack
+ // Packets sent without ack exceeded threshold.
+
+ if (mNoRecvPollCount == 0) {
+ EventLog.writeEvent(
+ TelephonyEventLog.EVENT_LOG_RADIO_RESET_COUNTDOWN_TRIGGERED,
+ sentSinceLastRecv);
+ }
+
if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) {
mNoRecvPollCount++;
// Slow down the poll interval to let things happen
@@ -590,6 +594,8 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
netStatPollEnabled = false;
stopNetStatPoll();
restartRadio();
+ EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_RADIO_RESET,
+ NO_RECV_POLL_LIMIT);
}
} else {
mNoRecvPollCount = 0;
@@ -845,6 +851,13 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
if (state == State.FAILED) {
cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED);
nextReconnectDelay = RECONNECT_DELAY_INITIAL_MILLIS;
+
+ CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
+ int bsid = (loc != null) ? loc.getBaseStationId() : -1;
+
+ EventLog.List val = new EventLog.List(bsid,
+ TelephonyManager.getDefault().getNetworkType());
+ EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_CDMA_DATA_SETUP_FAILED, val);
}
trySetupData(Phone.REASON_CDMA_DATA_DETACHED);
}
@@ -870,10 +883,11 @@ public final class CdmaDataConnectionTracker extends DataConnectionTracker {
}
} else {
- int cid = -1;
- EventLog.List val = new EventLog.List(cid,
+ CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
+ int bsid = (loc != null) ? loc.getBaseStationId() : -1;
+ EventLog.List val = new EventLog.List(bsid,
TelephonyManager.getDefault().getNetworkType());
- EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_PDP_NETWORK_DROP, val);
+ EventLog.writeEvent(TelephonyEventLog.EVENT_LOG_CDMA_DATA_DROP, val);
cleanUpConnection(true, null);
}
diff --git a/test-runner/android/test/TestLocationProvider.java b/test-runner/android/test/TestLocationProvider.java
index dded745..2ea020e 100644
--- a/test-runner/android/test/TestLocationProvider.java
+++ b/test-runner/android/test/TestLocationProvider.java
@@ -159,6 +159,9 @@ public class TestLocationProvider extends ILocationProvider.Stub {
public void updateNetworkState(int state) {
}
+ public void updateLocation(Location location) {
+ }
+
public boolean sendExtraCommand(String command, Bundle extras) {
return false;
}
diff --git a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
index f8d5d4d..75fd157 100644
--- a/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
+++ b/tests/AndroidTests/src/com/android/unit_tests/CdmaSmsTest.java
@@ -169,6 +169,43 @@ public class CdmaSmsTest extends AndroidTestCase {
}
@SmallTest
+ public void testUserDataHeaderIllegalConcatRef() throws Exception {
+ BearerData bearerData = new BearerData();
+ bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
+ bearerData.messageId = 55;
+ SmsHeader.ConcatRef concatRef = new SmsHeader.ConcatRef();
+ concatRef.refNumber = 0x10;
+ concatRef.msgCount = 0;
+ concatRef.seqNumber = 2;
+ concatRef.isEightBits = true;
+ SmsHeader smsHeader = new SmsHeader();
+ smsHeader.concatRef = concatRef;
+ byte[] encodedHeader = SmsHeader.toByteArray(smsHeader);
+ SmsHeader decodedHeader = SmsHeader.fromByteArray(encodedHeader);
+ assertEquals(decodedHeader.concatRef, null);
+ concatRef.isEightBits = false;
+ encodedHeader = SmsHeader.toByteArray(smsHeader);
+ decodedHeader = SmsHeader.fromByteArray(encodedHeader);
+ assertEquals(decodedHeader.concatRef, null);
+ concatRef.msgCount = 1;
+ concatRef.seqNumber = 2;
+ encodedHeader = SmsHeader.toByteArray(smsHeader);
+ decodedHeader = SmsHeader.fromByteArray(encodedHeader);
+ assertEquals(decodedHeader.concatRef, null);
+ concatRef.msgCount = 1;
+ concatRef.seqNumber = 0;
+ encodedHeader = SmsHeader.toByteArray(smsHeader);
+ decodedHeader = SmsHeader.fromByteArray(encodedHeader);
+ assertEquals(decodedHeader.concatRef, null);
+ concatRef.msgCount = 2;
+ concatRef.seqNumber = 1;
+ encodedHeader = SmsHeader.toByteArray(smsHeader);
+ decodedHeader = SmsHeader.fromByteArray(encodedHeader);
+ assertEquals(decodedHeader.concatRef.msgCount, 2);
+ assertEquals(decodedHeader.concatRef.seqNumber, 1);
+ }
+
+ @SmallTest
public void testUserDataHeaderMixedFeedback() throws Exception {
BearerData bearerData = new BearerData();
bearerData.messageType = BearerData.MESSAGE_TYPE_DELIVER;
diff --git a/tests/DumpRenderTree/AndroidManifest.xml b/tests/DumpRenderTree/AndroidManifest.xml
index 0e33d62..5442ec9 100644
--- a/tests/DumpRenderTree/AndroidManifest.xml
+++ b/tests/DumpRenderTree/AndroidManifest.xml
@@ -31,5 +31,6 @@
android:targetPackage="com.android.dumprendertree"
android:label="Layout test automation runner"
/>
- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
+ <uses-permission android:name="android.permission.INTERNET" />
+ <uses-permission android:name="android.permission.WRITE_SDCARD" />
</manifest>
diff --git a/tests/sketch/AndroidManifest.xml b/tests/sketch/AndroidManifest.xml
index 1f4333c..fbf3a09 100755
--- a/tests/sketch/AndroidManifest.xml
+++ b/tests/sketch/AndroidManifest.xml
@@ -14,25 +14,32 @@
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.gesture.example"
- android:versionCode="1"
- android:versionName="1.0.0">
- <uses-permission android:name="android.permission.READ_CONTACTS" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name="com.android.gesture.example.GestureEntry"
- android:label="@string/app_name">
+ package="com.android.gesture.example">
+
+ <uses-permission android:name="android.permission.READ_CONTACTS" />
+ <uses-permission android:name="android.permission.WRITE_SDCARD" />
+
+ <application android:icon="@drawable/icon" android:label="@string/app_name">
+
+ <activity
+ android:name="com.android.gesture.example.GestureEntry"
+ android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
<activity android:name="com.android.gesture.example.GestureLibViewer"/>
- <activity android:name="com.android.gesture.example.ContactListGestureOverlay"
- android:label="@string/overlay_name">
+
+ <activity
+ android:name="com.android.gesture.example.ContactListGestureOverlay"
+ android:label="@string/overlay_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
+
</application>
</manifest>
diff --git a/tests/sketch/res/layout/demo.xml b/tests/sketch/res/layout/demo.xml
index 8c9161a..c3a78cf 100755
--- a/tests/sketch/res/layout/demo.xml
+++ b/tests/sketch/res/layout/demo.xml
@@ -17,7 +17,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
- android:layout_height="wrap_content">
+ android:layout_height="fill_parent">
+
<Spinner
android:id="@+id/spinner"
android:layout_width="fill_parent"
@@ -25,10 +26,10 @@
android:drawSelectorOnTop="true"
android:prompt="@string/recognition_result"/>
- <com.android.gesture.GestureOverlay
+ <android.gesture.GestureOverlayView
android:id="@+id/drawingpad"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_weight="1"/>
+ android:layout_weight="1" />
</LinearLayout>
diff --git a/tests/sketch/res/layout/gestureviewer.xml b/tests/sketch/res/layout/gestureviewer.xml
index 73d6a35..e4cca52 100755
--- a/tests/sketch/res/layout/gestureviewer.xml
+++ b/tests/sketch/res/layout/gestureviewer.xml
@@ -17,7 +17,7 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
- android:layout_height="wrap_content">
+ android:layout_height="fill_parent">
<Spinner
android:id="@+id/spinner"
@@ -26,11 +26,11 @@
android:drawSelectorOnTop="true"
android:prompt="@string/recognition_result"/>
- <com.android.gesture.GestureOverlay
+ <android.gesture.GestureOverlayView
android:id="@+id/drawingpad"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
- android:layout_weight="1"/>
+ android:layout_weight="1" />
<LinearLayout
android:orientation="horizontal"
diff --git a/tests/sketch/res/layout/overlaydemo.xml b/tests/sketch/res/layout/overlaydemo.xml
index b6bbab3..4d5a657 100644
--- a/tests/sketch/res/layout/overlaydemo.xml
+++ b/tests/sketch/res/layout/overlaydemo.xml
@@ -1,12 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
+<!-- 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.
+-->
+
+<android.gesture.GestureOverlayView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/overlay"
android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
+ android:layout_height="fill_parent">
+
<ListView
- android:id="@+id/list"
- android:layout_width="fill_parent"
- android:layout_height="0dip"
- android:layout_weight="1"/>
-</LinearLayout>
+ android:id="@+id/list"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent" />
+
+</android.gesture.GestureOverlayView>
diff --git a/tests/sketch/src/com/android/gesture/GestureLibrary.java b/tests/sketch/src/com/android/gesture/GestureLibrary.java
deleted file mode 100644
index 3e753e7..0000000
--- a/tests/sketch/src/com/android/gesture/GestureLibrary.java
+++ /dev/null
@@ -1,344 +0,0 @@
-/*
- * Copyright (C) 2008-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.gesture;
-
-import android.util.Config;
-import android.util.Log;
-import android.util.Xml;
-import android.util.Xml.Encoding;
-
-import org.xml.sax.Attributes;
-import org.xml.sax.ContentHandler;
-import org.xml.sax.Locator;
-import org.xml.sax.SAXException;
-import org.xmlpull.v1.XmlSerializer;
-
-import java.io.BufferedInputStream;
-import java.io.BufferedOutputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.Set;
-
-import static com.android.gesture.GestureConstants.LOG_TAG;
-
-/**
- * GestureLibrary maintains gesture examples and makes predictions on a new
- * gesture
- */
-public class GestureLibrary {
-
- private static final String NAMESPACE = "";
-
- public static final int SEQUENCE_INVARIANT = 1;
- // when SEQUENCE_SENSITIVE is used, only single stroke gestures are allowed
- public static final int SEQUENCE_SENSITIVE = 2;
-
- public static final int ORIENTATION_INVARIANT = 1;
- // ORIENTATION_SENSITIVE is only available for single stroke gestures
- public static final int ORIENTATION_SENSITIVE = 2;
-
- private int mSequenceType = SEQUENCE_SENSITIVE;
- private int mOrientationStyle = ORIENTATION_SENSITIVE;
-
- private final String mGestureFileName;
-
- private final HashMap<String, ArrayList<Gesture>> mEntryName2gestures =
- new HashMap<String, ArrayList<Gesture>>();
-
- private Learner mClassifier;
-
- private boolean mChanged = false;
-
- /**
- * @param path where gesture data is stored
- */
- public GestureLibrary(String path) {
- mGestureFileName = path;
- mClassifier = new InstanceLearner();
- }
-
- /**
- * Specify whether the gesture library will handle orientation sensitive
- * gestures. Use ORIENTATION_INVARIANT or ORIENTATION_SENSITIVE
- *
- * @param style
- */
- public void setOrientationStyle(int style) {
- mOrientationStyle = style;
- }
-
- public int getOrientationStyle() {
- return mOrientationStyle;
- }
-
- public void setGestureType(int type) {
- mSequenceType = type;
- }
-
- public int getGestureType() {
- return mSequenceType;
- }
-
- /**
- * Get all the gesture entry names in the library
- *
- * @return a set of strings
- */
- public Set<String> getGestureEntries() {
- return mEntryName2gestures.keySet();
- }
-
- /**
- * Recognize a gesture
- *
- * @param gesture the query
- * @return a list of predictions of possible entries for a given gesture
- */
- public ArrayList<Prediction> recognize(Gesture gesture) {
- Instance instance = Instance.createInstance(this, gesture, null);
- return mClassifier.classify(this, instance);
- }
-
- /**
- * Add a gesture for the entry
- *
- * @param entryName entry name
- * @param gesture
- */
- public void addGesture(String entryName, Gesture gesture) {
- if (entryName == null || entryName.length() == 0) {
- return;
- }
- ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName);
- if (gestures == null) {
- gestures = new ArrayList<Gesture>();
- mEntryName2gestures.put(entryName, gestures);
- }
- gestures.add(gesture);
- mClassifier.addInstance(Instance.createInstance(this, gesture, entryName));
- mChanged = true;
- }
-
- /**
- * Remove a gesture from the library. If there are no more gestures for the
- * given entry, the gesture entry will be removed.
- *
- * @param entryName entry name
- * @param gesture
- */
- public void removeGesture(String entryName, Gesture gesture) {
- ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName);
- if (gestures == null) {
- return;
- }
-
- gestures.remove(gesture);
-
- // if there are no more samples, remove the entry automatically
- if (gestures.isEmpty()) {
- mEntryName2gestures.remove(entryName);
- }
-
- mClassifier.removeInstance(gesture.getID());
-
- mChanged = true;
- }
-
- /**
- * Remove a entry of gestures
- *
- * @param entryName the entry name
- */
- public void removeEntireEntry(String entryName) {
- mEntryName2gestures.remove(entryName);
- mClassifier.removeInstances(entryName);
- mChanged = true;
- }
-
- /**
- * Get all the gestures of an entry
- *
- * @param entryName
- * @return the list of gestures that is under this name
- */
- public ArrayList<Gesture> getGestures(String entryName) {
- ArrayList<Gesture> gestures = mEntryName2gestures.get(entryName);
- if (gestures != null) {
- return new ArrayList<Gesture>(gestures);
- } else {
- return null;
- }
- }
-
- /**
- * Save the gesture library
- */
- public boolean save() {
- if (!mChanged) {
- return true;
- }
-
- boolean result= false;
- PrintWriter writer = null;
-
- try {
- File file = new File(mGestureFileName);
- if (!file.getParentFile().exists()) {
- if (!file.getParentFile().mkdirs()) {
- return false;
- }
- }
-
- writer = new PrintWriter(new BufferedOutputStream(new FileOutputStream(
- mGestureFileName), GestureConstants.IO_BUFFER_SIZE));
-
- final XmlSerializer serializer = Xml.newSerializer();
- serializer.setOutput(writer);
- serializer.startDocument(Encoding.ISO_8859_1.name(), null);
- serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY);
-
- final HashMap<String, ArrayList<Gesture>> maps = mEntryName2gestures;
-
- for (String key : maps.keySet()) {
- ArrayList<Gesture> examples = maps.get(key);
- // save an entry
- serializer.startTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY);
- serializer.attribute(NAMESPACE, GestureConstants.XML_TAG_NAME, key);
- int count = examples.size();
- for (int i = 0; i < count; i++) {
- Gesture gesture = examples.get(i);
- // save each gesture in the entry
- gesture.toXML(NAMESPACE, serializer);
- }
- serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_ENTRY);
- }
-
- serializer.endTag(NAMESPACE, GestureConstants.XML_TAG_LIBRARY);
- serializer.endDocument();
- serializer.flush();
-
- mChanged = false;
- result = true;
- } catch (IOException ex) {
- Log.d(LOG_TAG, "Failed to save gestures:", ex);
- } finally {
- GestureUtilities.closeStream(writer);
- }
-
- return result;
- }
-
- /**
- * Load the gesture library
- */
- public boolean load() {
- boolean result = false;
-
- final File file = new File(mGestureFileName);
- if (file.exists()) {
- BufferedInputStream in = null;
- try {
- if (Config.DEBUG) {
- Log.v(LOG_TAG, "Load from " + mGestureFileName);
- }
- in = new BufferedInputStream(new FileInputStream(
- mGestureFileName), GestureConstants.IO_BUFFER_SIZE);
- Xml.parse(in, Encoding.ISO_8859_1, new CompactInkHandler());
- result = true;
- } catch (SAXException ex) {
- Log.d(LOG_TAG, "Failed to load gestures:", ex);
- } catch (IOException ex) {
- Log.d(LOG_TAG, "Failed to load gestures:", ex);
- } finally {
- GestureUtilities.closeStream(in);
- }
- }
-
- return result;
- }
-
- private class CompactInkHandler implements ContentHandler {
- final StringBuilder mBuffer = new StringBuilder(GestureConstants.STROKE_STRING_BUFFER_SIZE);
-
- String mEntryName;
-
- Gesture mCurrentGesture = null;
- ArrayList<Gesture> mGestures;
-
- CompactInkHandler() {
- }
-
- public void characters(char[] ch, int start, int length) {
- mBuffer.append(ch, start, length);
- }
-
- public void endDocument() {
- }
-
- public void endElement(String uri, String localName, String qName) {
- if (localName.equals(GestureConstants.XML_TAG_ENTRY)) {
- mEntryName2gestures.put(mEntryName, mGestures);
- mGestures = null;
- } else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) {
- mGestures.add(mCurrentGesture);
- mClassifier.addInstance(Instance.createInstance(GestureLibrary.this,
- mCurrentGesture, mEntryName));
- mCurrentGesture = null;
- } else if (localName.equals(GestureConstants.XML_TAG_STROKE)) {
- mCurrentGesture.addStroke(GestureStroke.createFromString(mBuffer.toString()));
- mBuffer.setLength(0);
- }
- }
-
- public void endPrefixMapping(String prefix) {
- }
-
- public void ignorableWhitespace(char[] ch, int start, int length) {
- }
-
- public void processingInstruction(String target, String data) {
- }
-
- public void setDocumentLocator(Locator locator) {
- }
-
- public void skippedEntity(String name) {
- }
-
- public void startDocument() {
- }
-
- public void startElement(String uri, String localName, String qName, Attributes attributes) {
- if (localName.equals(GestureConstants.XML_TAG_ENTRY)) {
- mGestures = new ArrayList<Gesture>();
- mEntryName = attributes.getValue(NAMESPACE, GestureConstants.XML_TAG_NAME);
- } else if (localName.equals(GestureConstants.XML_TAG_GESTURE)) {
- mCurrentGesture = new Gesture();
- mCurrentGesture.setID(Long.parseLong(attributes.getValue(NAMESPACE,
- GestureConstants.XML_TAG_ID)));
- }
- }
-
- public void startPrefixMapping(String prefix, String uri) {
- }
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/GestureListener.java b/tests/sketch/src/com/android/gesture/GestureListener.java
deleted file mode 100755
index 9b50714..0000000
--- a/tests/sketch/src/com/android/gesture/GestureListener.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2008-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.gesture;
-
-import android.view.MotionEvent;
-
-/**
- * An interface for processing gesture events
- */
-public interface GestureListener {
- public void onStartGesture(GestureOverlay overlay, MotionEvent event);
-
- public void onGesture(GestureOverlay overlay, MotionEvent event);
-
- public void onFinishGesture(GestureOverlay overlay, MotionEvent event);
-}
diff --git a/tests/sketch/src/com/android/gesture/GestureOverlay.java b/tests/sketch/src/com/android/gesture/GestureOverlay.java
deleted file mode 100755
index 454cecb..0000000
--- a/tests/sketch/src/com/android/gesture/GestureOverlay.java
+++ /dev/null
@@ -1,390 +0,0 @@
-/*
- * Copyright (C) 2008-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.gesture;
-
-import android.content.Context;
-import android.graphics.Bitmap;
-import android.graphics.BlurMaskFilter;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.Path;
-import android.graphics.Rect;
-import android.os.Handler;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import java.util.ArrayList;
-
-/**
- * A (transparent) overlay for gesture input that can be placed on top of other
- * widgets. The view can also be opaque.
- */
-
-public class GestureOverlay extends View {
- static final float TOUCH_TOLERANCE = 3;
-
- // TODO: Move all these values into XML attributes
- private static final int TRANSPARENT_BACKGROUND = 0x00000000;
-
- // TODO: SHOULD BE A TOTAL DURATION
- private static final float FADING_ALPHA_CHANGE = 0.15f;
- private static final long FADING_OFFSET = 300;
- private static final long FADING_REFRESHING_RATE = 16;
-
- private static final int GESTURE_STROKE_WIDTH = 12;
- private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
-
- private static final boolean DITHER_FLAG = true;
-
- public static final int DEFAULT_GESTURE_COLOR = 0xFFFFFF00;
-
- private static final int REFRESH_RANGE = 10;
-
- private static final BlurMaskFilter BLUR_MASK_FILTER =
- new BlurMaskFilter(1, BlurMaskFilter.Blur.NORMAL);
-
-
- // double buffering
- private Paint mGesturePaint;
-
- private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
- private Bitmap mBitmap; // with transparent background
- private Canvas mBitmapCanvas;
-
- // for rendering immediate ink feedback
- private Rect mInvalidRect = new Rect();
-
- private Path mPath;
-
- private float mX;
- private float mY;
-
- private float mCurveEndX;
- private float mCurveEndY;
-
- // current gesture
- private Gesture mCurrentGesture = null;
-
- // TODO: Make this a list of WeakReferences
- private final ArrayList<GestureListener> mGestureListeners = new ArrayList<GestureListener>();
- private ArrayList<GesturePoint> mPointBuffer = null;
-
- // fading out effect
- private boolean mIsFadingOut = false;
- private float mFadingAlpha = 1;
-
- private Handler mHandler = new Handler();
-
- private final Runnable mFadingOut = new Runnable() {
- public void run() {
- if (mIsFadingOut) {
- mFadingAlpha -= FADING_ALPHA_CHANGE;
- if (mFadingAlpha <= 0) {
- mIsFadingOut = false;
- mPath = null;
- mCurrentGesture = null;
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- } else {
- mHandler.postDelayed(this, FADING_REFRESHING_RATE);
- }
- invalidate();
- }
- }
- };
-
- public GestureOverlay(Context context) {
- super(context);
- init();
- }
-
- public GestureOverlay(Context context, AttributeSet attrs) {
- super(context, attrs);
- init();
- }
-
- public ArrayList<GesturePoint> getCurrentStroke() {
- return mPointBuffer;
- }
-
- public Gesture getCurrentGesture() {
- return mCurrentGesture;
- }
-
- /**
- * Set Gesture color
- *
- * @param color
- */
- public void setGestureColor(int color) {
- mGesturePaint.setColor(color);
- if (mCurrentGesture != null) {
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
- }
- }
-
- /**
- * Set the gesture to be shown in the view
- *
- * @param gesture
- */
- public void setCurrentGesture(Gesture gesture) {
- if (mCurrentGesture != null) {
- clear(false);
- }
-
- mCurrentGesture = gesture;
-
- if (gesture != null) {
- if (mBitmapCanvas != null) {
- gesture.draw(mBitmapCanvas, mGesturePaint);
- invalidate();
- }
- }
- }
-
- private void init() {
- mGesturePaint = new Paint();
-
- final Paint gesturePaint = mGesturePaint;
- gesturePaint.setAntiAlias(GESTURE_RENDERING_ANTIALIAS);
- gesturePaint.setColor(DEFAULT_GESTURE_COLOR);
- gesturePaint.setStyle(Paint.Style.STROKE);
- gesturePaint.setStrokeJoin(Paint.Join.ROUND);
- gesturePaint.setStrokeCap(Paint.Cap.ROUND);
- gesturePaint.setStrokeWidth(GESTURE_STROKE_WIDTH);
- gesturePaint.setDither(DITHER_FLAG);
-
- mPath = null;
- }
-
- @Override
- protected void onSizeChanged(int width, int height, int oldWidth, int oldHeight) {
- super.onSizeChanged(width, height, oldWidth, oldHeight);
-
- if (width <= 0 || height <= 0) {
- return;
- }
-
- int targetWidth = width > oldWidth ? width : oldWidth;
- int targetHeight = height > oldHeight ? height : oldHeight;
-
- if (mBitmap != null) mBitmap.recycle();
-
- mBitmap = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888);
- if (mBitmapCanvas != null) {
- mBitmapCanvas.setBitmap(mBitmap);
- } else {
- mBitmapCanvas = new Canvas(mBitmap);
- }
- mBitmapCanvas.drawColor(TRANSPARENT_BACKGROUND);
-
- if (mCurrentGesture != null) {
- mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
- }
- }
-
- public void addGestureListener(GestureListener listener) {
- mGestureListeners.add(listener);
- }
-
- public void removeGestureListener(GestureListener listener) {
- mGestureListeners.remove(listener);
- }
-
- @Override
- protected void onDraw(Canvas canvas) {
- super.onDraw(canvas);
-
- // draw double buffer
- if (mIsFadingOut) {
- mBitmapPaint.setAlpha((int) (255 * mFadingAlpha));
- canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
- } else {
- mBitmapPaint.setAlpha(255);
- canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
- }
-
- // draw the current stroke
- if (mPath != null) {
- canvas.drawPath(mPath, mGesturePaint);
- }
- }
-
- /**
- * Clear up the overlay
- *
- * @param fadeOut whether the gesture on the overlay should fade out
- * gradually or disappear immediately
- */
- public void clear(boolean fadeOut) {
- if (fadeOut) {
- mFadingAlpha = 1;
- mIsFadingOut = true;
- mHandler.removeCallbacks(mFadingOut);
- mHandler.postDelayed(mFadingOut, FADING_OFFSET);
- } else {
- mPath = null;
- mCurrentGesture = null;
- if (mBitmap != null) {
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- invalidate();
- }
- }
- }
-
- public void cancelFadingOut() {
- mIsFadingOut = false;
- mHandler.removeCallbacks(mFadingOut);
- }
-
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (!isEnabled()) {
- return true;
- }
-
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- Rect rect = touchStart(event);
- invalidate(rect);
- break;
- case MotionEvent.ACTION_MOVE:
- rect = touchMove(event);
- if (rect != null) {
- invalidate(rect);
- }
- break;
- case MotionEvent.ACTION_UP:
- touchUp(event);
- invalidate();
- break;
- }
-
- return true;
- }
-
- private Rect touchStart(MotionEvent event) {
- // pass the event to handlers
- final ArrayList<GestureListener> listeners = mGestureListeners;
- final int count = listeners.size();
- for (int i = 0; i < count; i++) {
- GestureListener listener = listeners.get(i);
- listener.onStartGesture(this, event);
- }
-
- // if there is fading out going on, stop it.
- if (mIsFadingOut) {
- mIsFadingOut = false;
- mHandler.removeCallbacks(mFadingOut);
- mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
- mCurrentGesture = null;
- }
-
- float x = event.getX();
- float y = event.getY();
-
- mX = x;
- mY = y;
-
- if (mCurrentGesture == null) {
- mCurrentGesture = new Gesture();
- }
-
- mPointBuffer = new ArrayList<GesturePoint>();
- mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
-
- mPath = new Path();
- mPath.moveTo(x, y);
-
- mInvalidRect.set((int) x - REFRESH_RANGE, (int) y - REFRESH_RANGE,
- (int) x + REFRESH_RANGE, (int) y + REFRESH_RANGE);
-
- mCurveEndX = x;
- mCurveEndY = y;
-
- return mInvalidRect;
- }
-
- private Rect touchMove(MotionEvent event) {
- Rect areaToRefresh = null;
-
- float x = event.getX();
- float y = event.getY();
-
- float dx = Math.abs(x - mX);
- float dy = Math.abs(y - mY);
-
- if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
-
- // start with the curve end
- mInvalidRect.set((int) mCurveEndX - REFRESH_RANGE, (int) mCurveEndY - REFRESH_RANGE,
- (int) mCurveEndX + REFRESH_RANGE, (int) mCurveEndY + REFRESH_RANGE);
-
- mCurveEndX = (x + mX) / 2;
- mCurveEndY = (y + mY) / 2;
- mPath.quadTo(mX, mY, mCurveEndX, mCurveEndY);
-
- // union with the control point of the new curve
- mInvalidRect.union((int) mX - REFRESH_RANGE, (int) mY - REFRESH_RANGE,
- (int) mX + REFRESH_RANGE, (int) mY + REFRESH_RANGE);
-
- // union with the end point of the new curve
- mInvalidRect.union((int) mCurveEndX - REFRESH_RANGE, (int) mCurveEndY - REFRESH_RANGE,
- (int) mCurveEndX + REFRESH_RANGE, (int) mCurveEndY + REFRESH_RANGE);
-
- areaToRefresh = mInvalidRect;
-
- mX = x;
- mY = y;
- }
-
-
- mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
-
- // pass the event to handlers
- final ArrayList<GestureListener> listeners = mGestureListeners;
- final int count = listeners.size();
- for (int i = 0; i < count; i++) {
- listeners.get(i).onGesture(this, event);
- }
-
- return areaToRefresh;
- }
-
- private void touchUp(MotionEvent event) {
- // add the stroke to the current gesture
- mCurrentGesture.addStroke(new GestureStroke(mPointBuffer));
-
- // add the stroke to the double buffer
- mGesturePaint.setMaskFilter(BLUR_MASK_FILTER);
- mBitmapCanvas.drawPath(mPath, mGesturePaint);
- mGesturePaint.setMaskFilter(null);
-
- // pass the event to handlers
- final ArrayList<GestureListener> listeners = mGestureListeners;
- final int count = listeners.size();
- for (int i = 0; i < count; i++) {
- listeners.get(i).onFinishGesture(this, event);
- }
-
- mPath = null;
- mPointBuffer = null;
- }
-
-}
diff --git a/tests/sketch/src/com/android/gesture/LetterRecognizer.java b/tests/sketch/src/com/android/gesture/LetterRecognizer.java
deleted file mode 100644
index 73151de..0000000
--- a/tests/sketch/src/com/android/gesture/LetterRecognizer.java
+++ /dev/null
@@ -1,180 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gesture;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.util.Log;
-
-import java.io.IOException;
-import java.io.DataInputStream;
-import java.io.BufferedInputStream;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-
-public class LetterRecognizer {
- private static final String LOG_TAG = "LetterRecognizer";
-
- public final static int LATIN_LOWERCASE = 0;
-
- private SigmoidUnit[] mHiddenLayer;
- private SigmoidUnit[] mOutputLayer;
-
- private final String[] mClasses;
-
- private final int mInputCount;
-
- private static class SigmoidUnit {
- final float[] mWeights;
-
- SigmoidUnit(float[] weights) {
- mWeights = weights;
- }
-
- private float compute(float[] inputs) {
- float sum = 0;
-
- final int count = inputs.length;
- final float[] weights = mWeights;
-
- for (int i = 0; i < count; i++) {
- sum += inputs[i] * weights[i];
- }
- sum += weights[weights.length - 1];
-
- return 1.0f / (float) (1 + Math.exp(-sum));
- }
- }
-
- private LetterRecognizer(int numOfInput, int numOfHidden, String[] classes) {
- mInputCount = (int)Math.sqrt(numOfInput);
- mHiddenLayer = new SigmoidUnit[numOfHidden];
- mClasses = classes;
- mOutputLayer = new SigmoidUnit[classes.length];
- }
-
- public static LetterRecognizer getLetterRecognizer(Context context, int type) {
- switch (type) {
- case LATIN_LOWERCASE: {
- return createFromResource(context, com.android.internal.R.raw.latin_lowercase);
- }
- }
- return null;
- }
-
- public ArrayList<Prediction> recognize(Gesture gesture) {
- return classify(GestureUtilities.spatialSampling(gesture, mInputCount));
- }
-
- private ArrayList<Prediction> classify(float[] vector) {
- final float[] intermediateOutput = compute(mHiddenLayer, vector);
- final float[] output = compute(mOutputLayer, intermediateOutput);
- final ArrayList<Prediction> predictions = new ArrayList<Prediction>();
-
- double sum = 0;
-
- final String[] classes = mClasses;
- final int count = classes.length;
-
- for (int i = 0; i < count; i++) {
- double score = output[i];
- sum += score;
- predictions.add(new Prediction(classes[i], score));
- }
-
- for (int i = 0; i < count; i++) {
- predictions.get(i).score /= sum;
- }
-
- Collections.sort(predictions, new Comparator<Prediction>() {
- public int compare(Prediction object1, Prediction object2) {
- double score1 = object1.score;
- double score2 = object2.score;
- if (score1 > score2) {
- return -1;
- } else if (score1 < score2) {
- return 1;
- } else {
- return 0;
- }
- }
- });
- return predictions;
- }
-
- private float[] compute(SigmoidUnit[] layer, float[] input) {
- final float[] output = new float[layer.length];
- final int count = layer.length;
-
- for (int i = 0; i < count; i++) {
- output[i] = layer[i].compute(input);
- }
-
- return output;
- }
-
- private static LetterRecognizer createFromResource(Context context, int resourceID) {
- final Resources resources = context.getResources();
-
- DataInputStream in = null;
- LetterRecognizer classifier = null;
-
- try {
- in = new DataInputStream(new BufferedInputStream(resources.openRawResource(resourceID)));
-
- final int iCount = in.readInt();
- final int hCount = in.readInt();
- final int oCount = in.readInt();
-
- final String[] classes = new String[oCount];
- for (int i = 0; i < classes.length; i++) {
- classes[i] = in.readUTF();
- }
-
- classifier = new LetterRecognizer(iCount, hCount, classes);
- SigmoidUnit[] hiddenLayer = new SigmoidUnit[hCount];
- SigmoidUnit[] outputLayer = new SigmoidUnit[oCount];
-
- for (int i = 0; i < hCount; i++) {
- float[] weights = new float[iCount];
- for (int j = 0; j < iCount; j++) {
- weights[j] = in.readFloat();
- }
- hiddenLayer[i] = new SigmoidUnit(weights);
- }
-
- for (int i = 0; i < oCount; i++) {
- float[] weights = new float[hCount];
- for (int j = 0; j < hCount; j++) {
- weights[j] = in.readFloat();
- }
- outputLayer[i] = new SigmoidUnit(weights);
- }
-
- classifier.mHiddenLayer = hiddenLayer;
- classifier.mOutputLayer = outputLayer;
-
- } catch (IOException e) {
- Log.d(LOG_TAG, "Failed to load gestures:", e);
- } finally {
- GestureUtilities.closeStream(in);
- }
-
- return classifier;
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java b/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
deleted file mode 100644
index fc878c8..0000000
--- a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * Copyright (C) 2008-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.gesture;
-
-import android.graphics.Color;
-import android.view.MotionEvent;
-import android.view.View;
-
-import java.util.ArrayList;
-
-/**
- * TouchThroughGesturing implements the interaction behavior that allows a user
- * to gesture over a regular UI widget such as ListView and at the same time,
- * still allows a user to perform basic interactions (clicking, scrolling and panning)
- * with the underlying widget.
- */
-
-public class TouchThroughGesturing implements GestureListener {
- public static final int SINGLE_STROKE = 0;
- public static final int MULTIPLE_STROKE = 1;
-
- private static final float STROKE_LENGTH_THRESHOLD = 30;
- private static final float SQUARENESS_THRESHOLD = 0.275f;
- private static final float ANGLE_THRESHOLD = 40;
-
- private static final boolean STEAL_EVENTS = false;
-
- public static final int DEFAULT_UNCERTAIN_GESTURE_COLOR = Color.argb(60, 255, 255, 0);
-
- private boolean mIsGesturing = false;
-
- private float mTotalLength;
-
- private float mX;
- private float mY;
-
- // TODO: Use WeakReference?
- private View mModel;
-
- private int mGestureType = SINGLE_STROKE;
- private int mUncertainGestureColor = DEFAULT_UNCERTAIN_GESTURE_COLOR;
-
- // TODO: Use WeakReferences
- private final ArrayList<GestureActionListener> mActionListeners =
- new ArrayList<GestureActionListener>();
-
- public TouchThroughGesturing(View model) {
- mModel = model;
- }
-
- /**
- *
- * @param type SINGLE_STROKE or MULTIPLE_STROKE
- */
- public void setGestureType(int type) {
- mGestureType = type;
- }
-
- public void setUncertainGestureColor(int color) {
- mUncertainGestureColor = color;
- }
-
- public void onStartGesture(GestureOverlay overlay, MotionEvent event) {
- if (mGestureType == MULTIPLE_STROKE) {
- overlay.cancelFadingOut();
- }
-
- mX = event.getX();
- mY = event.getY();
- mTotalLength = 0;
- mIsGesturing = false;
-
- if (mGestureType == SINGLE_STROKE || overlay.getCurrentGesture() == null
- || overlay.getCurrentGesture().getStrokesCount() == 0) {
- overlay.setGestureColor(mUncertainGestureColor);
- }
-
- mModel.dispatchTouchEvent(event);
- }
-
- public void onGesture(GestureOverlay overlay, MotionEvent event) {
- //noinspection PointlessBooleanExpression
- if (!STEAL_EVENTS) {
- mModel.dispatchTouchEvent(event);
- }
-
- if (mIsGesturing) {
- return;
- }
-
- final float x = event.getX();
- final float y = event.getY();
- final float dx = x - mX;
- final float dy = y - mY;
-
- mTotalLength += (float)Math.sqrt(dx * dx + dy * dy);
- mX = x;
- mY = y;
-
- if (mTotalLength > STROKE_LENGTH_THRESHOLD) {
- final OrientedBoundingBox box =
- GestureUtilities.computeOrientedBoundingBox(overlay.getCurrentStroke());
- float angle = Math.abs(box.orientation);
- if (angle > 90) {
- angle = 180 - angle;
- }
- if (box.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) {
- mIsGesturing = true;
- overlay.setGestureColor(GestureOverlay.DEFAULT_GESTURE_COLOR);
- if (STEAL_EVENTS) {
- event = MotionEvent.obtain(event.getDownTime(), System.currentTimeMillis(),
- MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(),
- event.getMetaState(), event.getXPrecision(), event.getYPrecision(),
- event.getDeviceId(), event.getEdgeFlags());
- }
- }
- }
-
- if (STEAL_EVENTS) {
- mModel.dispatchTouchEvent(event);
- }
- }
-
- public void onFinishGesture(GestureOverlay overlay, MotionEvent event) {
- if (mIsGesturing) {
- overlay.clear(true);
-
- final ArrayList<GestureActionListener> listeners = mActionListeners;
- final int count = listeners.size();
-
- for (int i = 0; i < count; i++) {
- listeners.get(i).onGesturePerformed(overlay, overlay.getCurrentGesture());
- }
- } else {
- mModel.dispatchTouchEvent(event);
- overlay.clear(false);
- }
- }
-
- public void addGestureActionListener(GestureActionListener listener) {
- mActionListeners.add(listener);
- }
-
- public void removeGestureActionListener(GestureActionListener listener) {
- mActionListeners.remove(listener);
- }
-
- public boolean isGesturing() {
- return mIsGesturing;
- }
-}
diff --git a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
index 6eb2f23..6767de6 100644
--- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
+++ b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
@@ -25,26 +25,20 @@ import android.os.Bundle;
import android.provider.Contacts.People;
import android.util.Log;
import android.view.View;
-import android.view.ViewGroup;
import android.view.Window;
import android.widget.AdapterView;
import android.widget.ListView;
-import com.android.gesture.Gesture;
-import com.android.gesture.GestureActionListener;
-import com.android.gesture.GestureOverlay;
-import com.android.gesture.LetterRecognizer;
-import com.android.gesture.Prediction;
-import com.android.gesture.TouchThroughGesturing;
+import android.gesture.Gesture;
+import android.gesture.GestureOverlayView;
+import android.gesture.LetterRecognizer;
+import android.gesture.Prediction;
import java.util.ArrayList;
public class ContactListGestureOverlay extends Activity {
-
- private static final String LOGTAG = "ContactListGestureOverlay";
-
+ private static final String LOG_TAG = "ContactListGestureOverlay";
private static final String SORT_ORDER = People.DISPLAY_NAME + " COLLATE LOCALIZED ASC";
-
private static final String[] CONTACTS_PROJECTION = new String[] {
People._ID, // 0
People.DISPLAY_NAME, // 1
@@ -52,11 +46,9 @@ public class ContactListGestureOverlay extends Activity {
private ContactAdapter mContactAdapter;
- private TouchThroughGesturing mGestureProcessor;
-
- private LetterRecognizer mRecognizer;
-
private ListView mContactList;
+ private LetterRecognizer mRecognizer;
+ private GestureOverlayView mOverlay;
@Override
public void onCreate(Bundle savedInstanceState) {
@@ -64,10 +56,10 @@ public class ContactListGestureOverlay extends Activity {
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setContentView(R.layout.overlaydemo);
- setProgressBarIndeterminateVisibility(true);
-
// create a letter recognizer
- mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATIN_LOWERCASE);
+ mRecognizer = LetterRecognizer.getLetterRecognizer(this,
+ LetterRecognizer.RECOGNIZER_LATIN_LOWERCASE);
+ mOverlay = (GestureOverlayView) findViewById(R.id.overlay);
// load the contact list
mContactList = (ListView) findViewById(R.id.list);
@@ -75,13 +67,14 @@ public class ContactListGestureOverlay extends Activity {
mContactList.setTextFilterEnabled(true);
mContactList.setOnItemClickListener(new AdapterView.OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v, int position, long id) {
- if (!mGestureProcessor.isGesturing()) {
+ if (!mOverlay.isGesturing()) {
Intent intent = new Intent(Intent.ACTION_VIEW, ContentUris.withAppendedId(
People.CONTENT_URI, id));
startActivity(intent);
}
}
});
+
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(People.CONTENT_URI, CONTACTS_PROJECTION, null, null,
SORT_ORDER);
@@ -92,19 +85,17 @@ public class ContactListGestureOverlay extends Activity {
mContactAdapter = new ContactAdapter(this, list);
mContactList.setAdapter(mContactAdapter);
- setProgressBarIndeterminateVisibility(false);
-
- // add a gesture overlay on top of the ListView
- GestureOverlay overlay = new GestureOverlay(this);
- mGestureProcessor = new TouchThroughGesturing(mContactList);
- mGestureProcessor.setGestureType(TouchThroughGesturing.MULTIPLE_STROKE);
- mGestureProcessor.addGestureActionListener(new GestureActionListener() {
- public void onGesturePerformed(GestureOverlay overlay, Gesture gesture) {
+ mOverlay.setGestureStrokeType(GestureOverlayView.GESTURE_STROKE_TYPE_MULTIPLE);
+ mOverlay.addOnGesturePerformedListener(new GestureOverlayView.OnGesturePerformedListener() {
+ public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
ArrayList<Prediction> predictions = mRecognizer.recognize(gesture);
if (!predictions.isEmpty()) {
- Log.v(LOGTAG, "1st Prediction : " + predictions.get(0).name);
- Log.v(LOGTAG, "2nd Prediction : " + predictions.get(1).name);
- Log.v(LOGTAG, "3rd Prediction : " + predictions.get(2).name);
+ Log.v(LOG_TAG, "1st Prediction : " + predictions.get(0).name +
+ " @" + predictions.get(0).score);
+ Log.v(LOG_TAG, "2nd Prediction : " + predictions.get(1).name +
+ " @" + predictions.get(1).score);
+ Log.v(LOG_TAG, "3rd Prediction : " + predictions.get(2).name +
+ " @" + predictions.get(2).score);
int index = mContactAdapter.search(predictions.get(0).name);
if (index != -1) {
mContactList.setSelection(index);
@@ -112,9 +103,5 @@ public class ContactListGestureOverlay extends Activity {
}
}
});
- overlay.addGestureListener(mGestureProcessor);
- ViewGroup.LayoutParams params = new ViewGroup.LayoutParams(
- ViewGroup.LayoutParams.FILL_PARENT, ViewGroup.LayoutParams.FILL_PARENT);
- this.addContentView(overlay, params);
}
}
diff --git a/tests/sketch/src/com/android/gesture/example/GestureEntry.java b/tests/sketch/src/com/android/gesture/example/GestureEntry.java
index 03a26da..3f86ed4 100644
--- a/tests/sketch/src/com/android/gesture/example/GestureEntry.java
+++ b/tests/sketch/src/com/android/gesture/example/GestureEntry.java
@@ -34,12 +34,11 @@ import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
+import android.gesture.Gesture;
-import com.android.gesture.Gesture;
-import com.android.gesture.GestureLibrary;
-import com.android.gesture.GestureListener;
-import com.android.gesture.GestureOverlay;
-import com.android.gesture.Prediction;
+import android.gesture.GestureLibrary;
+import android.gesture.GestureOverlayView;
+import android.gesture.Prediction;
import java.io.File;
import java.util.ArrayList;
@@ -48,8 +47,9 @@ public class GestureEntry extends Activity {
private static final String PARCEL_KEY = "gesture";
- static final String GESTURE_FILE_NAME = Environment.getExternalStorageDirectory().getAbsolutePath()
- + File.separator + "gestureEntry.xml";
+ static final String GESTURE_FILE_NAME =
+ Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator +
+ "demo_library.gestures";
private static final int DIALOG_NEW_ENTRY = 1;
@@ -57,7 +57,7 @@ public class GestureEntry extends Activity {
private static final int VIEW_ID = Menu.FIRST + 1;
- private GestureOverlay mGesturePad;
+ private GestureOverlayView mGesturePad;
private Spinner mRecognitionResult;
@@ -83,7 +83,7 @@ public class GestureEntry extends Activity {
// correct the recognition result by adding the new example
if (!mChangedByRecognizer) {
mGestureLibrary.addGesture(parent.getSelectedItem().toString(), mGesturePad
- .getCurrentGesture());
+ .getGesture());
} else {
mChangedByRecognizer = false;
}
@@ -96,25 +96,28 @@ public class GestureEntry extends Activity {
});
// create the area for drawing a gesture
- mGesturePad = (GestureOverlay) findViewById(R.id.drawingpad);
+ mGesturePad = (GestureOverlayView) findViewById(R.id.drawingpad);
mGesturePad.setBackgroundColor(Color.BLACK);
- mGesturePad.addGestureListener(new GestureListener() {
- public void onFinishGesture(GestureOverlay overlay, MotionEvent event) {
- recognize(overlay.getCurrentGesture());
+ mGesturePad.addOnGestureListener(new GestureOverlayView.OnGestureListener() {
+ public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
+ recognize(overlay.getGesture());
}
- public void onGesture(GestureOverlay overlay, MotionEvent event) {
+ public void onGesture(GestureOverlayView overlay, MotionEvent event) {
}
- public void onStartGesture(GestureOverlay overlay, MotionEvent event) {
+ public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
overlay.clear(false);
}
+
+ public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
+ }
});
if (savedInstanceState != null) {
Gesture gesture = (Gesture) savedInstanceState.getParcelable(PARCEL_KEY);
if (gesture != null) {
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
}
}
}
@@ -131,7 +134,7 @@ public class GestureEntry extends Activity {
.findViewById(R.id.gesturename_edit);
String text = edittext.getText().toString().trim();
if (text.length() > 0) {
- mGestureLibrary.addGesture(text, mGesturePad.getCurrentGesture());
+ mGestureLibrary.addGesture(text, mGesturePad.getGesture());
}
}
}).setNegativeButton(R.string.newgesture_dialog_cancel,
@@ -155,7 +158,7 @@ public class GestureEntry extends Activity {
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case NEW_ID:
- if (mGesturePad.getCurrentGesture() != null) {
+ if (mGesturePad.getGesture() != null) {
showDialog(DIALOG_NEW_ENTRY);
}
break;
@@ -188,7 +191,7 @@ public class GestureEntry extends Activity {
@Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
- Gesture gesture = mGesturePad.getCurrentGesture();
+ Gesture gesture = mGesturePad.getGesture();
if (gesture != null) {
outState.putParcelable(PARCEL_KEY, gesture);
}
diff --git a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
index ca54110..a561c96 100755
--- a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
+++ b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
@@ -26,10 +26,10 @@ import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.Spinner;
import android.widget.AdapterView.OnItemSelectedListener;
+import android.gesture.Gesture;
-import com.android.gesture.Gesture;
-import com.android.gesture.GestureLibrary;
-import com.android.gesture.GestureOverlay;
+import android.gesture.GestureLibrary;
+import android.gesture.GestureOverlayView;
import java.util.ArrayList;
import java.util.Collections;
@@ -41,7 +41,7 @@ import java.util.Collections;
public class GestureLibViewer extends Activity {
- private GestureOverlay mGesturePad;
+ private GestureOverlayView mGesturePad;
private Spinner mGestureCategory;
@@ -78,7 +78,7 @@ public class GestureLibViewer extends Activity {
mCurrentGestureIndex--;
}
gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
mGesturePad.invalidate();
}
}
@@ -90,7 +90,7 @@ public class GestureLibViewer extends Activity {
setContentView(R.layout.gestureviewer);
// create the area for drawing a gesture
- mGesturePad = (GestureOverlay) findViewById(R.id.drawingpad);
+ mGesturePad = (GestureOverlayView) findViewById(R.id.drawingpad);
mGesturePad.setEnabled(false);
// init the gesture library
@@ -109,7 +109,7 @@ public class GestureLibViewer extends Activity {
mGestures = mGesureLibrary.getGestures(list.get(0));
mCurrentGestureIndex = 0;
Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
}
mGestureCategory.setOnItemSelectedListener(new OnItemSelectedListener() {
@@ -118,7 +118,7 @@ public class GestureLibViewer extends Activity {
if (!mGestures.isEmpty()) {
mCurrentGestureIndex = 0;
Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
}
mGesturePad.invalidate();
}
@@ -139,7 +139,7 @@ public class GestureLibViewer extends Activity {
}
mCurrentGestureIndex++;
Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
mGesturePad.invalidate();
}
});
@@ -150,7 +150,7 @@ public class GestureLibViewer extends Activity {
if (mCurrentGestureIndex >= 1 && !mGestures.isEmpty()) {
mCurrentGestureIndex--;
Gesture gesture = mGestures.get(mCurrentGestureIndex);
- mGesturePad.setCurrentGesture(gesture);
+ mGesturePad.setGesture(gesture);
mGesturePad.invalidate();
}
}
diff --git a/tests/sketch/tools/Converter.java b/tests/sketch/tools/Converter.java
index b4654f8..5db2769 100644
--- a/tests/sketch/tools/Converter.java
+++ b/tests/sketch/tools/Converter.java
@@ -15,6 +15,7 @@ import java.io.BufferedInputStream;
*/
public class Converter {
private final File mFile;
+ private static final short VERSION_NUMBER = 1;
Converter(File file) {
mFile = file;
@@ -63,10 +64,10 @@ public class Converter {
iWeights = new float[hCount][];
for (int i = 0; i < hCount; i++) {
- iWeights[i] = new float[iCount];
+ iWeights[i] = new float[iCount + 1];
line = reader.readLine();
startIndex = 0;
- for (int j = 0; j < iCount; j++) {
+ for (int j = 0; j <= iCount; j++) {
endIndex = line.indexOf(" ", startIndex);
iWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex));
startIndex = endIndex + 1;
@@ -75,10 +76,10 @@ public class Converter {
oWeights = new float[oCount][];
for (int i = 0; i < oCount; i++) {
- oWeights[i] = new float[hCount];
+ oWeights[i] = new float[hCount + 1];
line = reader.readLine();
startIndex = 0;
- for (int j = 0; j < hCount; j++) {
+ for (int j = 0; j <= hCount; j++) {
endIndex = line.indexOf(" ", startIndex);
oWeights[i][j] = Float.parseFloat(line.substring(startIndex, endIndex));
startIndex = endIndex + 1;
@@ -105,6 +106,7 @@ public class Converter {
try {
out = new DataOutputStream(new FileOutputStream(mFile));
+ out.writeShort(VERSION_NUMBER);
out.writeInt(iCount);
out.writeInt(hCount);
out.writeInt(oCount);
@@ -144,6 +146,7 @@ public class Converter {
long start = System.nanoTime();
+ in.readShort();
iCount = in.readInt();
hCount = in.readInt();
oCount = in.readInt();
diff --git a/tts/java/android/tts/ITts.aidl b/tts/java/android/tts/ITts.aidl
new file mode 100755
index 0000000..1fe4a6a
--- /dev/null
+++ b/tts/java/android/tts/ITts.aidl
@@ -0,0 +1,59 @@
+/*
+ * 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 android.tts;
+
+import android.tts.ITtsCallback;
+
+import android.content.Intent;
+
+/**
+ * AIDL for the TTS Service
+ * ITts.java is autogenerated from this.
+ *
+ * {@hide}
+ */
+interface ITts {
+ void setEngine(in String engineName, in String[] requestedLanguages, in int strictness);
+
+ void setEngineWithIntent(in Intent engineIntent);
+
+ void setSpeechRate(in int speechRate);
+
+ void speak(in String text, in int queueMode, in String[] params);
+
+ boolean isSpeaking();
+
+ void stop();
+
+ void addSpeech(in String text, in String packageName, in int resId);
+
+ void addSpeechFile(in String text, in String filename);
+
+ void setLanguage(in String language);
+
+ boolean synthesizeToFile(in String text, in String[] params, in String outputDirectory);
+
+ void playEarcon(in String earcon, in int queueMode, in String[] params);
+
+ void addEarcon(in String earcon, in String packageName, in int resId);
+
+ void addEarconFile(in String earcon, in String filename);
+
+ void registerCallback(ITtsCallback cb);
+
+ void unregisterCallback(ITtsCallback cb);
+}
diff --git a/tests/sketch/src/com/android/gesture/GestureActionListener.java b/tts/java/android/tts/ITtsCallback.aidl
index c9c5232..1314010 100644..100755
--- a/tests/sketch/src/com/android/gesture/GestureActionListener.java
+++ b/tts/java/android/tts/ITtsCallback.aidl
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008-2009 The Android Open Source Project
+ * 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.
@@ -14,8 +14,14 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.tts;
-public interface GestureActionListener {
- public void onGesturePerformed(GestureOverlay overlay, Gesture gesture);
+/**
+ * AIDL for the callback from the TTS Service
+ * ITtsCallback.java is autogenerated from this.
+ *
+ * {@hide}
+ */
+oneway interface ITtsCallback {
+ void markReached(String mark);
}