summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--api/current.xml1381
-rw-r--r--camera/libcameraservice/CameraService.cpp2
-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--core/java/android/app/SearchDialog.java68
-rwxr-xr-xcore/java/android/gesture/Gesture.java (renamed from tests/sketch/src/com/android/gesture/Gesture.java)169
-rw-r--r--core/java/android/gesture/GestureConstants.java (renamed from tests/sketch/src/com/android/gesture/GestureActionListener.java)13
-rw-r--r--core/java/android/gesture/GestureLibrary.java346
-rwxr-xr-xcore/java/android/gesture/GestureOverlayView.java476
-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)114
-rwxr-xr-xcore/java/android/gesture/GestureUtilities.java (renamed from tests/sketch/src/com/android/gesture/GestureUtilities.java)50
-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/gesture/TouchThroughGestureListener.java (renamed from tests/sketch/src/com/android/gesture/TouchThroughGesturing.java)89
-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.java9
-rw-r--r--core/java/android/view/Window.java6
-rw-r--r--core/java/android/view/WindowManager.java9
-rw-r--r--core/java/android/widget/AbsListView.java389
-rw-r--r--core/java/android/widget/ExpandableListView.java5
-rw-r--r--core/java/android/widget/FastScroller.java19
-rw-r--r--core/java/android/widget/PopupWindow.java14
-rw-r--r--core/java/android/widget/TextView.java11
-rw-r--r--core/res/res/layout/list_gestures_overlay.xml19
-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/attrs.xml34
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/values/public.xml8
-rw-r--r--core/res/res/values/styles.xml13
-rw-r--r--core/res/res/values/themes.xml4
-rw-r--r--data/etc/platform.xml2
-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--tests/DumpRenderTree/AndroidManifest.xml3
-rwxr-xr-xtests/sketch/AndroidManifest.xml25
-rwxr-xr-xtests/sketch/res/layout/demo.xml2
-rwxr-xr-xtests/sketch/res/layout/gestureviewer.xml2
-rw-r--r--tests/sketch/res/layout/overlaydemo.xml28
-rw-r--r--tests/sketch/src/com/android/gesture/GestureConstants.java32
-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/example/ContactListGestureOverlay.java36
-rw-r--r--tests/sketch/src/com/android/gesture/example/GestureEntry.java26
-rwxr-xr-xtests/sketch/src/com/android/gesture/example/GestureLibViewer.java10
-rw-r--r--tests/sketch/tools/Converter.java11
60 files changed, 3686 insertions, 1459 deletions
diff --git a/api/current.xml b/api/current.xml
index 5bbf352..436b24a 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -3584,17 +3584,6 @@
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"
@@ -3606,61 +3595,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"
@@ -4134,6 +4068,28 @@
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="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"
@@ -4453,6 +4409,39 @@
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="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"
@@ -8853,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"
@@ -46164,6 +46164,1183 @@
</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="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.view.View"
+ 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="cancelFadingOut"
+ 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="fadeOut" type="boolean">
+</parameter>
+</method>
+<method name="getCurrentGesture"
+ return="android.gesture.Gesture"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</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="getGestureColor"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getGestureStroke"
+ return="float"
+ 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="processEvent"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="event" type="android.view.MotionEvent">
+</parameter>
+</method>
+<method name="removeAllOnGestureListeners"
+ 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="setCurrentGesture"
+ 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="setGestureDrawingColor"
+ 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="setGestureStroke"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="gestureStroke" type="float">
+</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>
+</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>
+<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="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>
+<class name="TouchThroughGestureListener"
+ extends="java.lang.Object"
+ abstract="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.gesture.GestureOverlayView.OnGestureListener">
+</implements>
+<constructor name="TouchThroughGestureListener"
+ type="android.gesture.TouchThroughGestureListener"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="model" type="android.view.View">
+</parameter>
+</constructor>
+<constructor name="TouchThroughGestureListener"
+ type="android.gesture.TouchThroughGestureListener"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="model" type="android.view.View">
+</parameter>
+<parameter name="stealEvents" type="boolean">
+</parameter>
+</constructor>
+<method name="addOnGestureActionListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.gesture.TouchThroughGestureListener.OnGesturePerformedListener">
+</parameter>
+</method>
+<method name="isGesturing"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="onGesture"
+ return="void"
+ abstract="false"
+ 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="false"
+ 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="false"
+ 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="false"
+ 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="removeOnGestureActionListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.gesture.TouchThroughGestureListener.OnGesturePerformedListener">
+</parameter>
+</method>
+<method name="setGestureType"
+ 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="MULTIPLE_STROKE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="SINGLE_STROKE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</class>
+<interface name="TouchThroughGestureListener.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>
+</package>
<package name="android.graphics"
>
<class name="AvoidXfermode"
@@ -158375,6 +159552,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"
@@ -158748,6 +159936,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"
@@ -158893,6 +160094,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"
@@ -167517,6 +168751,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 46fc2d0..4e6859c 100644
--- a/camera/libcameraservice/CameraService.cpp
+++ b/camera/libcameraservice/CameraService.cpp
@@ -1084,7 +1084,6 @@ 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) {
@@ -1121,6 +1120,7 @@ status_t CameraService::onTransact(
}
}
#endif // DEBUG_HEAP_LEAKS
+
return err;
}
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/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 1ff5665..aaaf7bf 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -33,6 +33,11 @@ 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;
@@ -145,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.
*
@@ -221,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) {
+ }
+ };
+ }
}
/**
@@ -363,6 +408,8 @@ public class SearchDialog extends Dialog implements OnItemClickListener, OnItemS
// receive broadcasts
getContext().registerReceiver(mBroadcastReceiver, mCloseDialogsFilter);
getContext().registerReceiver(mBroadcastReceiver, mPackageFilter);
+
+ startLocationUpdates();
}
/**
@@ -375,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);
@@ -399,6 +448,25 @@ 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.
*
diff --git a/tests/sketch/src/com/android/gesture/Gesture.java b/core/java/android/gesture/Gesture.java
index 44711ca..14530a1 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;
/**
@@ -149,10 +152,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 +187,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 +200,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 +268,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/GestureActionListener.java b/core/java/android/gesture/GestureConstants.java
index c9c5232..230db0c 100644
--- a/tests/sketch/src/com/android/gesture/GestureActionListener.java
+++ b/core/java/android/gesture/GestureConstants.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,8 +14,13 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
-public interface GestureActionListener {
- public void onGesturePerformed(GestureOverlay overlay, Gesture gesture);
+interface GestureConstants {
+ 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 = 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..64ddbbd
--- /dev/null
+++ b/core/java/android/gesture/GestureOverlayView.java
@@ -0,0 +1,476 @@
+/*
+ * 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.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Path;
+import android.graphics.Rect;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.animation.AnimationUtils;
+import android.view.animation.AccelerateDecelerateInterpolator;
+import com.android.internal.R;
+
+import java.util.ArrayList;
+
+/**
+ * A (transparent) overlay for gesture input that can be placed on top of other
+ * widgets.
+ *
+ * @attr ref android.R.styleable#GestureOverlayView_gestureStrokeWidth
+ * @attr ref android.R.styleable#GestureOverlayView_gestureColor
+ * @attr ref android.R.styleable#GestureOverlayView_uncertainGestureColor
+ * @attr ref android.R.styleable#GestureOverlayView_fadeDuration
+ * @attr ref android.R.styleable#GestureOverlayView_fadeOffset
+ */
+public class GestureOverlayView extends View {
+ private static final int TRANSPARENT_BACKGROUND = 0x00000000;
+ private static final boolean GESTURE_RENDERING_ANTIALIAS = true;
+ private static final boolean DITHER_FLAG = true;
+
+ private Paint mGesturePaint;
+
+ private final Paint mBitmapPaint = new Paint(Paint.DITHER_FLAG);
+ private Bitmap mBitmap;
+ private Canvas mBitmapCanvas;
+
+ private long mFadeDuration = 300;
+ private long mFadeOffset = 300;
+ private long mFadingStart;
+
+ private float mGestureStroke = 12.0f;
+ private int mCertainGestureColor = 0xFFFFFF00;
+ private int mUncertainGestureColor = 0x3CFFFF00;
+ private int mInvalidateExtraBorder = 10;
+
+ // for rendering immediate ink feedback
+ private final Rect mInvalidRect = new Rect();
+ private final Path mPath = new Path();
+
+ 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<OnGestureListener> mOnGestureListeners =
+ new ArrayList<OnGestureListener>();
+ private final ArrayList<GesturePoint> mPointBuffer = new ArrayList<GesturePoint>(100);
+
+ // fading out effect
+ private boolean mIsFadingOut = false;
+ private float mFadingAlpha = 1;
+ private final AccelerateDecelerateInterpolator mInterpolator =
+ new AccelerateDecelerateInterpolator();
+
+ private final Runnable mFadingOut = new Runnable() {
+ public void run() {
+ if (mIsFadingOut) {
+ final long now = AnimationUtils.currentAnimationTimeMillis();
+ final long duration = now - mFadingStart;
+
+ if (duration > mFadeDuration) {
+ mIsFadingOut = false;
+ mPath.rewind();
+ mCurrentGesture = null;
+ mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
+ } else {
+ float interpolatedTime = Math.max(0.0f,
+ Math.min(1.0f, duration / (float) mFadeDuration));
+ mFadingAlpha = 1.0f - mInterpolator.getInterpolation(interpolatedTime);
+ postDelayed(this, 16);
+ }
+ invalidate();
+ }
+ }
+ };
+
+ 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);
+
+ mGestureStroke = a.getFloat(R.styleable.GestureOverlayView_gestureStrokeWidth,
+ mGestureStroke);
+ mInvalidateExtraBorder = Math.max(1, ((int) mGestureStroke) - 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);
+
+ a.recycle();
+
+ init();
+ }
+
+ public ArrayList<GesturePoint> getCurrentStroke() {
+ return mPointBuffer;
+ }
+
+ public Gesture getCurrentGesture() {
+ return mCurrentGesture;
+ }
+
+ /**
+ * Set Gesture color
+ *
+ * @param color
+ */
+ public void setGestureDrawingColor(int color) {
+ mGesturePaint.setColor(color);
+ if (mCurrentGesture != null) {
+ mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
+ mCurrentGesture.draw(mBitmapCanvas, mGesturePaint);
+ }
+ invalidate();
+ }
+
+ 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 getGestureStroke() {
+ return mGestureStroke;
+ }
+
+ public void setGestureStroke(float gestureStroke) {
+ mGestureStroke = gestureStroke;
+ mInvalidateExtraBorder = Math.max(1, ((int) mGestureStroke) - 1);
+ mGesturePaint.setStrokeWidth(mGestureStroke);
+ }
+
+ /**
+ * 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(mCertainGestureColor);
+ gesturePaint.setStyle(Paint.Style.STROKE);
+ gesturePaint.setStrokeJoin(Paint.Join.ROUND);
+ gesturePaint.setStrokeCap(Paint.Cap.ROUND);
+ gesturePaint.setStrokeWidth(mGestureStroke);
+ gesturePaint.setDither(DITHER_FLAG);
+ }
+
+ @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 addOnGestureListener(OnGestureListener listener) {
+ mOnGestureListeners.add(listener);
+ }
+
+ public void removeOnGestureListener(OnGestureListener listener) {
+ mOnGestureListeners.remove(listener);
+ }
+
+ public void removeAllOnGestureListeners() {
+ mOnGestureListeners.clear();
+ }
+
+ @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
+ 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.0f;
+ mIsFadingOut = true;
+ removeCallbacks(mFadingOut);
+ mFadingStart = AnimationUtils.currentAnimationTimeMillis() + mFadeOffset;
+ postDelayed(mFadingOut, mFadeOffset);
+ } else {
+ mPath.rewind();
+ mCurrentGesture = null;
+ if (mBitmap != null) {
+ mBitmap.eraseColor(TRANSPARENT_BACKGROUND);
+ invalidate();
+ }
+ }
+ }
+
+ public void cancelFadingOut() {
+ mIsFadingOut = false;
+ removeCallbacks(mFadingOut);
+ }
+
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (!isEnabled()) {
+ return true;
+ }
+
+ processEvent(event);
+
+ return true;
+ }
+
+ public void processEvent(MotionEvent event) {
+ 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, false);
+ invalidate();
+ break;
+ case MotionEvent.ACTION_CANCEL:
+ touchUp(event, true);
+ invalidate();
+ break;
+ }
+ }
+
+ private Rect touchStart(MotionEvent event) {
+ // pass the event to handlers
+ final ArrayList<OnGestureListener> listeners = mOnGestureListeners;
+ final int count = listeners.size();
+ for (int i = 0; i < count; i++) {
+ OnGestureListener listener = listeners.get(i);
+ listener.onGestureStarted(this, event);
+ }
+
+ // if there is fading out going on, stop it.
+ if (mIsFadingOut) {
+ mIsFadingOut = false;
+ 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.add(new GesturePoint(x, y, event.getEventTime()));
+
+ mPath.rewind();
+ mPath.moveTo(x, y);
+
+ mInvalidRect.set((int) x - mInvalidateExtraBorder, (int) y - mInvalidateExtraBorder,
+ (int) x + mInvalidateExtraBorder, (int) y + mInvalidateExtraBorder);
+
+ mCurveEndX = x;
+ mCurveEndY = y;
+
+ return mInvalidRect;
+ }
+
+ 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
+ areaToRefresh.set(
+ (int) mCurveEndX - mInvalidateExtraBorder,
+ (int) mCurveEndY - mInvalidateExtraBorder,
+ (int) mCurveEndX + mInvalidateExtraBorder,
+ (int) mCurveEndY + mInvalidateExtraBorder);
+
+ mCurveEndX = (x + previousX) / 2;
+ mCurveEndY = (y + previousY) / 2;
+
+ mPath.quadTo(previousX, previousY, mCurveEndX, mCurveEndY);
+
+ // union with the control point of the new curve
+ areaToRefresh.union(
+ (int) previousX - mInvalidateExtraBorder,
+ (int) previousY - mInvalidateExtraBorder,
+ (int) previousX + mInvalidateExtraBorder,
+ (int) previousY + mInvalidateExtraBorder);
+
+ // union with the end point of the new curve
+ areaToRefresh.union(
+ (int) mCurveEndX - mInvalidateExtraBorder,
+ (int) mCurveEndY - mInvalidateExtraBorder,
+ (int) mCurveEndX + mInvalidateExtraBorder,
+ (int) mCurveEndY + mInvalidateExtraBorder);
+
+ mX = x;
+ mY = y;
+ }
+
+ mPointBuffer.add(new GesturePoint(x, y, event.getEventTime()));
+
+ // 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) {
+ // add the stroke to the current gesture
+ mCurrentGesture.addStroke(new GestureStroke(mPointBuffer));
+
+ // add the stroke to the double buffer
+ mBitmapCanvas.drawPath(mPath, mGesturePaint);
+
+ if (!cancel) {
+ // 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).onGestureEnded(this, event);
+ }
+ } 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);
+ }
+ }
+
+ mPath.rewind();
+ mPointBuffer.clear();
+ }
+
+ /**
+ * An interface for processing gesture events
+ */
+ 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);
+ }
+}
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..6d022b4 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;
@@ -126,16 +128,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 +158,8 @@ 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 +170,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..e47856c 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);
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/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java b/core/java/android/gesture/TouchThroughGestureListener.java
index fc878c8..09a528d 100644
--- a/tests/sketch/src/com/android/gesture/TouchThroughGesturing.java
+++ b/core/java/android/gesture/TouchThroughGestureListener.java
@@ -14,13 +14,13 @@
* limitations under the License.
*/
-package com.android.gesture;
+package android.gesture;
-import android.graphics.Color;
import android.view.MotionEvent;
import android.view.View;
import java.util.ArrayList;
+import java.lang.ref.WeakReference;
/**
* TouchThroughGesturing implements the interaction behavior that allows a user
@@ -28,19 +28,15 @@ import java.util.ArrayList;
* still allows a user to perform basic interactions (clicking, scrolling and panning)
* with the underlying widget.
*/
-
-public class TouchThroughGesturing implements GestureListener {
+public class TouchThroughGestureListener implements GestureOverlayView.OnGestureListener {
public static final int SINGLE_STROKE = 0;
public static final int MULTIPLE_STROKE = 1;
+ // TODO: Add properties for all these
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;
@@ -48,18 +44,23 @@ public class TouchThroughGesturing implements GestureListener {
private float mX;
private float mY;
- // TODO: Use WeakReference?
- private View mModel;
+ private WeakReference<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>();
+ private final ArrayList<OnGesturePerformedListener> mPerformedListeners =
+ new ArrayList<OnGesturePerformedListener>();
+
+ private boolean mStealEvents = false;
- public TouchThroughGesturing(View model) {
- mModel = model;
+ public TouchThroughGestureListener(View model) {
+ this(model, true);
+ }
+
+ public TouchThroughGestureListener(View model, boolean stealEvents) {
+ mModel = new WeakReference<View>(model);
+ mStealEvents = stealEvents;
}
/**
@@ -70,11 +71,7 @@ public class TouchThroughGesturing implements GestureListener {
mGestureType = type;
}
- public void setUncertainGestureColor(int color) {
- mUncertainGestureColor = color;
- }
-
- public void onStartGesture(GestureOverlay overlay, MotionEvent event) {
+ public void onGestureStarted(GestureOverlayView overlay, MotionEvent event) {
if (mGestureType == MULTIPLE_STROKE) {
overlay.cancelFadingOut();
}
@@ -86,16 +83,21 @@ public class TouchThroughGesturing implements GestureListener {
if (mGestureType == SINGLE_STROKE || overlay.getCurrentGesture() == null
|| overlay.getCurrentGesture().getStrokesCount() == 0) {
- overlay.setGestureColor(mUncertainGestureColor);
+ overlay.setGestureDrawingColor(overlay.getUncertainGestureColor());
}
- mModel.dispatchTouchEvent(event);
+ dispatchEventToModel(event);
}
- public void onGesture(GestureOverlay overlay, MotionEvent event) {
+ private void dispatchEventToModel(MotionEvent event) {
+ View v = mModel.get();
+ if (v != null) v.dispatchTouchEvent(event);
+ }
+
+ public void onGesture(GestureOverlayView overlay, MotionEvent event) {
//noinspection PointlessBooleanExpression
- if (!STEAL_EVENTS) {
- mModel.dispatchTouchEvent(event);
+ if (!mStealEvents) {
+ dispatchEventToModel(event);
}
if (mIsGesturing) {
@@ -107,7 +109,7 @@ public class TouchThroughGesturing implements GestureListener {
final float dx = x - mX;
final float dy = y - mY;
- mTotalLength += (float)Math.sqrt(dx * dx + dy * dy);
+ mTotalLength += (float) Math.sqrt(dx * dx + dy * dy);
mX = x;
mY = y;
@@ -120,46 +122,57 @@ public class TouchThroughGesturing implements GestureListener {
}
if (box.squareness > SQUARENESS_THRESHOLD || angle < ANGLE_THRESHOLD) {
mIsGesturing = true;
- overlay.setGestureColor(GestureOverlay.DEFAULT_GESTURE_COLOR);
- if (STEAL_EVENTS) {
+ overlay.setGestureDrawingColor(overlay.getGestureColor());
+ if (mStealEvents) {
event = MotionEvent.obtain(event.getDownTime(), System.currentTimeMillis(),
- MotionEvent.ACTION_UP, x, y, event.getPressure(), event.getSize(),
+ MotionEvent.ACTION_CANCEL, x, y, event.getPressure(), event.getSize(),
event.getMetaState(), event.getXPrecision(), event.getYPrecision(),
event.getDeviceId(), event.getEdgeFlags());
}
}
}
- if (STEAL_EVENTS) {
- mModel.dispatchTouchEvent(event);
+ if (mStealEvents) {
+ dispatchEventToModel(event);
}
}
- public void onFinishGesture(GestureOverlay overlay, MotionEvent event) {
+ public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
if (mIsGesturing) {
overlay.clear(true);
- final ArrayList<GestureActionListener> listeners = mActionListeners;
+ final ArrayList<OnGesturePerformedListener> listeners = mPerformedListeners;
final int count = listeners.size();
for (int i = 0; i < count; i++) {
listeners.get(i).onGesturePerformed(overlay, overlay.getCurrentGesture());
}
} else {
- mModel.dispatchTouchEvent(event);
+ dispatchEventToModel(event);
overlay.clear(false);
}
}
- public void addGestureActionListener(GestureActionListener listener) {
- mActionListeners.add(listener);
+ public void onGestureCancelled(GestureOverlayView overlay, MotionEvent event) {
+ overlay.clear(mIsGesturing);
+ if (!mIsGesturing) {
+ dispatchEventToModel(event);
+ }
}
- public void removeGestureActionListener(GestureActionListener listener) {
- mActionListeners.remove(listener);
+ public void addOnGestureActionListener(OnGesturePerformedListener listener) {
+ mPerformedListeners.add(listener);
+ }
+
+ public void removeOnGestureActionListener(OnGesturePerformedListener listener) {
+ mPerformedListeners.remove(listener);
}
public boolean isGesturing() {
return mIsGesturing;
}
+
+ public static interface OnGesturePerformedListener {
+ public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture);
+ }
}
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..c6f36a0 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;
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/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 1ca59b2..8a538d7 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -41,12 +41,18 @@ 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.TouchThroughGestureListener;
+import android.gesture.Gesture;
+import android.gesture.LetterRecognizer;
+import android.gesture.Prediction;
import com.android.internal.R;
@@ -54,7 +60,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 +73,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 +102,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 +461,23 @@ 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 TouchThroughGestureListener mGesturesListener;
+ private boolean mPreviousGesturing;
+
+ private boolean mGlobalLayoutListenerAddedFilter;
+ private int mTouchSlop;
private float mDensityScale;
private InputConnection mDefInputConnection;
@@ -535,10 +584,197 @@ 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();
+ mGesturesListener = new TouchThroughGestureListener(null);
+ mGesturesListener.setGestureType(TouchThroughGestureListener.MULTIPLE_STROKE);
+ mGesturesListener.addOnGestureActionListener(new GesturesProcessor());
+ mGesturesOverlay.addOnGestureListener(mGesturesListener);
+
+ mPreviousGesturing = false;
+ }
+ }
+
+ private void uninstallGesturesOverlay() {
+ dismissGesturesPopup();
+ mGesturesPopup = null;
+ if (mGesturesLayoutListener != null) {
+ getViewTreeObserver().removeGlobalOnLayoutListener(mGesturesLayoutListener);
+ }
+ }
+
+ @Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (mGestures != GESTURES_NONE) {
+ mGesturesOverlay.processEvent(ev);
+
+ final boolean isGesturing = mGesturesListener.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) {
@@ -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,77 @@ public abstract class AbsListView extends AdapterView<ListAdapter> implements Te
}
}
}
+
+ private class GesturesProcessor implements
+ TouchThroughGestureListener.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..b9fd5a6 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) {
@@ -411,7 +422,7 @@ class FastScroller {
setState(STATE_DRAGGING);
if (mListAdapter == null && mList != null) {
- getSections();
+ getSectionsFromIndexer();
}
cancelFling();
@@ -448,7 +459,7 @@ class FastScroller {
}
return false;
}
-
+
public class ScrollFade implements Runnable {
long mStartTime;
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/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_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/attrs.xml b/core/res/res/values/attrs.xml
index 052ab35..c4c2446 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,23 @@
<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" />
+ </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/public.xml b/core/res/res/values/public.xml
index 07bb759..55aecc4 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1101,7 +1101,13 @@
<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-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/styles.xml b/core/res/res/values/styles.xml
index 8160c9c..09e299a 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -171,6 +171,19 @@
<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">#3cffff00</item>
+ <item name="android:fadeOffset">300</item>
+ <item name="android:fadeDuration">300</item>
+ </style>
+
+ <style name="Widget.GestureOverlayView.White">
+ <item name="android:gestureColor">#ff00ff00</item>
+ <item name="android:uncertainGestureColor">#3c00ff00</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/data/etc/platform.xml b/data/etc/platform.xml
index 6d750b3..33d6b3b 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -138,6 +138,8 @@
<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/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/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..2ef291a 100755
--- a/tests/sketch/res/layout/demo.xml
+++ b/tests/sketch/res/layout/demo.xml
@@ -25,7 +25,7 @@
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"
diff --git a/tests/sketch/res/layout/gestureviewer.xml b/tests/sketch/res/layout/gestureviewer.xml
index 73d6a35..1503736 100755
--- a/tests/sketch/res/layout/gestureviewer.xml
+++ b/tests/sketch/res/layout/gestureviewer.xml
@@ -26,7 +26,7 @@
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"
diff --git a/tests/sketch/res/layout/overlaydemo.xml b/tests/sketch/res/layout/overlaydemo.xml
index b6bbab3..75c86ed 100644
--- a/tests/sketch/res/layout/overlaydemo.xml
+++ b/tests/sketch/res/layout/overlaydemo.xml
@@ -1,12 +1,20 @@
<?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.
+-->
+
+<ListView xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/list"
android:layout_width="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:layout_height="fill_parent" />
diff --git a/tests/sketch/src/com/android/gesture/GestureConstants.java b/tests/sketch/src/com/android/gesture/GestureConstants.java
deleted file mode 100644
index cb64791..0000000
--- a/tests/sketch/src/com/android/gesture/GestureConstants.java
+++ /dev/null
@@ -1,32 +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;
-
-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";
-}
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/example/ContactListGestureOverlay.java b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
index 6eb2f23..f3081b7 100644
--- a/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
+++ b/tests/sketch/src/com/android/gesture/example/ContactListGestureOverlay.java
@@ -30,12 +30,11 @@ 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 android.gesture.TouchThroughGestureListener;
import java.util.ArrayList;
@@ -52,7 +51,7 @@ public class ContactListGestureOverlay extends Activity {
private ContactAdapter mContactAdapter;
- private TouchThroughGesturing mGestureProcessor;
+ private TouchThroughGestureListener mGestureProcessor;
private LetterRecognizer mRecognizer;
@@ -67,7 +66,7 @@ public class ContactListGestureOverlay extends Activity {
setProgressBarIndeterminateVisibility(true);
// create a letter recognizer
- mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.LATIN_LOWERCASE);
+ mRecognizer = LetterRecognizer.getLetterRecognizer(this, LetterRecognizer.RECOGNIZER_LATIN_LOWERCASE);
// load the contact list
mContactList = (ListView) findViewById(R.id.list);
@@ -95,16 +94,19 @@ public class ContactListGestureOverlay extends Activity {
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) {
+ GestureOverlayView overlay = new GestureOverlayView(this);
+ mGestureProcessor = new TouchThroughGestureListener(mContactList);
+ mGestureProcessor.setGestureType(TouchThroughGestureListener.MULTIPLE_STROKE);
+ mGestureProcessor.addOnGestureActionListener(new TouchThroughGestureListener.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(LOGTAG, "1st Prediction : " + predictions.get(0).name +
+ " @" + predictions.get(0).score);
+ Log.v(LOGTAG, "2nd Prediction : " + predictions.get(1).name +
+ " @" + predictions.get(1).score);
+ Log.v(LOGTAG, "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,7 +114,7 @@ public class ContactListGestureOverlay extends Activity {
}
}
});
- overlay.addGestureListener(mGestureProcessor);
+ overlay.addOnGestureListener(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..bc2503c 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;
@@ -49,7 +48,7 @@ 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";
+ + File.separator + "demo_library.gestures";
private static final int DIALOG_NEW_ENTRY = 1;
@@ -57,7 +56,7 @@ public class GestureEntry extends Activity {
private static final int VIEW_ID = Menu.FIRST + 1;
- private GestureOverlay mGesturePad;
+ private GestureOverlayView mGesturePad;
private Spinner mRecognitionResult;
@@ -96,19 +95,22 @@ 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) {
+ mGesturePad.addOnGestureListener(new GestureOverlayView.OnGestureListener() {
+ public void onGestureEnded(GestureOverlayView overlay, MotionEvent event) {
recognize(overlay.getCurrentGesture());
}
- 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) {
diff --git a/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java b/tests/sketch/src/com/android/gesture/example/GestureLibViewer.java
index ca54110..aa07e7b 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;
@@ -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
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();