Merge "bugreport: Add bcm4329 internal counters dump"
diff --git a/Android.mk b/Android.mk
index 0af2302..4e01b97 100644
--- a/Android.mk
+++ b/Android.mk
@@ -419,6 +419,8 @@
resources/samples/SampleSyncAdapter "Sample Sync Adapter" \
-samplecode $(sample_dir)/SearchableDictionary \
resources/samples/SearchableDictionary "Searchable Dictionary v2" \
+ -samplecode $(sample_dir)/SipDemo \
+ resources/samples/SipDemo "SIP Demo" \
-samplecode $(sample_dir)/Snake \
resources/samples/Snake "Snake" \
-samplecode $(sample_dir)/SoftKeyboard \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1cc8e33..c7bd9fd 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -85,6 +85,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/com/trustedlogic)
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/android_stubs_current_intermediates/src/com/trustedlogic)
+$(call add-clean-step, rm -rf $(OUT_DIR)/target/target/common/obj/APPS/Music2_intermediates)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/current.xml b/api/current.xml
index 07f298e..9173afd 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -1905,7 +1905,7 @@
type="int"
transient="false"
volatile="false"
- value="16843550"
+ value="16843552"
static="true"
final="true"
deprecated="not deprecated"
@@ -1916,7 +1916,7 @@
type="int"
transient="false"
volatile="false"
- value="16843549"
+ value="16843551"
static="true"
final="true"
deprecated="not deprecated"
@@ -1927,7 +1927,7 @@
type="int"
transient="false"
volatile="false"
- value="16843551"
+ value="16843553"
static="true"
final="true"
deprecated="not deprecated"
@@ -3804,6 +3804,17 @@
visibility="public"
>
</field>
+<field name="enterFadeDuration"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843549"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="entries"
type="int"
transient="false"
@@ -3848,6 +3859,17 @@
visibility="public"
>
</field>
+<field name="exitFadeDuration"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843550"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="expandableListPreferredChildIndicatorLeft"
type="int"
transient="false"
@@ -9308,7 +9330,7 @@
type="int"
transient="false"
volatile="false"
- value="16843553"
+ value="16843555"
static="true"
final="true"
deprecated="not deprecated"
@@ -9319,7 +9341,7 @@
type="int"
transient="false"
volatile="false"
- value="16843552"
+ value="16843554"
static="true"
final="true"
deprecated="not deprecated"
@@ -17874,7 +17896,7 @@
</class>
<class name="Keyframe"
extends="java.lang.Object"
- abstract="false"
+ abstract="true"
static="false"
final="false"
deprecated="not deprecated"
@@ -17889,86 +17911,10 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="java.lang.Object">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="java.lang.Float">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="java.lang.Integer">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="java.lang.Double">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="int">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="float">
-</parameter>
-</constructor>
-<constructor name="Keyframe"
- type="android.animation.Keyframe"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="fraction" type="float">
-</parameter>
-<parameter name="value" type="double">
-</parameter>
</constructor>
<method name="clone"
return="android.animation.Keyframe"
- abstract="false"
+ abstract="true"
native="false"
synchronized="false"
static="false"
@@ -18012,6 +17958,17 @@
</method>
<method name="getValue"
return="java.lang.Object"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="hasValue"
+ return="boolean"
abstract="false"
native="false"
synchronized="false"
@@ -18021,6 +17978,90 @@
visibility="public"
>
</method>
+<method name="ofFloat"
+ return="android.animation.Keyframe"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
+<parameter name="value" type="float">
+</parameter>
+</method>
+<method name="ofFloat"
+ return="android.animation.Keyframe"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
+</method>
+<method name="ofInt"
+ return="android.animation.Keyframe"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
+<parameter name="value" type="int">
+</parameter>
+</method>
+<method name="ofInt"
+ return="android.animation.Keyframe"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
+</method>
+<method name="ofObject"
+ return="android.animation.Keyframe"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
+<parameter name="value" type="java.lang.Object">
+</parameter>
+</method>
+<method name="ofObject"
+ return="android.animation.Keyframe"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="fraction" type="float">
+</parameter>
+</method>
<method name="setFraction"
return="void"
abstract="false"
@@ -18049,7 +18090,7 @@
</method>
<method name="setValue"
return="void"
- abstract="false"
+ abstract="true"
native="false"
synchronized="false"
static="false"
@@ -18456,23 +18497,6 @@
visibility="public"
>
</method>
-<method name="ofDouble"
- return="android.animation.ObjectAnimator"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="target" type="java.lang.Object">
-</parameter>
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="ofFloat"
return="android.animation.ObjectAnimator"
abstract="false"
@@ -18507,23 +18531,6 @@
<parameter name="values" type="int...">
</parameter>
</method>
-<method name="ofLong"
- return="android.animation.ObjectAnimator"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="target" type="java.lang.Object">
-</parameter>
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="ofObject"
return="android.animation.ObjectAnimator"
abstract="false"
@@ -18626,21 +18633,6 @@
visibility="public"
>
</method>
-<method name="ofDouble"
- return="android.animation.PropertyValuesHolder"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="ofFloat"
return="android.animation.PropertyValuesHolder"
abstract="false"
@@ -18686,21 +18678,6 @@
<parameter name="values" type="android.animation.Keyframe...">
</parameter>
</method>
-<method name="ofLong"
- return="android.animation.PropertyValuesHolder"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="propertyName" type="java.lang.String">
-</parameter>
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="ofObject"
return="android.animation.PropertyValuesHolder"
abstract="false"
@@ -18718,19 +18695,6 @@
<parameter name="values" type="java.lang.Object...">
</parameter>
</method>
-<method name="setDoubleValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="setEvaluator"
return="void"
abstract="false"
@@ -18796,19 +18760,6 @@
<parameter name="values" type="android.animation.Keyframe...">
</parameter>
</method>
-<method name="setLongValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="setObjectValues"
return="void"
abstract="false"
@@ -19083,19 +19034,6 @@
visibility="public"
>
</method>
-<method name="ofDouble"
- return="android.animation.ValueAnimator"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="ofFloat"
return="android.animation.ValueAnimator"
abstract="false"
@@ -19122,19 +19060,6 @@
<parameter name="values" type="int...">
</parameter>
</method>
-<method name="ofLong"
- return="android.animation.ValueAnimator"
- abstract="false"
- native="false"
- synchronized="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="ofObject"
return="android.animation.ValueAnimator"
abstract="false"
@@ -19211,19 +19136,6 @@
<parameter name="playTime" type="long">
</parameter>
</method>
-<method name="setDoubleValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="double...">
-</parameter>
-</method>
<method name="setDuration"
return="android.animation.ValueAnimator"
abstract="false"
@@ -19302,19 +19214,6 @@
<parameter name="value" type="android.animation.TimeInterpolator">
</parameter>
</method>
-<method name="setLongValues"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="values" type="long...">
-</parameter>
-</method>
<method name="setObjectValues"
return="void"
abstract="false"
@@ -19626,6 +19525,17 @@
<parameter name="index" type="int">
</parameter>
</method>
+<method name="getTabCount"
+ return="int"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getTitle"
return="java.lang.CharSequence"
abstract="true"
@@ -28423,6 +28333,17 @@
visibility="public"
>
</method>
+<method name="disallowAddToBackStack"
+ return="android.app.FragmentTransaction"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="hide"
return="android.app.FragmentTransaction"
abstract="true"
@@ -28436,6 +28357,17 @@
<parameter name="fragment" type="android.app.Fragment">
</parameter>
</method>
+<method name="isAddToBackStackAllowed"
+ return="boolean"
+ abstract="true"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="isEmpty"
return="boolean"
abstract="true"
@@ -84055,6 +83987,17 @@
visibility="public"
>
</method>
+<method name="jumpToCurrentState"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="mutate"
return="android.graphics.drawable.Drawable"
abstract="false"
@@ -84544,6 +84487,32 @@
<parameter name="state" type="android.graphics.drawable.DrawableContainer.DrawableContainerState">
</parameter>
</method>
+<method name="setEnterFadeDuration"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="ms" type="int">
+</parameter>
+</method>
+<method name="setExitFadeDuration"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="ms" type="int">
+</parameter>
+</method>
<method name="unscheduleDrawable"
return="void"
abstract="false"
@@ -84691,6 +84660,28 @@
visibility="public"
>
</method>
+<method name="getEnterFadeDuration"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getExitFadeDuration"
+ return="int"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getOpacity"
return="int"
abstract="false"
@@ -84752,6 +84743,32 @@
<parameter name="constant" type="boolean">
</parameter>
</method>
+<method name="setEnterFadeDuration"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="duration" type="int">
+</parameter>
+</method>
+<method name="setExitFadeDuration"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="duration" type="int">
+</parameter>
+</method>
<method name="setVariablePadding"
return="void"
abstract="false"
@@ -142494,6 +142511,17 @@
visibility="public"
>
</method>
+<method name="hasVibrator"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="vibrate"
return="void"
abstract="false"
@@ -157182,6 +157210,160 @@
>
</field>
</interface>
+<class name="MediaStore.Files"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="MediaStore.Files"
+ type="android.provider.MediaStore.Files"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
+<method name="getContentUri"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="volumeName" type="java.lang.String">
+</parameter>
+</method>
+<method name="getContentUri"
+ return="android.net.Uri"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="volumeName" type="java.lang.String">
+</parameter>
+<parameter name="rowId" type="long">
+</parameter>
+</method>
+</class>
+<interface name="MediaStore.Files.FileColumns"
+ abstract="true"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<implements name="android.provider.MediaStore.MediaColumns">
+</implements>
+<field name="MEDIA_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""media_type""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MEDIA_TYPE_AUDIO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="2"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MEDIA_TYPE_IMAGE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="1"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MEDIA_TYPE_NONE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="0"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MEDIA_TYPE_PLAYLIST"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="4"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MEDIA_TYPE_VIDEO"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="MIME_TYPE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""mime_type""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="PARENT"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""parent""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="TITLE"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""title""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+</interface>
<class name="MediaStore.Images"
extends="java.lang.Object"
abstract="false"
@@ -160907,6 +161089,17 @@
visibility="public"
>
</field>
+<field name="USER_ROTATION"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""user_rotation""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="USE_GOOGLE_MAIL"
type="java.lang.String"
transient="false"
@@ -166627,6 +166820,17 @@
visibility="public"
>
</field>
+<field name="NETWORK_TYPE_EHRPD"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="14"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="NETWORK_TYPE_EVDO_0"
type="int"
transient="false"
@@ -166715,6 +166919,17 @@
visibility="public"
>
</field>
+<field name="NETWORK_TYPE_LTE"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="13"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="NETWORK_TYPE_UMTS"
type="int"
transient="false"
@@ -166770,6 +166985,17 @@
visibility="public"
>
</field>
+<field name="PHONE_TYPE_SIP"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="3"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="SIM_STATE_ABSENT"
type="int"
transient="false"
@@ -190513,6 +190739,17 @@
<parameter name="newSize" type="int">
</parameter>
</method>
+<field name="NOTHING"
+ type="int[]"
+ transient="false"
+ volatile="false"
+ value="null"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="WILD_CARD"
type="int[]"
transient="false"
@@ -203855,6 +204092,17 @@
visibility="public"
>
</method>
+<method name="jumpDrawablesToCurrentState"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="layout"
return="void"
abstract="false"
@@ -250796,7 +251044,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -250811,11 +251059,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<parameter name="offset" type="int">
</parameter>
-<parameter name="count" type="int">
+<parameter name="byteCount" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -251056,7 +251304,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -251071,11 +251319,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<parameter name="offset" type="int">
</parameter>
-<parameter name="length" type="int">
+<parameter name="byteCount" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -253982,7 +254230,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -253997,11 +254245,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<parameter name="offset" type="int">
</parameter>
-<parameter name="length" type="int">
+<parameter name="byteCount" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -257802,7 +258050,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -257817,11 +258065,11 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="buffer" type="byte[]">
+<parameter name="dst" type="byte[]">
</parameter>
<parameter name="offset" type="int">
</parameter>
-<parameter name="count" type="int">
+<parameter name="byteCount" type="int">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
@@ -283974,9 +284222,9 @@
>
<parameter name="uri" type="java.net.URI">
</parameter>
-<parameter name="sa" type="java.net.SocketAddress">
+<parameter name="address" type="java.net.SocketAddress">
</parameter>
-<parameter name="ioe" type="java.io.IOException">
+<parameter name="failure" type="java.io.IOException">
</parameter>
</method>
<method name="getDefault"
@@ -284075,7 +284323,7 @@
>
<parameter name="uri" type="java.net.URI">
</parameter>
-<parameter name="conn" type="java.net.URLConnection">
+<parameter name="connection" type="java.net.URLConnection">
</parameter>
<exception name="IOException" type="java.io.IOException">
</exception>
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 9fe1fb8..6650a71 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -248,13 +248,11 @@
mFlingerSurface = s;
mAndroidAnimation = true;
- if ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) ||
- (access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0)) {
- if ((mZip.open(USER_BOOTANIMATION_FILE) != NO_ERROR) ||
- (mZip.open(SYSTEM_BOOTANIMATION_FILE) != NO_ERROR)) {
- mAndroidAnimation = false;
- }
- }
+ if ((access(USER_BOOTANIMATION_FILE, R_OK) == 0) &&
+ (mZip.open(USER_BOOTANIMATION_FILE) == NO_ERROR) ||
+ (access(SYSTEM_BOOTANIMATION_FILE, R_OK) == 0) &&
+ (mZip.open(SYSTEM_BOOTANIMATION_FILE) == NO_ERROR))
+ mAndroidAnimation = false;
return NO_ERROR;
}
diff --git a/core/java/android/animation/AnimatorInflater.java b/core/java/android/animation/AnimatorInflater.java
index 4a6c460..b96391a 100644
--- a/core/java/android/animation/AnimatorInflater.java
+++ b/core/java/android/animation/AnimatorInflater.java
@@ -51,8 +51,6 @@
*/
private static final int VALUE_TYPE_FLOAT = 0;
private static final int VALUE_TYPE_INT = 1;
- private static final int VALUE_TYPE_DOUBLE = 2;
- private static final int VALUE_TYPE_LONG = 3;
private static final int VALUE_TYPE_COLOR = 4;
private static final int VALUE_TYPE_CUSTOM = 5;
@@ -242,42 +240,6 @@
}
break;
- case VALUE_TYPE_LONG: {
- int valueFrom;
- int valueTo;
- if (hasFrom) {
- valueFrom = a.getInteger(com.android.internal.R.styleable.Animator_valueFrom, 0);
- if (hasTo) {
- valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0);
- anim.setLongValues(valueFrom, valueTo);
- } else {
- anim.setLongValues(valueFrom);
- }
- } else {
- valueTo = a.getInteger(com.android.internal.R.styleable.Animator_valueTo, 0);
- anim.setLongValues(valueTo);
- }
- }
- break;
-
- case VALUE_TYPE_DOUBLE: {
- double valueFrom;
- double valueTo;
- if (hasFrom) {
- valueFrom = a.getFloat(com.android.internal.R.styleable.Animator_valueFrom, 0f);
- if (hasTo) {
- valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
- anim.setDoubleValues(valueFrom, valueTo);
- } else {
- anim.setDoubleValues(valueFrom);
- }
- } else {
- valueTo = a.getFloat(com.android.internal.R.styleable.Animator_valueTo, 0f);
- anim.setDoubleValues(valueTo);
- }
- }
- break;
-
case VALUE_TYPE_CUSTOM: {
// TODO: How to get an 'Object' value?
float valueFrom;
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 8fc45f4..9ba9388 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -362,14 +362,18 @@
// dependencies on all of the nodes. For example, we don't want to start an animation
// when some other animation also wants to start when the first animation begins.
final ArrayList<Node> nodesToStart = new ArrayList<Node>();
- for (Node node : mSortedNodes) {
+ int numSortedNodes = mSortedNodes.size();
+ for (int i = 0; i < numSortedNodes; ++i) {
+ Node node = mSortedNodes.get(i);
if (mSetListener == null) {
mSetListener = new AnimatorSetListener(this);
}
if (node.dependencies == null || node.dependencies.size() == 0) {
nodesToStart.add(node);
} else {
- for (Dependency dependency : node.dependencies) {
+ int numDependencies = node.dependencies.size();
+ for (int j = 0; j < numDependencies; ++j) {
+ Dependency dependency = node.dependencies.get(j);
dependency.node.animation.addListener(
new DependencyListener(this, node, dependency.rule));
}
@@ -389,7 +393,9 @@
delayAnim.setDuration(mStartDelay);
delayAnim.addListener(new AnimatorListenerAdapter() {
public void onAnimationEnd(Animator anim) {
- for (Node node : nodesToStart) {
+ int numNodes = nodesToStart.size();
+ for (int i = 0; i < numNodes; ++i) {
+ Node node = nodesToStart.get(i);
node.animation.start();
mPlayingSet.add(node.animation);
}
@@ -399,8 +405,9 @@
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationStart(this);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationStart(this);
}
}
}
@@ -540,7 +547,9 @@
return;
}
Dependency dependencyToRemove = null;
- for (Dependency dependency : mNode.tmpDependencies) {
+ int numDependencies = mNode.tmpDependencies.size();
+ for (int i = 0; i < numDependencies; ++i) {
+ Dependency dependency = mNode.tmpDependencies.get(i);
if (dependency.rule == mRule &&
dependency.node.animation == dependencyAnimation) {
// rule fired - remove the dependency and listener and check to
@@ -571,8 +580,9 @@
public void onAnimationCancel(Animator animation) {
if (mPlayingSet.size() == 0) {
if (mListeners != null) {
- for (AnimatorListener listener : mListeners) {
- listener.onAnimationCancel(mAnimatorSet);
+ int numListeners = mListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ mListeners.get(i).onAnimationCancel(mAnimatorSet);
}
}
}
@@ -586,8 +596,9 @@
animNode.done = true;
ArrayList<Node> sortedNodes = mAnimatorSet.mSortedNodes;
boolean allDone = true;
- for (Node node : sortedNodes) {
- if (!node.done) {
+ int numSortedNodes = sortedNodes.size();
+ for (int i = 0; i < numSortedNodes; ++i) {
+ if (!sortedNodes.get(i).done) {
allDone = false;
break;
}
@@ -598,8 +609,9 @@
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationEnd(mAnimatorSet);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationEnd(mAnimatorSet);
}
}
}
@@ -629,17 +641,23 @@
if (mNeedsSort) {
mSortedNodes.clear();
ArrayList<Node> roots = new ArrayList<Node>();
- for (Node node : mNodes) {
+ int numNodes = mNodes.size();
+ for (int i = 0; i < numNodes; ++i) {
+ Node node = mNodes.get(i);
if (node.dependencies == null || node.dependencies.size() == 0) {
roots.add(node);
}
}
ArrayList<Node> tmpRoots = new ArrayList<Node>();
while (roots.size() > 0) {
- for (Node root : roots) {
+ int numRoots = roots.size();
+ for (int i = 0; i < numRoots; ++i) {
+ Node root = roots.get(i);
mSortedNodes.add(root);
if (root.nodeDependents != null) {
- for (Node node : root.nodeDependents) {
+ int numDependents = root.nodeDependents.size();
+ for (int j = 0; j < numDependents; ++j) {
+ Node node = root.nodeDependents.get(j);
node.nodeDependencies.remove(root);
if (node.nodeDependencies.size() == 0) {
tmpRoots.add(node);
@@ -660,9 +678,13 @@
// Doesn't need sorting, but still need to add in the nodeDependencies list
// because these get removed as the event listeners fire and the dependencies
// are satisfied
- for (Node node : mNodes) {
+ int numNodes = mNodes.size();
+ for (int i = 0; i < numNodes; ++i) {
+ Node node = mNodes.get(i);
if (node.dependencies != null && node.dependencies.size() > 0) {
- for (Dependency dependency : node.dependencies) {
+ int numDependencies = node.dependencies.size();
+ for (int j = 0; j < numDependencies; ++j) {
+ Dependency dependency = node.dependencies.get(j);
if (node.nodeDependencies == null) {
node.nodeDependencies = new ArrayList<Node>();
}
diff --git a/core/java/android/animation/FloatKeyframeSet.java b/core/java/android/animation/FloatKeyframeSet.java
new file mode 100644
index 0000000..6fad4a68
--- /dev/null
+++ b/core/java/android/animation/FloatKeyframeSet.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (C) 2010 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.animation;
+
+import android.animation.Keyframe.FloatKeyframe;
+
+import java.util.ArrayList;
+
+/**
+ * This class holds a collection of FloatKeyframe objects and is called by ValueAnimator to calculate
+ * values between those keyframes for a given animation. The class internal to the animation
+ * package because it is an implementation detail of how Keyframes are stored and used.
+ *
+ * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclasses for
+ * int, long, and double, exists to speed up the getValue() method when there is no custom
+ * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
+ * Object equivalents of these primitive types.</p>
+ */
+class FloatKeyframeSet extends KeyframeSet {
+ private float firstValue;
+ private float lastValue;
+ private float deltaValue;
+ private boolean firstTime = true;
+
+ public FloatKeyframeSet(FloatKeyframe... keyframes) {
+ super(keyframes);
+ }
+
+ @Override
+ public Object getValue(float fraction) {
+ return getFloatValue(fraction);
+ }
+
+ @Override
+ public FloatKeyframeSet clone() {
+ ArrayList<Keyframe> keyframes = mKeyframes;
+ int numKeyframes = mKeyframes.size();
+ FloatKeyframe[] newKeyframes = new FloatKeyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ newKeyframes[i] = (FloatKeyframe) keyframes.get(i).clone();
+ }
+ FloatKeyframeSet newSet = new FloatKeyframeSet(newKeyframes);
+ return newSet;
+ }
+
+ public float getFloatValue(float fraction) {
+ if (mNumKeyframes == 2) {
+ if (firstTime) {
+ firstTime = false;
+ firstValue = ((FloatKeyframe) mKeyframes.get(0)).getFloatValue();
+ lastValue = ((FloatKeyframe) mKeyframes.get(1)).getFloatValue();
+ deltaValue = lastValue - firstValue;
+ }
+ if (mInterpolator != null) {
+ fraction = mInterpolator.getInterpolation(fraction);
+ }
+ if (mEvaluator == null) {
+ return firstValue + fraction * deltaValue;
+ } else {
+ return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).floatValue();
+ }
+ }
+ if (fraction <= 0f) {
+ final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
+ final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(1);
+ float prevValue = prevKeyframe.getFloatValue();
+ float nextValue = nextKeyframe.getFloatValue();
+ float prevFraction = prevKeyframe.getFraction();
+ float nextFraction = nextKeyframe.getFraction();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
+ return mEvaluator == null ?
+ prevValue + fraction * (nextValue - prevValue) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ floatValue();
+ } else if (fraction >= 1f) {
+ final FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 2);
+ final FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(mNumKeyframes - 1);
+ float prevValue = prevKeyframe.getFloatValue();
+ float nextValue = nextKeyframe.getFloatValue();
+ float prevFraction = prevKeyframe.getFraction();
+ float nextFraction = nextKeyframe.getFraction();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
+ return mEvaluator == null ?
+ prevValue + fraction * (nextValue - prevValue) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ floatValue();
+ }
+ FloatKeyframe prevKeyframe = (FloatKeyframe) mKeyframes.get(0);
+ for (int i = 1; i < mNumKeyframes; ++i) {
+ FloatKeyframe nextKeyframe = (FloatKeyframe) mKeyframes.get(i);
+ if (fraction < nextKeyframe.getFraction()) {
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevKeyframe.getFraction()) /
+ (nextKeyframe.getFraction() - prevKeyframe.getFraction());
+ float prevValue = prevKeyframe.getFloatValue();
+ float nextValue = nextKeyframe.getFloatValue();
+ return mEvaluator == null ?
+ prevValue + fraction * (nextValue - prevValue) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ floatValue();
+ }
+ prevKeyframe = nextKeyframe;
+ }
+ // shouldn't get here
+ return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).floatValue();
+ }
+
+}
+
diff --git a/core/java/android/animation/IntKeyframeSet.java b/core/java/android/animation/IntKeyframeSet.java
new file mode 100644
index 0000000..14a4e3a
--- /dev/null
+++ b/core/java/android/animation/IntKeyframeSet.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2010 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.animation;
+
+import android.animation.Keyframe.IntKeyframe;
+
+import java.util.ArrayList;
+
+/**
+ * This class holds a collection of IntKeyframe objects and is called by ValueAnimator to calculate
+ * values between those keyframes for a given animation. The class internal to the animation
+ * package because it is an implementation detail of how Keyframes are stored and used.
+ *
+ * <p>This type-specific subclass of KeyframeSet, along with the other type-specific subclasses for
+ * float, long, and double, exists to speed up the getValue() method when there is no custom
+ * TypeEvaluator set for the animation, so that values can be calculated without autoboxing to the
+ * Object equivalents of these primitive types.</p>
+ */
+class IntKeyframeSet extends KeyframeSet {
+ private int firstValue;
+ private int lastValue;
+ private int deltaValue;
+ private boolean firstTime = true;
+
+ public IntKeyframeSet(IntKeyframe... keyframes) {
+ super(keyframes);
+ }
+
+ @Override
+ public Object getValue(float fraction) {
+ return getIntValue(fraction);
+ }
+
+ @Override
+ public IntKeyframeSet clone() {
+ ArrayList<Keyframe> keyframes = mKeyframes;
+ int numKeyframes = mKeyframes.size();
+ IntKeyframe[] newKeyframes = new IntKeyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ newKeyframes[i] = (IntKeyframe) keyframes.get(i).clone();
+ }
+ IntKeyframeSet newSet = new IntKeyframeSet(newKeyframes);
+ return newSet;
+ }
+
+ public int getIntValue(float fraction) {
+ if (mNumKeyframes == 2) {
+ if (firstTime) {
+ firstTime = false;
+ firstValue = ((IntKeyframe) mKeyframes.get(0)).getIntValue();
+ lastValue = ((IntKeyframe) mKeyframes.get(1)).getIntValue();
+ deltaValue = lastValue - firstValue;
+ }
+ if (mInterpolator != null) {
+ fraction = mInterpolator.getInterpolation(fraction);
+ }
+ if (mEvaluator == null) {
+ return firstValue + (int)(fraction * deltaValue);
+ } else {
+ return ((Number)mEvaluator.evaluate(fraction, firstValue, lastValue)).intValue();
+ }
+ }
+ if (fraction <= 0f) {
+ final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
+ final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(1);
+ int prevValue = prevKeyframe.getIntValue();
+ int nextValue = nextKeyframe.getIntValue();
+ float prevFraction = prevKeyframe.getFraction();
+ float nextFraction = nextKeyframe.getFraction();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
+ return mEvaluator == null ?
+ prevValue + (int)(fraction * (nextValue - prevValue)) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ intValue();
+ } else if (fraction >= 1f) {
+ final IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 2);
+ final IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(mNumKeyframes - 1);
+ int prevValue = prevKeyframe.getIntValue();
+ int nextValue = nextKeyframe.getIntValue();
+ float prevFraction = prevKeyframe.getFraction();
+ float nextFraction = nextKeyframe.getFraction();
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevFraction) / (nextFraction - prevFraction);
+ return mEvaluator == null ?
+ prevValue + (int)(fraction * (nextValue - prevValue)) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).intValue();
+ }
+ IntKeyframe prevKeyframe = (IntKeyframe) mKeyframes.get(0);
+ for (int i = 1; i < mNumKeyframes; ++i) {
+ IntKeyframe nextKeyframe = (IntKeyframe) mKeyframes.get(i);
+ if (fraction < nextKeyframe.getFraction()) {
+ final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
+ if (interpolator != null) {
+ fraction = interpolator.getInterpolation(fraction);
+ }
+ float intervalFraction = (fraction - prevKeyframe.getFraction()) /
+ (nextKeyframe.getFraction() - prevKeyframe.getFraction());
+ int prevValue = prevKeyframe.getIntValue();
+ int nextValue = nextKeyframe.getIntValue();
+ return mEvaluator == null ?
+ prevValue + (int)(fraction * (nextValue - prevValue)) :
+ ((Number)mEvaluator.evaluate(intervalFraction, prevValue, nextValue)).
+ intValue();
+ }
+ prevKeyframe = nextKeyframe;
+ }
+ // shouldn't get here
+ return ((Number)mKeyframes.get(mNumKeyframes - 1).getValue()).intValue();
+ }
+
+}
+
diff --git a/core/java/android/animation/Keyframe.java b/core/java/android/animation/Keyframe.java
index f9a4f3c..e98719a 100644
--- a/core/java/android/animation/Keyframe.java
+++ b/core/java/android/animation/Keyframe.java
@@ -23,23 +23,27 @@
* target object will animate between the value at the previous keyframe and the value at the
* next keyframe. Each keyframe also holds an optional {@link TimeInterpolator}
* object, which defines the time interpolation over the intervalue preceding the keyframe.
+ *
+ * <p>The Keyframe class itself is abstract. The type-specific factory methods will return
+ * a subclass of Keyframe specific to the type of value being stored. This is done to improve
+ * performance when dealing with the most common cases (e.g., <code>float</code> and
+ * <code>int</code> values). Other types will fall into a more general Keyframe class that
+ * treats its values as Objects. Unless your animation requires dealing with a custom type
+ * or a data structure that needs to be animated directly (and evaluated using an implementation
+ * of {@link TypeEvaluator}), you should stick to using float and int as animations using those
+ * types have lower runtime overhead than other types.</p>
*/
-public class Keyframe implements Cloneable {
+public abstract class Keyframe implements Cloneable {
/**
* The time at which mValue will hold true.
*/
- private float mFraction;
-
- /**
- * The value of the animation at the time mFraction.
- */
- private Object mValue;
+ float mFraction;
/**
* The type of the value in this Keyframe. This type is determined at construction time,
* based on the type of the <code>value</code> object passed into the constructor.
*/
- private Class mValueType;
+ Class mValueType;
/**
* The optional time interpolator for the interval preceding this keyframe. A null interpolator
@@ -48,22 +52,42 @@
private TimeInterpolator mInterpolator = null;
/**
- * Private constructor, called from the public constructors with the additional
- * <code>valueType</code> parameter.
+ * Flag to indicate whether this keyframe has a valid value. This flag is used when an
+ * animation first starts, to populate placeholder keyframes with real values derived
+ * from the target object.
+ */
+ boolean mHasValue = false;
+
+ /**
+ * Constructs a Keyframe object with the given time and value. The time defines the
+ * time, as a proportion of an overall animation's duration, at which the value will hold true
+ * for the animation. The value for the animation between keyframes will be calculated as
+ * an interpolation between the values at those keyframes.
*
* @param fraction The time, expressed as a value between 0 and 1, representing the fraction
* of time elapsed of the overall animation duration.
* @param value The value that the object will animate to as the animation time approaches
* the time in this keyframe, and the the value animated from as the time passes the time in
* this keyframe.
- * @param valueType The type of the <code>value</code> object. This is used by the
- * {@link #getValue()} functionm, which is queried by {@link ValueAnimator} to determine
- * the type of {@link TypeEvaluator} to use to interpolate between values.
*/
- private Keyframe(float fraction, Object value, Class valueType) {
- mFraction = fraction;
- mValue = value;
- mValueType = valueType;
+ public static Keyframe ofInt(float fraction, int value) {
+ return new IntKeyframe(fraction, value);
+ }
+
+ /**
+ * Constructs a Keyframe object with the given time. The value at this time will be derived
+ * from the target object when the animation first starts (note that this implies that keyframes
+ * with no initial value must be used as part of an {@link ObjectAnimator}).
+ * The time defines the
+ * time, as a proportion of an overall animation's duration, at which the value will hold true
+ * for the animation. The value for the animation between keyframes will be calculated as
+ * an interpolation between the values at those keyframes.
+ *
+ * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
+ * of time elapsed of the overall animation duration.
+ */
+ public static Keyframe ofInt(float fraction) {
+ return new IntKeyframe(fraction);
}
/**
@@ -78,12 +102,28 @@
* the time in this keyframe, and the the value animated from as the time passes the time in
* this keyframe.
*/
- public Keyframe(float fraction, Object value) {
- this(fraction, value, (value != null) ? value.getClass() : Object.class);
+ public static Keyframe ofFloat(float fraction, float value) {
+ return new FloatKeyframe(fraction, value);
}
/**
- * Constructs a Keyframe object with the given time and float value. The time defines the
+ * Constructs a Keyframe object with the given time. The value at this time will be derived
+ * from the target object when the animation first starts (note that this implies that keyframes
+ * with no initial value must be used as part of an {@link ObjectAnimator}).
+ * The time defines the
+ * time, as a proportion of an overall animation's duration, at which the value will hold true
+ * for the animation. The value for the animation between keyframes will be calculated as
+ * an interpolation between the values at those keyframes.
+ *
+ * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
+ * of time elapsed of the overall animation duration.
+ */
+ public static Keyframe ofFloat(float fraction) {
+ return new FloatKeyframe(fraction);
+ }
+
+ /**
+ * Constructs a Keyframe object with the given time and value. The time defines the
* time, as a proportion of an overall animation's duration, at which the value will hold true
* for the animation. The value for the animation between keyframes will be calculated as
* an interpolation between the values at those keyframes.
@@ -94,88 +134,35 @@
* the time in this keyframe, and the the value animated from as the time passes the time in
* this keyframe.
*/
- public Keyframe(float fraction, Float value) {
- this(fraction, value, Float.class);
+ public static Keyframe ofObject(float fraction, Object value) {
+ return new ObjectKeyframe(fraction, value);
}
/**
- * Constructs a Keyframe object with the given time and integer value. The time defines the
+ * Constructs a Keyframe object with the given time. The value at this time will be derived
+ * from the target object when the animation first starts (note that this implies that keyframes
+ * with no initial value must be used as part of an {@link ObjectAnimator}).
+ * The time defines the
* time, as a proportion of an overall animation's duration, at which the value will hold true
* for the animation. The value for the animation between keyframes will be calculated as
* an interpolation between the values at those keyframes.
*
* @param fraction The time, expressed as a value between 0 and 1, representing the fraction
* of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
*/
- public Keyframe(float fraction, Integer value) {
- this(fraction, value, Integer.class);
+ public static Keyframe ofObject(float fraction) {
+ return new ObjectKeyframe(fraction, null);
}
/**
- * Constructs a Keyframe object with the given time and double value. The time defines the
- * time, as a proportion of an overall animation's duration, at which the value will hold true
- * for the animation. The value for the animation between keyframes will be calculated as
- * an interpolation between the values at those keyframes.
+ * Indicates whether this keyframe has a valid value. This method is called internally when
+ * an {@link ObjectAnimator} first starts; keyframes without values are assigned values at
+ * that time by deriving the value for the property from the target object.
*
- * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
- * of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
+ * @return boolean Whether this object has a value assigned.
*/
- public Keyframe(float fraction, Double value) {
- this(fraction, value, Double.class);
- }
-
- /**
- * Constructs a Keyframe object with the given time and integer value. The time defines the
- * time, as a proportion of an overall animation's duration, at which the value will hold true
- * for the animation. The value for the animation between keyframes will be calculated as
- * an interpolation between the values at those keyframes.
- *
- * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
- * of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
- */
- public Keyframe(float fraction, int value) {
- this(fraction, value, int.class);
- }
-
- /**
- * Constructs a Keyframe object with the given time and float value. The time defines the
- * time, as a proportion of an overall animation's duration, at which the value will hold true
- * for the animation. The value for the animation between keyframes will be calculated as
- * an interpolation between the values at those keyframes.
- *
- * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
- * of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
- */
- public Keyframe(float fraction, float value) {
- this(fraction, value, float.class);
- }
-
- /**
- * Constructs a Keyframe object with the given time and double value. The time defines the
- * time, as a proportion of an overall animation's duration, at which the value will hold true
- * for the animation. The value for the animation between keyframes will be calculated as
- * an interpolation between the values at those keyframes.
- *
- * @param fraction The time, expressed as a value between 0 and 1, representing the fraction
- * of time elapsed of the overall animation duration.
- * @param value The value that the object will animate to as the animation time approaches
- * the time in this keyframe, and the the value animated from as the time passes the time in
- * this keyframe.
- */
- public Keyframe(float fraction, double value) {
- this(fraction, value, double.class);
+ public boolean hasValue() {
+ return mHasValue;
}
/**
@@ -183,18 +170,14 @@
*
* @return The value for this Keyframe.
*/
- public Object getValue() {
- return mValue;
- }
+ public abstract Object getValue();
/**
* Sets the value for this Keyframe.
*
* @param value value for this Keyframe.
*/
- public void setValue(Object value) {
- mValue = value;
- }
+ public abstract void setValue(Object value);
/**
* Gets the time for this keyframe, as a fraction of the overall animation duration.
@@ -248,9 +231,128 @@
}
@Override
- public Keyframe clone() {
- Keyframe kfClone = new Keyframe(mFraction, mValue, mValueType);
- kfClone.setInterpolator(mInterpolator);
- return kfClone;
+ public abstract Keyframe clone();
+
+ /**
+ * This internal subclass is used for all types which are not int or float.
+ */
+ static class ObjectKeyframe extends Keyframe {
+
+ /**
+ * The value of the animation at the time mFraction.
+ */
+ Object mValue;
+
+ ObjectKeyframe(float fraction, Object value) {
+ mFraction = fraction;
+ mValue = value;
+ mHasValue = (value != null);
+ mValueType = mHasValue ? value.getClass() : Object.class;
+ }
+
+ public Object getValue() {
+ return mValue;
+ }
+
+ public void setValue(Object value) {
+ mValue = value;
+ mHasValue = (value != null);
+ }
+
+ @Override
+ public ObjectKeyframe clone() {
+ ObjectKeyframe kfClone = new ObjectKeyframe(getFraction(), mValue);
+ kfClone.setInterpolator(getInterpolator());
+ return kfClone;
+ }
+ }
+
+ /**
+ * Internal subclass used when the keyframe value is of type int.
+ */
+ static class IntKeyframe extends Keyframe {
+
+ /**
+ * The value of the animation at the time mFraction.
+ */
+ int mValue;
+
+ IntKeyframe(float fraction, int value) {
+ mFraction = fraction;
+ mValue = value;
+ mValueType = int.class;
+ mHasValue = true;
+ }
+
+ IntKeyframe(float fraction) {
+ mFraction = fraction;
+ mValueType = int.class;
+ }
+
+ public int getIntValue() {
+ return mValue;
+ }
+
+ public Object getValue() {
+ return mValue;
+ }
+
+ public void setValue(Object value) {
+ if (value != null && value.getClass() == Integer.class) {
+ mValue = ((Integer)value).intValue();
+ mHasValue = true;
+ }
+ }
+
+ @Override
+ public IntKeyframe clone() {
+ IntKeyframe kfClone = new IntKeyframe(getFraction(), mValue);
+ kfClone.setInterpolator(getInterpolator());
+ return kfClone;
+ }
+ }
+
+ /**
+ * Internal subclass used when the keyframe value is of type float.
+ */
+ static class FloatKeyframe extends Keyframe {
+ /**
+ * The value of the animation at the time mFraction.
+ */
+ float mValue;
+
+ FloatKeyframe(float fraction, float value) {
+ mFraction = fraction;
+ mValue = value;
+ mValueType = float.class;
+ mHasValue = true;
+ }
+
+ FloatKeyframe(float fraction) {
+ mFraction = fraction;
+ mValueType = float.class;
+ }
+
+ public float getFloatValue() {
+ return mValue;
+ }
+
+ public Object getValue() {
+ return mValue;
+ }
+
+ public void setValue(Object value) {
+ if (value != null && value.getClass() == Float.class) {
+ mValue = ((Float)value).floatValue();
+ mHasValue = true;
+ }
+ }
+
+ @Override
+ public FloatKeyframe clone() {
+ FloatKeyframe kfClone = new FloatKeyframe(getFraction(), mValue);
+ kfClone.setInterpolator(getInterpolator());
+ return kfClone;
+ }
}
}
diff --git a/core/java/android/animation/KeyframeSet.java b/core/java/android/animation/KeyframeSet.java
index 2242462..fa61b71 100644
--- a/core/java/android/animation/KeyframeSet.java
+++ b/core/java/android/animation/KeyframeSet.java
@@ -18,6 +18,9 @@
import java.util.ArrayList;
import java.util.Arrays;
+import android.animation.Keyframe.IntKeyframe;
+import android.animation.Keyframe.FloatKeyframe;
+import android.animation.Keyframe.ObjectKeyframe;
/**
* This class holds a collection of Keyframe objects and is called by ValueAnimator to calculate
@@ -26,12 +29,14 @@
*/
class KeyframeSet {
- private int mNumKeyframes;
+ int mNumKeyframes;
Keyframe mFirstKeyframe;
Keyframe mLastKeyframe;
TimeInterpolator mInterpolator; // only used in the 2-keyframe case
ArrayList<Keyframe> mKeyframes; // only used when there are not 2 keyframes
+ TypeEvaluator mEvaluator;
+
public KeyframeSet(Keyframe... keyframes) {
mNumKeyframes = keyframes.length;
@@ -44,80 +49,106 @@
public static KeyframeSet ofInt(int... values) {
int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
+ IntKeyframe keyframes[] = new IntKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
+ keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f);
+ keyframes[1] = (IntKeyframe) Keyframe.ofInt(1f, values[0]);
} else {
- keyframes[0] = new Keyframe(0f, values[0]);
+ keyframes[0] = (IntKeyframe) Keyframe.ofInt(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ keyframes[i] = (IntKeyframe) Keyframe.ofInt((float) i / (numKeyframes - 1), values[i]);
}
}
- return new KeyframeSet(keyframes);
+ return new IntKeyframeSet(keyframes);
}
public static KeyframeSet ofFloat(float... values) {
int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
+ FloatKeyframe keyframes[] = new FloatKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
+ keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f);
+ keyframes[1] = (FloatKeyframe) Keyframe.ofFloat(1f, values[0]);
} else {
- keyframes[0] = new Keyframe(0f, values[0]);
+ keyframes[0] = (FloatKeyframe) Keyframe.ofFloat(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ keyframes[i] = (FloatKeyframe) Keyframe.ofFloat((float) i / (numKeyframes - 1), values[i]);
}
}
- return new KeyframeSet(keyframes);
+ return new FloatKeyframeSet(keyframes);
}
- public static KeyframeSet ofDouble(double... values) {
- int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
- if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
- } else {
- keyframes[0] = new Keyframe(0f, values[0]);
- for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ public static KeyframeSet ofKeyframe(Keyframe... keyframes) {
+ // if all keyframes of same primitive type, create the appropriate KeyframeSet
+ int numKeyframes = keyframes.length;
+ boolean hasFloat = false;
+ boolean hasInt = false;
+ boolean hasOther = false;
+ for (int i = 0; i < numKeyframes; ++i) {
+ if (keyframes[i] instanceof FloatKeyframe) {
+ hasFloat = true;
+ } else if (keyframes[i] instanceof IntKeyframe) {
+ hasInt = true;
+ } else {
+ hasOther = true;
}
}
- return new KeyframeSet(keyframes);
- }
-
- public static KeyframeSet ofLong(long... values) {
- int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
- if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
- } else {
- keyframes[0] = new Keyframe(0f, values[0]);
- for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ if (hasFloat && !hasInt && !hasOther) {
+ FloatKeyframe floatKeyframes[] = new FloatKeyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ floatKeyframes[i] = (FloatKeyframe) keyframes[i];
}
+ return new FloatKeyframeSet(floatKeyframes);
+ } else if (hasInt && !hasFloat && !hasOther) {
+ IntKeyframe intKeyframes[] = new IntKeyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ intKeyframes[i] = (IntKeyframe) keyframes[i];
+ }
+ return new IntKeyframeSet(intKeyframes);
+ } else {
+ return new KeyframeSet(keyframes);
}
- return new KeyframeSet(keyframes);
}
public static KeyframeSet ofObject(Object... values) {
int numKeyframes = values.length;
- Keyframe keyframes[] = new Keyframe[Math.max(numKeyframes,2)];
+ ObjectKeyframe keyframes[] = new ObjectKeyframe[Math.max(numKeyframes,2)];
if (numKeyframes == 1) {
- keyframes[0] = new Keyframe(0f, (Object) null);
- keyframes[1] = new Keyframe(1f, values[0]);
+ keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f);
+ keyframes[1] = (ObjectKeyframe) Keyframe.ofObject(1f, values[0]);
} else {
- keyframes[0] = new Keyframe(0f, values[0]);
+ keyframes[0] = (ObjectKeyframe) Keyframe.ofObject(0f, values[0]);
for (int i = 1; i < numKeyframes; ++i) {
- keyframes[i] = new Keyframe((float) i / (numKeyframes - 1), values[i]);
+ keyframes[i] = (ObjectKeyframe) Keyframe.ofObject((float) i / (numKeyframes - 1), values[i]);
}
}
return new KeyframeSet(keyframes);
}
/**
+ * Sets the TypeEvaluator to be used when calculating animated values. This object
+ * is required only for KeyframeSets that are not either IntKeyframeSet or FloatKeyframeSet,
+ * both of which assume their own evaluator to speed up calculations with those primitive
+ * types.
+ *
+ * @param evaluator The TypeEvaluator to be used to calculate animated values.
+ */
+ public void setEvaluator(TypeEvaluator evaluator) {
+ mEvaluator = evaluator;
+ }
+
+ @Override
+ public KeyframeSet clone() {
+ ArrayList<Keyframe> keyframes = mKeyframes;
+ int numKeyframes = mKeyframes.size();
+ Keyframe[] newKeyframes = new Keyframe[numKeyframes];
+ for (int i = 0; i < numKeyframes; ++i) {
+ newKeyframes[i] = keyframes.get(i).clone();
+ }
+ KeyframeSet newSet = new KeyframeSet(newKeyframes);
+ return newSet;
+ }
+
+ /**
* Gets the animated value, given the elapsed fraction of the animation (interpolated by the
* animation's interpolator) and the evaluator used to calculate in-between values. This
* function maps the input fraction to the appropriate keyframe interval and a fraction
@@ -127,20 +158,18 @@
* just using the two keyframes at the appropriate end when the value is outside those bounds.
*
* @param fraction The elapsed fraction of the animation
- * @param evaluator The type evaluator to use when calculating the interpolated values.
* @return The animated value.
*/
- public Object getValue(float fraction, TypeEvaluator evaluator) {
+ public Object getValue(float fraction) {
// Special-case optimization for the common case of only two keyframes
if (mNumKeyframes == 2) {
if (mInterpolator != null) {
fraction = mInterpolator.getInterpolation(fraction);
}
- return evaluator.evaluate(fraction, mFirstKeyframe.getValue(),
+ return mEvaluator.evaluate(fraction, mFirstKeyframe.getValue(),
mLastKeyframe.getValue());
}
-
if (fraction <= 0f) {
final Keyframe nextKeyframe = mKeyframes.get(1);
final TimeInterpolator interpolator = nextKeyframe.getInterpolator();
@@ -150,7 +179,7 @@
final float prevFraction = mFirstKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(nextKeyframe.getFraction() - prevFraction);
- return evaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(),
+ return mEvaluator.evaluate(intervalFraction, mFirstKeyframe.getValue(),
nextKeyframe.getValue());
} else if (fraction >= 1f) {
final Keyframe prevKeyframe = mKeyframes.get(mNumKeyframes - 2);
@@ -161,7 +190,7 @@
final float prevFraction = prevKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(mLastKeyframe.getFraction() - prevFraction);
- return evaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
+ return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
mLastKeyframe.getValue());
}
Keyframe prevKeyframe = mFirstKeyframe;
@@ -175,7 +204,7 @@
final float prevFraction = prevKeyframe.getFraction();
float intervalFraction = (fraction - prevFraction) /
(nextKeyframe.getFraction() - prevFraction);
- return evaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
+ return mEvaluator.evaluate(intervalFraction, prevKeyframe.getValue(),
nextKeyframe.getValue());
}
prevKeyframe = nextKeyframe;
diff --git a/core/java/android/animation/ObjectAnimator.java b/core/java/android/animation/ObjectAnimator.java
index 5b8c91d..7c2e70d 100644
--- a/core/java/android/animation/ObjectAnimator.java
+++ b/core/java/android/animation/ObjectAnimator.java
@@ -26,6 +26,9 @@
* as well as the name of the property that will be animated. Appropriate set/get functions
* are then determined internally and the animation will call these functions as necessary to
* animate the property.
+ *
+ * @see #setPropertyName(String)
+ *
*/
public final class ObjectAnimator extends ValueAnimator {
@@ -42,6 +45,13 @@
* <code>valueFrom</code> or <code>valueTo</code> is null, then a getter function will
* also be derived and called.
*
+ * <p>For best performance of the mechanism that calls the setter function determined by the
+ * name of the property being animated, use <code>float</code> or <code>int</code> typed values,
+ * and make the setter function for those properties have a <code>void</code> return value. This
+ * will cause the code to take an optimized path for these constrained circumstances. Other
+ * property types and return types will work, but will have more overhead in processing
+ * the requests due to normal reflection mechanisms.</p>
+ *
* <p>Note that the setter function derived from this property name
* must take the same parameter type as the
* <code>valueFrom</code> and <code>valueTo</code> properties, otherwise the call to
@@ -175,48 +185,6 @@
}
/**
- * Constructs and returns an ObjectAnimator that animates between long values. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * @param target The object whose property is to be animated. This object should
- * have a public method on it called <code>setName()</code>, where <code>name</code> is
- * the value of the <code>propertyName</code> parameter.
- * @param propertyName The name of the property being animated.
- * @param values A set of values that the animation will animate between over time.
- * @return A ValueAnimator object that is set up to animate between the given values.
- */
- public static ObjectAnimator ofLong(Object target, String propertyName, long... values) {
- ObjectAnimator anim = new ObjectAnimator(target, propertyName);
- anim.setLongValues(values);
- return anim;
- }
-
- /**
- * Constructs and returns an ObjectAnimator that animates between double values. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * @param target The object whose property is to be animated. This object should
- * have a public method on it called <code>setName()</code>, where <code>name</code> is
- * the value of the <code>propertyName</code> parameter.
- * @param propertyName The name of the property being animated.
- * @param values A set of values that the animation will animate between over time.
- * @return A ValueAnimator object that is set up to animate between the given values.
- */
- public static ObjectAnimator ofDouble(Object target, String propertyName, double... values) {
- ObjectAnimator anim = new ObjectAnimator(target, propertyName);
- anim.setDoubleValues(values);
- return anim;
- }
-
- /**
* A constructor that takes <code>PropertyValueHolder</code> values. This constructor should
* be used when animating several properties at once with the same ObjectAnimator, since
* PropertyValuesHolder allows you to associate a set of animation values with a property
@@ -287,28 +255,6 @@
}
@Override
- public void setDoubleValues(double... values) {
- if (mValues == null || mValues.length == 0) {
- // No values yet - this animator is being constructed piecemeal. Init the values with
- // whatever the current propertyName is
- setValues(PropertyValuesHolder.ofDouble(mPropertyName, values));
- } else {
- super.setDoubleValues(values);
- }
- }
-
- @Override
- public void setLongValues(long... values) {
- if (mValues == null || mValues.length == 0) {
- // No values yet - this animator is being constructed piecemeal. Init the values with
- // whatever the current propertyName is
- setValues(PropertyValuesHolder.ofLong(mPropertyName, values));
- } else {
- super.setLongValues(values);
- }
- }
-
- @Override
public void setObjectValues(Object... values) {
if (mValues == null || mValues.length == 0) {
// No values yet - this animator is being constructed piecemeal. Init the values with
diff --git a/core/java/android/animation/PropertyValuesHolder.java b/core/java/android/animation/PropertyValuesHolder.java
index 0f759f1..97aa5a1 100644
--- a/core/java/android/animation/PropertyValuesHolder.java
+++ b/core/java/android/animation/PropertyValuesHolder.java
@@ -20,7 +20,6 @@
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@@ -37,7 +36,7 @@
* unless this object is being used with ObjectAnimator. But this is the name by which
* aniamted values are looked up with getAnimatedValue(String) in ValueAnimator.
*/
- private String mPropertyName;
+ String mPropertyName;
/**
* The setter function, if needed. ObjectAnimator hands off this functionality to
@@ -45,7 +44,7 @@
* property can be manually set via setSetter(). Otherwise, it is automatically
* derived when the animation starts in setupSetterAndGetter() if using ObjectAnimator.
*/
- private Method mSetter = null;
+ Method mSetter = null;
/**
* The getter function, if needed. ObjectAnimator hands off this functionality to
@@ -60,12 +59,12 @@
* The type of values supplied. This information is used both in deriving the setter/getter
* functions and in deriving the type of TypeEvaluator.
*/
- private Class mValueType;
+ Class mValueType;
/**
* The set of keyframes (time/value pairs) that define this animation.
*/
- private KeyframeSet mKeyframeSet = null;
+ KeyframeSet mKeyframeSet = null;
// type evaluators for the three primitive types handled by this implementation
@@ -97,10 +96,10 @@
// This lock is used to ensure that only one thread is accessing the property maps
// at a time.
- private ReentrantReadWriteLock propertyMapLock = new ReentrantReadWriteLock();
+ final ReentrantReadWriteLock mPropertyMapLock = new ReentrantReadWriteLock();
// Used to pass single value to varargs parameter in setter invocation
- private Object[] mTmpValueArray = new Object[1];
+ final Object[] mTmpValueArray = new Object[1];
/**
* The type evaluator used to calculate the animated values. This evaluator is determined
@@ -133,8 +132,7 @@
* @return PropertyValuesHolder The constructed PropertyValuesHolder object.
*/
public static PropertyValuesHolder ofInt(String propertyName, int... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setIntValues(values);
+ PropertyValuesHolder pvh = new IntPropertyValuesHolder(propertyName, values);
return pvh;
}
@@ -146,34 +144,7 @@
* @return PropertyValuesHolder The constructed PropertyValuesHolder object.
*/
public static PropertyValuesHolder ofFloat(String propertyName, float... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setFloatValues(values);
- return pvh;
- }
-
- /**
- * Constructs and returns a PropertyValuesHolder with a given property name and
- * set of double values.
- * @param propertyName The name of the property being animated.
- * @param values The values that the named property will animate between.
- * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
- */
- public static PropertyValuesHolder ofDouble(String propertyName, double... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setDoubleValues(values);
- return pvh;
- }
-
- /**
- * Constructs and returns a PropertyValuesHolder with a given property name and
- * set of long values.
- * @param propertyName The name of the property being animated.
- * @param values The values that the named property will animate between.
- * @return PropertyValuesHolder The constructed PropertyValuesHolder object.
- */
- public static PropertyValuesHolder ofLong(String propertyName, long... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setLongValues(values);
+ PropertyValuesHolder pvh = new FloatPropertyValuesHolder(propertyName, values);
return pvh;
}
@@ -218,9 +189,18 @@
* @param values The set of values to animate between.
*/
public static PropertyValuesHolder ofKeyframe(String propertyName, Keyframe... values) {
- PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
- pvh.setKeyframes(values);
- return pvh;
+ KeyframeSet keyframeSet = KeyframeSet.ofKeyframe(values);
+ if (keyframeSet instanceof IntKeyframeSet) {
+ return new IntPropertyValuesHolder(propertyName, (IntKeyframeSet) keyframeSet);
+ } else if (keyframeSet instanceof FloatKeyframeSet) {
+ return new FloatPropertyValuesHolder(propertyName, (FloatKeyframeSet) keyframeSet);
+ }
+ else {
+ PropertyValuesHolder pvh = new PropertyValuesHolder(propertyName);
+ pvh.mKeyframeSet = keyframeSet;
+ pvh.mValueType = ((Keyframe)values[0]).getType();
+ return pvh;
+ }
}
/**
@@ -262,44 +242,6 @@
}
/**
- * Set the animated values for this object to this set of doubles.
- * If there is only one value, it is assumed to be the end value of an animation,
- * and an initial value will be derived, if possible, by calling a getter function
- * on the object. Also, if any value is null, the value will be filled in when the animation
- * starts in the same way. This mechanism of automatically getting null values only works
- * if the PropertyValuesHolder object is used in conjunction
- * {@link ObjectAnimator}, and with a getter function either
- * derived automatically from <code>propertyName</code> or set explicitly via
- * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
- * no way of determining what the value should be.
- *
- * @param values One or more values that the animation will animate between.
- */
- public void setDoubleValues(double... values) {
- mValueType = double.class;
- mKeyframeSet = KeyframeSet.ofDouble(values);
- }
-
- /**
- * Set the animated values for this object to this set of longs.
- * If there is only one value, it is assumed to be the end value of an animation,
- * and an initial value will be derived, if possible, by calling a getter function
- * on the object. Also, if any value is null, the value will be filled in when the animation
- * starts in the same way. This mechanism of automatically getting null values only works
- * if the PropertyValuesHolder object is used in conjunction
- * {@link ObjectAnimator}, and with a getter function either
- * derived automatically from <code>propertyName</code> or set explicitly via
- * {@link #setGetter(java.lang.reflect.Method)}, since otherwise PropertyValuesHolder has
- * no way of determining what the value should be.
- *
- * @param values One or more values that the animation will animate between.
- */
- public void setLongValues(long... values) {
- mValueType = long.class;
- mKeyframeSet = KeyframeSet.ofLong(values);
- }
-
- /**
* Set the animated values for this object to this set of Keyframes.
*
* @param values One or more values that the animation will animate between.
@@ -351,10 +293,7 @@
private Method getPropertyFunction(Class targetClass, String prefix, Class valueType) {
// TODO: faster implementation...
Method returnVal = null;
- String firstLetter = mPropertyName.substring(0, 1);
- String theRest = mPropertyName.substring(1);
- firstLetter = firstLetter.toUpperCase();
- String methodName = prefix + firstLetter + theRest;
+ String methodName = getMethodName(prefix, mPropertyName);
Class args[] = null;
if (valueType == null) {
try {
@@ -416,7 +355,7 @@
// another thread putting something in there after we've checked it
// but before we've added an entry to it
// TODO: can we store the setter/getter per Class instead of per Object?
- propertyMapLock.writeLock().lock();
+ mPropertyMapLock.writeLock().lock();
HashMap<String, Method> propertyMap = propertyMapMap.get(targetClass);
if (propertyMap != null) {
setterOrGetter = propertyMap.get(mPropertyName);
@@ -430,7 +369,7 @@
propertyMap.put(mPropertyName, setterOrGetter);
}
} finally {
- propertyMapLock.writeLock().unlock();
+ mPropertyMapLock.writeLock().unlock();
}
return setterOrGetter;
}
@@ -439,7 +378,7 @@
* Utility function to get the setter from targetClass
* @param targetClass The Class on which the requested method should exist.
*/
- private void setupSetter(Class targetClass) {
+ void setupSetter(Class targetClass) {
mSetter = setupSetterOrGetter(targetClass, sSetterPropertyMap, "set", mValueType);
}
@@ -466,7 +405,7 @@
setupSetter(targetClass);
}
for (Keyframe kf : mKeyframeSet.mKeyframes) {
- if (kf.getValue() == null) {
+ if (!kf.hasValue()) {
if (mGetter == null) {
setupGetter(targetClass);
}
@@ -528,14 +467,18 @@
@Override
public PropertyValuesHolder clone() {
- ArrayList<Keyframe> keyframes = mKeyframeSet.mKeyframes;
- int numKeyframes = mKeyframeSet.mKeyframes.size();
- Keyframe[] newKeyframes = new Keyframe[numKeyframes];
- for (int i = 0; i < numKeyframes; ++i) {
- newKeyframes[i] = keyframes.get(i).clone();
+ try {
+ PropertyValuesHolder newPVH = (PropertyValuesHolder) super.clone();
+ newPVH.mPropertyName = mPropertyName;
+ newPVH.mKeyframeSet = mKeyframeSet.clone();
+ newPVH.mEvaluator = mEvaluator;
+ return newPVH;
+ } catch (CloneNotSupportedException e) {
+ // won't reach here
+ return null;
}
- return PropertyValuesHolder.ofKeyframe(mPropertyName, newKeyframes);
}
+
/**
* Internal function to set the value on the target object, using the setter set up
* earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
@@ -546,7 +489,7 @@
void setAnimatedValue(Object target) {
if (mSetter != null) {
try {
- mTmpValueArray[0] = mAnimatedValue;
+ mTmpValueArray[0] = getAnimatedValue();
mSetter.invoke(target, mTmpValueArray);
} catch (InvocationTargetException e) {
Log.e("PropertyValuesHolder", e.toString());
@@ -562,9 +505,16 @@
*/
void init() {
if (mEvaluator == null) {
- mEvaluator = (mValueType == int.class || mValueType == Integer.class) ? sIntEvaluator :
- (mValueType == double.class || mValueType == Double.class) ? sDoubleEvaluator :
- sFloatEvaluator;
+ // We already handle int, float, long, double automatically, but not their Object
+ // equivalents
+ mEvaluator = (mValueType == Integer.class) ? sIntEvaluator :
+ (mValueType == Float.class) ? sFloatEvaluator :
+ null;
+ }
+ if (mEvaluator != null) {
+ // KeyframeSet knows how to evaluate the common types - only give it a custom
+ // evaulator if one has been set on this class
+ mKeyframeSet.setEvaluator(mEvaluator);
}
}
@@ -578,8 +528,9 @@
* and Integer) are correctly interpolated; all other types require setting a TypeEvaluator.
* @param evaluator
*/
- public void setEvaluator(TypeEvaluator evaluator) {
+ public void setEvaluator(TypeEvaluator evaluator) {
mEvaluator = evaluator;
+ mKeyframeSet.setEvaluator(evaluator);
}
/**
@@ -587,11 +538,9 @@
* this PropertyValuesHolder object. This function is called by ValueAnimator.animateValue().
*
* @param fraction The elapsed, interpolated fraction of the animation.
- * @return The calculated value at this point in the animation.
*/
- Object calculateValue(float fraction) {
- mAnimatedValue = mKeyframeSet.getValue(fraction, mEvaluator);
- return mAnimatedValue;
+ void calculateValue(float fraction) {
+ mAnimatedValue = mKeyframeSet.getValue(fraction);
}
/**
@@ -694,4 +643,238 @@
Object getAnimatedValue() {
return mAnimatedValue;
}
+
+ /**
+ * Utility method to derive a setter/getter method name from a property name, where the
+ * prefix is typically "set" or "get" and the first letter of the property name is
+ * capitalized.
+ *
+ * @param prefix The precursor to the method name, before the property name begins, typically
+ * "set" or "get".
+ * @param propertyName The name of the property that represents the bulk of the method name
+ * after the prefix. The first letter of this word will be capitalized in the resulting
+ * method name.
+ * @return String the property name converted to a method name according to the conventions
+ * specified above.
+ */
+ static String getMethodName(String prefix, String propertyName) {
+ char firstLetter = propertyName.charAt(0);
+ String theRest = propertyName.substring(1);
+ firstLetter = Character.toUpperCase(firstLetter);
+ return prefix + firstLetter + theRest;
+ }
+
+ static class IntPropertyValuesHolder extends PropertyValuesHolder {
+
+ private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap =
+ new HashMap<Class, HashMap<String, Integer>>();
+ int mJniSetter;
+
+ IntKeyframeSet mIntKeyframeSet;
+ int mIntAnimatedValue;
+
+ public IntPropertyValuesHolder(String propertyName, IntKeyframeSet keyframeSet) {
+ super(propertyName);
+ mValueType = int.class;
+ mKeyframeSet = keyframeSet;
+ mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
+ }
+
+ public IntPropertyValuesHolder(String propertyName, int... values) {
+ super(propertyName);
+ setIntValues(values);
+ }
+
+ @Override
+ public void setIntValues(int... values) {
+ super.setIntValues(values);
+ mIntKeyframeSet = (IntKeyframeSet) mKeyframeSet;
+ }
+
+ @Override
+ void calculateValue(float fraction) {
+ mIntAnimatedValue = mIntKeyframeSet.getIntValue(fraction);
+ }
+
+ @Override
+ Object getAnimatedValue() {
+ return mIntAnimatedValue;
+ }
+
+ @Override
+ public IntPropertyValuesHolder clone() {
+ IntPropertyValuesHolder newPVH = (IntPropertyValuesHolder) super.clone();
+ newPVH.mIntKeyframeSet = (IntKeyframeSet) newPVH.mKeyframeSet;
+ return newPVH;
+ }
+
+ /**
+ * Internal function to set the value on the target object, using the setter set up
+ * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+ * to handle turning the value calculated by ValueAnimator into a value set on the object
+ * according to the name of the property.
+ * @param target The target object on which the value is set
+ */
+ @Override
+ void setAnimatedValue(Object target) {
+ if (mJniSetter != 0) {
+ nCallIntMethod(target, mJniSetter, mIntAnimatedValue);
+ return;
+ }
+ if (mSetter != null) {
+ try {
+ mTmpValueArray[0] = mIntAnimatedValue;
+ mSetter.invoke(target, mTmpValueArray);
+ } catch (InvocationTargetException e) {
+ Log.e("PropertyValuesHolder", e.toString());
+ } catch (IllegalAccessException e) {
+ Log.e("PropertyValuesHolder", e.toString());
+ }
+ }
+ }
+
+ @Override
+ void setupSetter(Class targetClass) {
+ // Check new static hashmap<propName, int> for setter method
+ try {
+ mPropertyMapLock.writeLock().lock();
+ HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass);
+ if (propertyMap != null) {
+ Integer mJniSetterInteger = propertyMap.get(mPropertyName);
+ if (mJniSetterInteger != null) {
+ mJniSetter = mJniSetterInteger;
+ }
+ }
+ if (mJniSetter == 0) {
+ String methodName = getMethodName("set", mPropertyName);
+ mJniSetter = nGetIntMethod(targetClass, methodName);
+ if (mJniSetter != 0) {
+ if (propertyMap == null) {
+ propertyMap = new HashMap<String, Integer>();
+ sJNISetterPropertyMap.put(targetClass, propertyMap);
+ }
+ propertyMap.put(mPropertyName, mJniSetter);
+ }
+ }
+ } catch (NoSuchMethodError e) {
+ // System.out.println("Can't find native method using JNI, use reflection" + e);
+ } finally {
+ mPropertyMapLock.writeLock().unlock();
+ }
+ if (mJniSetter == 0) {
+ // Couldn't find method through fast JNI approach - just use reflection
+ super.setupSetter(targetClass);
+ }
+ }
+ }
+
+ static class FloatPropertyValuesHolder extends PropertyValuesHolder {
+
+ private static final HashMap<Class, HashMap<String, Integer>> sJNISetterPropertyMap =
+ new HashMap<Class, HashMap<String, Integer>>();
+ int mJniSetter;
+
+ FloatKeyframeSet mFloatKeyframeSet;
+ float mFloatAnimatedValue;
+
+ public FloatPropertyValuesHolder(String propertyName, FloatKeyframeSet keyframeSet) {
+ super(propertyName);
+ mValueType = float.class;
+ mKeyframeSet = keyframeSet;
+ mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
+ }
+
+ public FloatPropertyValuesHolder(String propertyName, float... values) {
+ super(propertyName);
+ setFloatValues(values);
+ }
+
+ @Override
+ public void setFloatValues(float... values) {
+ super.setFloatValues(values);
+ mFloatKeyframeSet = (FloatKeyframeSet) mKeyframeSet;
+ }
+
+ @Override
+ void calculateValue(float fraction) {
+ mFloatAnimatedValue = mFloatKeyframeSet.getFloatValue(fraction);
+ }
+
+ @Override
+ Object getAnimatedValue() {
+ return mFloatAnimatedValue;
+ }
+
+ @Override
+ public FloatPropertyValuesHolder clone() {
+ FloatPropertyValuesHolder newPVH = (FloatPropertyValuesHolder) super.clone();
+ newPVH.mFloatKeyframeSet = (FloatKeyframeSet) newPVH.mKeyframeSet;
+ return newPVH;
+ }
+
+ /**
+ * Internal function to set the value on the target object, using the setter set up
+ * earlier on this PropertyValuesHolder object. This function is called by ObjectAnimator
+ * to handle turning the value calculated by ValueAnimator into a value set on the object
+ * according to the name of the property.
+ * @param target The target object on which the value is set
+ */
+ @Override
+ void setAnimatedValue(Object target) {
+ if (mJniSetter != 0) {
+ nCallFloatMethod(target, mJniSetter, mFloatAnimatedValue);
+ return;
+ }
+ if (mSetter != null) {
+ try {
+ mTmpValueArray[0] = mFloatAnimatedValue;
+ mSetter.invoke(target, mTmpValueArray);
+ } catch (InvocationTargetException e) {
+ Log.e("PropertyValuesHolder", e.toString());
+ } catch (IllegalAccessException e) {
+ Log.e("PropertyValuesHolder", e.toString());
+ }
+ }
+ }
+
+ @Override
+ void setupSetter(Class targetClass) {
+ // Check new static hashmap<propName, int> for setter method
+ try {
+ mPropertyMapLock.writeLock().lock();
+ HashMap<String, Integer> propertyMap = sJNISetterPropertyMap.get(targetClass);
+ if (propertyMap != null) {
+ Integer mJniSetterInteger = propertyMap.get(mPropertyName);
+ if (mJniSetterInteger != null) {
+ mJniSetter = mJniSetterInteger;
+ }
+ }
+ if (mJniSetter == 0) {
+ String methodName = getMethodName("set", mPropertyName);
+ mJniSetter = nGetFloatMethod(targetClass, methodName);
+ if (mJniSetter != 0) {
+ if (propertyMap == null) {
+ propertyMap = new HashMap<String, Integer>();
+ sJNISetterPropertyMap.put(targetClass, propertyMap);
+ }
+ propertyMap.put(mPropertyName, mJniSetter);
+ }
+ }
+ } catch (NoSuchMethodError e) {
+ // System.out.println("Can't find native method using JNI, use reflection" + e);
+ } finally {
+ mPropertyMapLock.writeLock().unlock();
+ }
+ if (mJniSetter == 0) {
+ // Couldn't find method through fast JNI approach - just use reflection
+ super.setupSetter(targetClass);
+ }
+ }
+
+ }
+
+ native static private int nGetIntMethod(Class targetClass, String methodName);
+ native static private int nGetFloatMethod(Class targetClass, String methodName);
+ native static private void nCallIntMethod(Object target, int methodID, int arg);
+ native static private void nCallFloatMethod(Object target, int methodID, float arg);
}
\ No newline at end of file
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index a0b70b5..b021e75 100755
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -297,40 +297,6 @@
}
/**
- * Constructs and returns a ValueAnimator that animates between double values. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * @param values A set of values that the animation will animate between over time.
- * @return A ValueAnimator object that is set up to animate between the given values.
- */
- public static ValueAnimator ofDouble(double... values) {
- ValueAnimator anim = new ValueAnimator();
- anim.setDoubleValues(values);
- return anim;
- }
-
- /**
- * Constructs and returns a ValueAnimator that animates between long values. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * @param values A set of values that the animation will animate between over time.
- * @return A ValueAnimator object that is set up to animate between the given values.
- */
- public static ValueAnimator ofLong(long... values) {
- ValueAnimator anim = new ValueAnimator();
- anim.setLongValues(values);
- return anim;
- }
-
- /**
* Constructs and returns a ValueAnimator that animates between the values
* specified in the PropertyValuesHolder objects.
*
@@ -425,62 +391,6 @@
}
/**
- * Sets long values that will be animated between. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * <p>If there are already multiple sets of values defined for this ValueAnimator via more
- * than one PropertyValuesHolder object, this method will set the values for the first
- * of those objects.</p>
- *
- * @param values A set of values that the animation will animate between over time.
- */
- public void setLongValues(long... values) {
- if (values == null || values.length == 0) {
- return;
- }
- if (mValues == null || mValues.length == 0) {
- setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofLong("", values)});
- } else {
- PropertyValuesHolder valuesHolder = mValues[0];
- valuesHolder.setLongValues(values);
- }
- // New property/values/target should cause re-initialization prior to starting
- mInitialized = false;
- }
-
- /**
- * Sets double values that will be animated between. A single
- * value implies that that value is the one being animated to. However, this is not typically
- * useful in a ValueAnimator object because there is no way for the object to determine the
- * starting value for the animation (unlike ObjectAnimator, which can derive that value
- * from the target object and property being animated). Therefore, there should typically
- * be two or more values.
- *
- * <p>If there are already multiple sets of values defined for this ValueAnimator via more
- * than one PropertyValuesHolder object, this method will set the values for the first
- * of those objects.</p>
- *
- * @param values A set of values that the animation will animate between over time.
- */
- public void setDoubleValues(double... values) {
- if (values == null || values.length == 0) {
- return;
- }
- if (mValues == null || mValues.length == 0) {
- setValues(new PropertyValuesHolder[]{PropertyValuesHolder.ofDouble("", values)});
- } else {
- PropertyValuesHolder valuesHolder = mValues[0];
- valuesHolder.setDoubleValues(values);
- }
- // New property/values/target should cause re-initialization prior to starting
- mInitialized = false;
- }
-
- /**
* Sets the values to animate between for this animation. A single
* value implies that that value is the one being animated to. However, this is not typically
* useful in a ValueAnimator object because there is no way for the object to determine the
@@ -968,8 +878,9 @@
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationStart(this);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationStart(this);
}
}
// This sets the initial value of the animation, prior to actually starting it running
@@ -1059,8 +970,9 @@
if (mListeners != null) {
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationEnd(this);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationEnd(this);
}
}
}
@@ -1077,8 +989,9 @@
// just for delayed animations
ArrayList<AnimatorListener> tmpListeners =
(ArrayList<AnimatorListener>) mListeners.clone();
- for (AnimatorListener listener : tmpListeners) {
- listener.onAnimationStart(this);
+ int numListeners = tmpListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ tmpListeners.get(i).onAnimationStart(this);
}
}
}
@@ -1147,8 +1060,9 @@
if (mCurrentIteration < mRepeatCount || mRepeatCount == INFINITE) {
// Time to repeat
if (mListeners != null) {
- for (AnimatorListener listener : mListeners) {
- listener.onAnimationRepeat(this);
+ int numListeners = mListeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ mListeners.get(i).onAnimationRepeat(this);
}
}
++mCurrentIteration;
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index e185624..a57b54a 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -478,6 +478,12 @@
public abstract Tab getTabAt(int index);
/**
+ * Returns the number of tabs currently registered with the action bar.
+ * @return Tab count
+ */
+ public abstract int getTabCount();
+
+ /**
* Retrieve the current height of the ActionBar.
*
* @return The ActionBar's height
@@ -626,7 +632,8 @@
* @param tab The tab that was selected
* @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
* during a tab switch. The previous tab's unselect and this tab's select will be
- * executed in a single transaction.
+ * executed in a single transaction. This FragmentTransaction does not support
+ * being added to the back stack.
*/
public void onTabSelected(Tab tab, FragmentTransaction ft);
@@ -636,7 +643,8 @@
* @param tab The tab that was unselected
* @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
* during a tab switch. This tab's unselect and the newly selected tab's select
- * will be executed in a single transaction.
+ * will be executed in a single transaction. This FragmentTransaction does not
+ * support being added to the back stack.
*/
public void onTabUnselected(Tab tab, FragmentTransaction ft);
@@ -646,7 +654,8 @@
*
* @param tab The tab that was reselected.
* @param ft A {@link FragmentTransaction} for queuing fragment operations to execute
- * once this method returns.
+ * once this method returns. This FragmentTransaction does not support
+ * being added to the back stack.
*/
public void onTabReselected(Tab tab, FragmentTransaction ft);
}
diff --git a/core/java/android/app/BackStackRecord.java b/core/java/android/app/BackStackRecord.java
index e6cc0f9..c75777d 100644
--- a/core/java/android/app/BackStackRecord.java
+++ b/core/java/android/app/BackStackRecord.java
@@ -186,6 +186,7 @@
int mTransition;
int mTransitionStyle;
boolean mAddToBackStack;
+ boolean mAllowAddToBackStack = true;
String mName;
boolean mCommitted;
int mIndex;
@@ -346,11 +347,28 @@
}
public FragmentTransaction addToBackStack(String name) {
+ if (!mAllowAddToBackStack) {
+ throw new IllegalStateException(
+ "This FragmentTransaction is not allowed to be added to the back stack.");
+ }
mAddToBackStack = true;
mName = name;
return this;
}
+ public boolean isAddToBackStackAllowed() {
+ return mAllowAddToBackStack;
+ }
+
+ public FragmentTransaction disallowAddToBackStack() {
+ if (mAddToBackStack) {
+ throw new IllegalStateException(
+ "This transaction is already being added to the back stack");
+ }
+ mAllowAddToBackStack = false;
+ return this;
+ }
+
public FragmentTransaction setBreadCrumbTitle(int res) {
mBreadCrumbTitleRes = res;
mBreadCrumbTitleText = null;
diff --git a/core/java/android/app/FragmentTransaction.java b/core/java/android/app/FragmentTransaction.java
index b00476bb..19da763 100644
--- a/core/java/android/app/FragmentTransaction.java
+++ b/core/java/android/app/FragmentTransaction.java
@@ -144,6 +144,22 @@
public FragmentTransaction addToBackStack(String name);
/**
+ * Returns true if this FragmentTransaction is allowed to be added to the back
+ * stack. If this method would return false, {@link #addToBackStack(String)}
+ * will throw {@link IllegalStateException}.
+ *
+ * @return True if {@link #addToBackStack(String)} is permitted on this transaction.
+ */
+ public boolean isAddToBackStackAllowed();
+
+ /**
+ * Disallow calls to {@link #addToBackStack(String)}. Any future calls to
+ * addToBackStack will throw {@link IllegalStateException}. If addToBackStack
+ * has already been called, this method will throw IllegalStateException.
+ */
+ public FragmentTransaction disallowAddToBackStack();
+
+ /**
* Set the full title to show as a bread crumb when this transaction
* is on the back stack, as used by {@link FragmentBreadCrumbs}.
*
diff --git a/core/java/android/app/LauncherActivity.java b/core/java/android/app/LauncherActivity.java
index 0ece2fc..7b9bd60 100644
--- a/core/java/android/app/LauncherActivity.java
+++ b/core/java/android/app/LauncherActivity.java
@@ -36,7 +36,9 @@
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
+import android.view.View.OnClickListener;
import android.widget.BaseAdapter;
+import android.widget.Button;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ListView;
@@ -101,11 +103,13 @@
protected List<ListItem> mActivitiesList;
private Filter mFilter;
+ private final boolean mShowIcons;
public ActivityAdapter(IconResizer resizer) {
mIconResizer = resizer;
mInflater = (LayoutInflater) LauncherActivity.this.getSystemService(
Context.LAYOUT_INFLATER_SERVICE);
+ mShowIcons = onEvaluateShowIcons();
mActivitiesList = makeListItems();
}
@@ -158,13 +162,14 @@
private void bindView(View view, ListItem item) {
TextView text = (TextView) view;
text.setText(item.label);
- if (item.icon == null) {
- item.icon = mIconResizer.createIconThumbnail(
- item.resolveInfo.loadIcon(getPackageManager()));
+ if (mShowIcons) {
+ if (item.icon == null) {
+ item.icon = mIconResizer.createIconThumbnail(item.resolveInfo.loadIcon(getPackageManager()));
+ }
+ text.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null);
}
- text.setCompoundDrawablesWithIntrinsicBounds(item.icon, null, null, null);
}
-
+
public Filter getFilter() {
if (mFilter == null) {
mFilter = new ArrayFilter();
@@ -337,19 +342,52 @@
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarIndeterminateVisibility(true);
onSetContentView();
-
+
mIconResizer = new IconResizer();
mIntent = new Intent(getTargetIntent());
mIntent.setComponent(null);
mAdapter = new ActivityAdapter(mIconResizer);
-
+
setListAdapter(mAdapter);
getListView().setTextFilterEnabled(true);
-
+
+ updateAlertTitle();
+ updateButtonText();
+
setProgressBarIndeterminateVisibility(false);
}
+ private void updateAlertTitle() {
+ TextView alertTitle = (TextView) findViewById(com.android.internal.R.id.alertTitle);
+ if (alertTitle != null) {
+ alertTitle.setText(getTitle());
+ }
+ }
+
+ private void updateButtonText() {
+ Button cancelButton = (Button) findViewById(com.android.internal.R.id.button1);
+ if (cancelButton != null) {
+ cancelButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ finish();
+ }
+ });
+ }
+ }
+
+ @Override
+ public void setTitle(CharSequence title) {
+ super.setTitle(title);
+ updateAlertTitle();
+ }
+
+ @Override
+ public void setTitle(int titleId) {
+ super.setTitle(titleId);
+ updateAlertTitle();
+ }
+
/**
* Override to call setContentView() with your own content view to
* customize the list layout.
@@ -407,7 +445,7 @@
// Load all matching activities and sort correctly
List<ResolveInfo> list = onQueryPackageManager(mIntent);
Collections.sort(list, new ResolveInfo.DisplayNameComparator(mPackageManager));
-
+
ArrayList<ListItem> result = new ArrayList<ListItem>(list.size());
int listSize = list.size();
for (int i = 0; i < listSize; i++) {
@@ -417,4 +455,13 @@
return result;
}
+
+ /**
+ * Whether or not to show icons in the list
+ * @hide keeping this private for now, since only Settings needs it
+ * @return true to show icons beside the activity names, false otherwise
+ */
+ protected boolean onEvaluateShowIcons() {
+ return true;
+ }
}
diff --git a/core/java/android/hardware/SensorManager.java b/core/java/android/hardware/SensorManager.java
index a271075..3f6e4ce 100644
--- a/core/java/android/hardware/SensorManager.java
+++ b/core/java/android/hardware/SensorManager.java
@@ -1872,25 +1872,25 @@
}
if(prevR.length == 9) {
- pri0 = R[0];
- pri1 = R[1];
- pri2 = R[2];
- pri3 = R[3];
- pri4 = R[4];
- pri5 = R[5];
- pri6 = R[6];
- pri7 = R[7];
- pri8 = R[8];
+ pri0 = prevR[0];
+ pri1 = prevR[1];
+ pri2 = prevR[2];
+ pri3 = prevR[3];
+ pri4 = prevR[4];
+ pri5 = prevR[5];
+ pri6 = prevR[6];
+ pri7 = prevR[7];
+ pri8 = prevR[8];
} else if(prevR.length == 16) {
- pri0 = R[0];
- pri1 = R[1];
- pri2 = R[2];
- pri3 = R[4];
- pri4 = R[5];
- pri5 = R[6];
- pri6 = R[8];
- pri7 = R[9];
- pri8 = R[10];
+ pri0 = prevR[0];
+ pri1 = prevR[1];
+ pri2 = prevR[2];
+ pri3 = prevR[4];
+ pri4 = prevR[5];
+ pri5 = prevR[6];
+ pri6 = prevR[8];
+ pri7 = prevR[9];
+ pri8 = prevR[10];
}
// calculate the parts of the rotation difference matrix we need
diff --git a/core/java/android/nfc/INfcAdapter.aidl b/core/java/android/nfc/INfcAdapter.aidl
index 7743ceb..cd08e33 100644
--- a/core/java/android/nfc/INfcAdapter.aidl
+++ b/core/java/android/nfc/INfcAdapter.aidl
@@ -39,8 +39,6 @@
// NfcAdapter-class related methods
boolean isEnabled();
- NdefMessage localGet();
- void localSet(in NdefMessage message);
void openTagConnection(in Tag tag);
// Non-public methods
diff --git a/core/java/android/nfc/NfcAdapter.java b/core/java/android/nfc/NfcAdapter.java
index cf80faf..88b6ea4 100644
--- a/core/java/android/nfc/NfcAdapter.java
+++ b/core/java/android/nfc/NfcAdapter.java
@@ -301,48 +301,6 @@
}
/**
- * Set the NDEF Message that this NFC adapter should appear as to Tag
- * readers.
- * <p>
- * Any Tag reader can read the contents of the local tag when it is in
- * proximity, without any further user confirmation.
- * <p>
- * The implementation of this method must either
- * <ul>
- * <li>act as a passive tag containing this NDEF message
- * <li>provide the NDEF message on over LLCP to peer NFC adapters
- * </ul>
- * The NDEF message is preserved across reboot.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- *
- * @param message NDEF message to make public
- * @hide
- */
- public void setLocalNdefMessage(NdefMessage message) {
- try {
- mService.localSet(message);
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- }
- }
-
- /**
- * Get the NDEF Message that this adapter appears as to Tag readers.
- * <p>Requires {@link android.Manifest.permission#NFC} permission.
- *
- * @return NDEF Message that is publicly readable
- * @hide
- */
- public NdefMessage getLocalNdefMessage() {
- try {
- return mService.localGet();
- } catch (RemoteException e) {
- attemptDeadServiceRecovery(e);
- return null;
- }
- }
-
- /**
* Create a raw tag connection to the default Target
* <p>Requires {@link android.Manifest.permission#NFC} permission.
* @hide
diff --git a/core/java/android/os/IVibratorService.aidl b/core/java/android/os/IVibratorService.aidl
index c98fb56..2c2fe8a 100755
--- a/core/java/android/os/IVibratorService.aidl
+++ b/core/java/android/os/IVibratorService.aidl
@@ -19,6 +19,7 @@
/** {@hide} */
interface IVibratorService
{
+ boolean hasVibrator();
void vibrate(long milliseconds, IBinder token);
void vibratePattern(in long[] pattern, int repeat, IBinder token);
void cancelVibrate(IBinder token);
diff --git a/core/java/android/os/ParcelFileDescriptor.java b/core/java/android/os/ParcelFileDescriptor.java
index c1a1809..5f6c4f0 100644
--- a/core/java/android/os/ParcelFileDescriptor.java
+++ b/core/java/android/os/ParcelFileDescriptor.java
@@ -230,7 +230,11 @@
@Override
public void close() throws IOException {
- mFd.close();
+ try {
+ mFd.close();
+ } finally {
+ super.close();
+ }
}
}
@@ -249,7 +253,11 @@
@Override
public void close() throws IOException {
- mFd.close();
+ try {
+ mFd.close();
+ } finally {
+ super.close();
+ }
}
}
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 34d3b85..ab5173e 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -26,6 +26,7 @@
import com.android.internal.os.RuntimeInit;
import dalvik.system.BlockGuard;
+import dalvik.system.CloseGuard;
import java.io.PrintWriter;
import java.io.StringWriter;
@@ -70,6 +71,7 @@
* .build());
* StrictMode.setVmPolicy(new {@link VmPolicy.Builder StrictMode.VmPolicy.Builder}()
* .detectLeakedSqlLiteObjects()
+ * .detectLeakedClosableObjects()
* .penaltyLog()
* .penaltyDeath()
* .build());
@@ -140,6 +142,12 @@
public static final int DETECT_VM_CURSOR_LEAKS = 0x200; // for ProcessPolicy
/**
+ * Note, a "VM_" bit, not thread.
+ * @hide
+ */
+ public static final int DETECT_VM_CLOSABLE_LEAKS = 0x400; // for ProcessPolicy
+
+ /**
* @hide
*/
public static final int PENALTY_LOG = 0x10; // normal android.util.Log
@@ -450,12 +458,12 @@
/**
* Detect everything that's potentially suspect.
*
- * <p>As of the Gingerbread release this only includes
- * SQLite cursor leaks but will likely expand in future
- * releases.
+ * <p>In the Honeycomb release this includes leaks of
+ * SQLite cursors and other closable objects but will
+ * likely expand in future releases.
*/
public Builder detectAll() {
- return enable(DETECT_VM_CURSOR_LEAKS);
+ return enable(DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS);
}
/**
@@ -472,6 +480,18 @@
}
/**
+ * Detect when an {@link java.io.Closeable} or other
+ * object with a explict termination method is finalized
+ * without having been closed.
+ *
+ * <p>You always want to explicitly close such objects to
+ * avoid unnecessary resources leaks.
+ */
+ public Builder detectLeakedClosableObjects() {
+ return enable(DETECT_VM_CLOSABLE_LEAKS);
+ }
+
+ /**
* Crashes the whole process on violation. This penalty runs at
* the end of all enabled penalties so yo you'll still get
* your logging or other violations before the process dies.
@@ -671,6 +691,7 @@
StrictMode.DETECT_NETWORK |
StrictMode.PENALTY_DROPBOX);
sVmPolicyMask = StrictMode.DETECT_VM_CURSOR_LEAKS |
+ StrictMode.DETECT_VM_CLOSABLE_LEAKS |
StrictMode.PENALTY_DROPBOX |
StrictMode.PENALTY_LOG;
return true;
@@ -1030,6 +1051,7 @@
*/
public static void setVmPolicy(final VmPolicy policy) {
sVmPolicyMask = policy.mask;
+ CloseGuard.setEnabled(vmClosableObjectLeaksEnabled());
}
/**
@@ -1043,8 +1065,9 @@
* Enable the recommended StrictMode defaults, with violations just being logged.
*
* <p>This catches disk and network access on the main thread, as
- * well as leaked SQLite cursors. This is simply a wrapper around
- * {@link #setVmPolicy} and {@link #setThreadPolicy}.
+ * well as leaked SQLite cursors and unclosed resources. This is
+ * simply a wrapper around {@link #setVmPolicy} and {@link
+ * #setThreadPolicy}.
*/
public static void enableDefaults() {
StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder()
@@ -1053,6 +1076,7 @@
.build());
StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder()
.detectLeakedSqlLiteObjects()
+ .detectLeakedClosableObjects()
.penaltyLog()
.build());
}
@@ -1067,6 +1091,13 @@
/**
* @hide
*/
+ public static boolean vmClosableObjectLeaksEnabled() {
+ return (sVmPolicyMask & DETECT_VM_CLOSABLE_LEAKS) != 0;
+ }
+
+ /**
+ * @hide
+ */
public static void onSqliteObjectLeaked(String message, Throwable originStack) {
if ((sVmPolicyMask & PENALTY_LOG) != 0) {
Log.e(TAG, message, originStack);
diff --git a/core/java/android/os/Vibrator.java b/core/java/android/os/Vibrator.java
index be818da..e9428f7 100644
--- a/core/java/android/os/Vibrator.java
+++ b/core/java/android/os/Vibrator.java
@@ -38,6 +38,22 @@
}
/**
+ * Check whether the hardware has a vibrator. Returns true if a vibrator
+ * exists, else false.
+ */
+ public boolean hasVibrator() {
+ if (mService == null) {
+ Log.w(TAG, "Failed to vibrate; no vibrator service.");
+ return false;
+ }
+ try {
+ return mService.hasVibrator();
+ } catch (RemoteException e) {
+ }
+ return false;
+ }
+
+ /**
* Turn the vibrator on.
*
* @param milliseconds How long to vibrate for.
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index b74e76f..f111ef2 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -266,36 +266,62 @@
}
/**
- * Media provider table containing an index of all files in the storage.
- * This can be used by applications to find all documents of a particular type
- * and is also used internally by the device side MTP implementation.
- * @hide
+ * Media provider table containing an index of all files in the media storage,
+ * including non-media files. This should be used by applications that work with
+ * non-media file types (text, HTML, PDF, etc) as well as applications that need to
+ * work with multiple media file types in a single query.
*/
public static final class Files {
+ /**
+ * Get the content:// style URI for the files table on the
+ * given volume.
+ *
+ * @param volumeName the name of the volume to get the URI for
+ * @return the URI to the files table on the given volume
+ */
public static Uri getContentUri(String volumeName) {
return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
"/file");
}
+ /**
+ * Get the content:// style URI for a single row in the files table on the
+ * given volume.
+ *
+ * @param volumeName the name of the volume to get the URI for
+ * @param rowId the file to get the URI for
+ * @return the URI to the files table on the given volume
+ */
public static final Uri getContentUri(String volumeName,
- long fileId) {
+ long rowId) {
return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
- + "/file/" + fileId);
+ + "/file/" + rowId);
}
+ /**
+ * For use only by the MTP implementation.
+ * @hide
+ */
public static Uri getMtpObjectsUri(String volumeName) {
return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName +
"/object");
}
+ /**
+ * For use only by the MTP implementation.
+ * @hide
+ */
public static final Uri getMtpObjectsUri(String volumeName,
long fileId) {
return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
+ "/object/" + fileId);
}
- // Used to implement the MTP GetObjectReferences and SetObjectReferences commands.
+ /**
+ * Used to implement the MTP GetObjectReferences and SetObjectReferences commands.
+ * @hide
+ */
public static final Uri getMtpReferencesUri(String volumeName,
long fileId) {
return Uri.parse(CONTENT_AUTHORITY_SLASH + volumeName
@@ -310,6 +336,7 @@
/**
* The MTP format code of the file
* <P>Type: INTEGER</P>
+ * @hide
*/
public static final String FORMAT = "format";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 2229964..9c72dec 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -1573,6 +1573,16 @@
public static final String ACCELEROMETER_ROTATION = "accelerometer_rotation";
/**
+ * Default screen rotation when no other policy applies.
+ * When {@link #ACCELEROMETER_ROTATION} is zero and no on-screen Activity expresses a
+ * preference, this rotation value will be used. Must be one of the
+ * {@link android.view.Surface#ROTATION_0 Surface rotation constants}.
+ *
+ * @see Display#getRotation
+ */
+ public static final String USER_ROTATION = "user_rotation";
+
+ /**
* Whether the audible DTMF tones are played by the dialer when dialing. The value is
* boolean (1 or 0).
*/
@@ -1806,6 +1816,7 @@
TIME_12_24,
DATE_FORMAT,
ACCELEROMETER_ROTATION,
+ USER_ROTATION,
DTMF_TONE_WHEN_DIALING,
DTMF_TONE_TYPE_WHEN_DIALING,
EMERGENCY_TONE,
diff --git a/core/java/android/util/StateSet.java b/core/java/android/util/StateSet.java
index f3d8159..21d8e45 100644
--- a/core/java/android/util/StateSet.java
+++ b/core/java/android/util/StateSet.java
@@ -38,6 +38,7 @@
public class StateSet {
public static final int[] WILD_CARD = new int[0];
+ public static final int[] NOTHING = new int[] { 0 };
/**
* Return whether the stateSetOrSpec is matched by all StateSets.
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index d4dd05c..a54f342 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -156,4 +156,17 @@
* calls back when it changes.
*/
int watchRotation(IRotationWatcher watcher);
+
+ /**
+ * Lock the device orientation to the current rotation. Sensor input will
+ * be ignored until thawRotation() is called.
+ * @hide
+ */
+ void freezeRotation();
+
+ /**
+ * Release the orientation lock imposed by freezeRotation().
+ * @hide
+ */
+ void thawRotation();
}
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index a9f0780..340678d 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -8288,7 +8288,7 @@
(ArrayList<OnLayoutChangeListener>) mOnLayoutChangeListeners.clone();
int numListeners = listenersCopy.size();
for (int i = 0; i < numListeners; ++i) {
- listenersCopy.get(i).onLayoutChange(this, l, r, t, b, oldL, oldT, oldR, oldB);
+ listenersCopy.get(i).onLayoutChange(this, l, t, r, b, oldL, oldT, oldR, oldB);
}
}
}
@@ -8620,6 +8620,16 @@
}
/**
+ * Call {@link Drawable#jumpToCurrentState() Drawable.jumpToCurrentState()}
+ * on all Drawable objects associated with this view.
+ */
+ public void jumpDrawablesToCurrentState() {
+ if (mBGDrawable != null) {
+ mBGDrawable.jumpToCurrentState();
+ }
+ }
+
+ /**
* Sets the background color for this view.
* @param color the color of the background
*/
@@ -8627,6 +8637,7 @@
public void setBackgroundColor(int color) {
if (mBGDrawable instanceof ColorDrawable) {
((ColorDrawable) mBGDrawable).setColor(color);
+ invalidate();
} else {
setBackgroundDrawable(new ColorDrawable(color));
}
diff --git a/core/java/android/view/ViewTreeObserver.java b/core/java/android/view/ViewTreeObserver.java
index 26e5cbc..06a0fa6 100644
--- a/core/java/android/view/ViewTreeObserver.java
+++ b/core/java/android/view/ViewTreeObserver.java
@@ -18,6 +18,7 @@
import android.graphics.Rect;
+import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;
/**
@@ -32,10 +33,10 @@
public final class ViewTreeObserver {
private CopyOnWriteArrayList<OnGlobalFocusChangeListener> mOnGlobalFocusListeners;
private CopyOnWriteArrayList<OnGlobalLayoutListener> mOnGlobalLayoutListeners;
- private CopyOnWriteArrayList<OnPreDrawListener> mOnPreDrawListeners;
private CopyOnWriteArrayList<OnTouchModeChangeListener> mOnTouchModeChangeListeners;
private CopyOnWriteArrayList<OnComputeInternalInsetsListener> mOnComputeInternalInsetsListeners;
private CopyOnWriteArrayList<OnScrollChangedListener> mOnScrollChangedListeners;
+ private ArrayList<OnPreDrawListener> mOnPreDrawListeners;
private boolean mAlive = true;
@@ -354,7 +355,7 @@
checkIsAlive();
if (mOnPreDrawListeners == null) {
- mOnPreDrawListeners = new CopyOnWriteArrayList<OnPreDrawListener>();
+ mOnPreDrawListeners = new ArrayList<OnPreDrawListener>();
}
mOnPreDrawListeners.add(listener);
@@ -526,7 +527,7 @@
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
final CopyOnWriteArrayList<OnGlobalFocusChangeListener> listeners = mOnGlobalFocusListeners;
- if (listeners != null) {
+ if (listeners != null && listeners.size() > 0) {
for (OnGlobalFocusChangeListener listener : listeners) {
listener.onGlobalFocusChanged(oldFocus, newFocus);
}
@@ -544,7 +545,7 @@
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
final CopyOnWriteArrayList<OnGlobalLayoutListener> listeners = mOnGlobalLayoutListeners;
- if (listeners != null) {
+ if (listeners != null && listeners.size() > 0) {
for (OnGlobalLayoutListener listener : listeners) {
listener.onGlobalLayout();
}
@@ -560,15 +561,17 @@
* @return True if the current draw should be canceled and resceduled, false otherwise.
*/
public final boolean dispatchOnPreDraw() {
- // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
- // perform the dispatching. The iterator is a safe guard against listeners that
+ // NOTE: we *must* clone the listener list to perform the dispatching.
+ // The clone is a safe guard against listeners that
// could mutate the list by calling the various add/remove methods. This prevents
- // the array from being modified while we iterate it.
+ // the array from being modified while we process it.
boolean cancelDraw = false;
- final CopyOnWriteArrayList<OnPreDrawListener> listeners = mOnPreDrawListeners;
- if (listeners != null) {
- for (OnPreDrawListener listener : listeners) {
- cancelDraw |= !listener.onPreDraw();
+ if (mOnPreDrawListeners != null && mOnPreDrawListeners.size() > 0) {
+ final ArrayList<OnPreDrawListener> listeners =
+ (ArrayList<OnPreDrawListener>) mOnPreDrawListeners.clone();
+ int numListeners = listeners.size();
+ for (int i = 0; i < numListeners; ++i) {
+ cancelDraw |= !(listeners.get(i).onPreDraw());
}
}
return cancelDraw;
@@ -580,13 +583,9 @@
* @param inTouchMode True if the touch mode is now enabled, false otherwise.
*/
final void dispatchOnTouchModeChanged(boolean inTouchMode) {
- // NOTE: because of the use of CopyOnWriteArrayList, we *must* use an iterator to
- // perform the dispatching. The iterator is a safe guard against listeners that
- // could mutate the list by calling the various add/remove methods. This prevents
- // the array from being modified while we iterate it.
final CopyOnWriteArrayList<OnTouchModeChangeListener> listeners =
mOnTouchModeChangeListeners;
- if (listeners != null) {
+ if (listeners != null && listeners.size() > 0) {
for (OnTouchModeChangeListener listener : listeners) {
listener.onTouchModeChanged(inTouchMode);
}
@@ -602,7 +601,7 @@
// could mutate the list by calling the various add/remove methods. This prevents
// the array from being modified while we iterate it.
final CopyOnWriteArrayList<OnScrollChangedListener> listeners = mOnScrollChangedListeners;
- if (listeners != null) {
+ if (listeners != null && listeners.size() > 0) {
for (OnScrollChangedListener listener : listeners) {
listener.onScrollChanged();
}
@@ -628,7 +627,7 @@
// the array from being modified while we iterate it.
final CopyOnWriteArrayList<OnComputeInternalInsetsListener> listeners =
mOnComputeInternalInsetsListeners;
- if (listeners != null) {
+ if (listeners != null && listeners.size() > 0) {
for (OnComputeInternalInsetsListener listener : listeners) {
listener.onComputeInternalInsets(inoutInfo);
}
diff --git a/core/java/android/view/WindowManagerPolicy.java b/core/java/android/view/WindowManagerPolicy.java
index 1a341e1..e78d6a8 100644
--- a/core/java/android/view/WindowManagerPolicy.java
+++ b/core/java/android/view/WindowManagerPolicy.java
@@ -362,6 +362,13 @@
* modify the rotation.
*/
public final int USE_LAST_ROTATION = -1000;
+
+ /** When not otherwise specified by the activity's screenOrientation, rotation should be
+ * determined by the system (that is, using sensors). */
+ public final int USER_ROTATION_FREE = 0;
+ /** When not otherwise specified by the activity's screenOrientation, rotation is set by
+ * the user. */
+ public final int USER_ROTATION_LOCKED = 1;
/**
* Perform initialization of the policy.
@@ -787,4 +794,14 @@
* Return false to disable key repeat events from being generated.
*/
public boolean allowKeyRepeat();
+
+ /**
+ * Inform the policy that the user has chosen a preferred orientation ("rotation lock").
+ *
+ * @param mode One of {@link WindowManagerPolicy#USER_ROTATION_LOCKED} or
+ * {@link * WindowManagerPolicy#USER_ROTATION_FREE}.
+ * @param rotation One of {@link Surface#ROTATION_0}, {@link Surface#ROTATION_90},
+ * {@link Surface#ROTATION_180}, {@link Surface#ROTATION_270}.
+ */
+ public void setUserRotationMode(int mode, int rotation);
}
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index 2087664..cce7914 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -674,13 +674,16 @@
* @param url The url to load.
* @return An InputStream to the android resource
*/
- private InputStream inputStreamForAndroidResource(String url, int type) {
- final int RESOURCE = 1;
- final int ASSET = 2;
- final int CONTENT = 3;
+ private InputStream inputStreamForAndroidResource(String url) {
+ // This list needs to be kept in sync with the list in
+ // external/webkit/WebKit/android/WebCoreSupport/WebUrlLoaderClient.cpp
+ final String ANDROID_ASSET = "file:///android_asset/";
+ final String ANDROID_RESOURCE = "file:///android_res/";
+ final String ANDROID_CONTENT = "content:";
- if (type == RESOURCE) {
- // file:///android_res
+ // file:///android_res
+ if (url.startsWith(ANDROID_RESOURCE)) {
+ url = url.replaceFirst(ANDROID_RESOURCE, "");
if (url == null || url.length() == 0) {
Log.e(LOGTAG, "url has length 0 " + url);
return null;
@@ -717,15 +720,18 @@
return null;
}
- } else if (type == ASSET) {
- // file:///android_asset
+ // file:///android_asset
+ } else if (url.startsWith(ANDROID_ASSET)) {
+ url = url.replaceFirst(ANDROID_ASSET, "");
try {
AssetManager assets = mContext.getAssets();
return assets.open(url, AssetManager.ACCESS_STREAMING);
} catch (IOException e) {
return null;
}
- } else if (type == CONTENT) {
+
+ // content://
+ } else if (url.startsWith(ANDROID_CONTENT)) {
try {
// Strip off mimetype, for compatibility with ContentLoader.java
// If we don't do this, we can fail to load Gmail attachments,
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 14dc61d..1538bd0 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -124,6 +124,16 @@
private boolean mAutoFillable; // Is this textview part of an autofillable form?
private int mQueryId;
+ // Types used with setType. Keep in sync with CachedInput.h
+ private static final int NORMAL_TEXT_FIELD = 0;
+ private static final int TEXT_AREA = 1;
+ private static final int PASSWORD = 2;
+ private static final int SEARCH = 3;
+ private static final int EMAIL = 4;
+ private static final int NUMBER = 5;
+ private static final int TELEPHONE = 6;
+ private static final int URL = 7;
+
/**
* Create a new WebTextView.
* @param context The Context for this WebTextView.
@@ -788,7 +798,7 @@
/* package */ void setInPassword(boolean inPassword) {
if (inPassword) {
setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.
- TYPE_TEXT_VARIATION_PASSWORD);
+ TYPE_TEXT_VARIATION_WEB_PASSWORD);
createBackground();
}
// For password fields, draw the WebTextView. For others, just show
@@ -940,7 +950,7 @@
/**
* Called by WebView.rebuildWebTextView(). Based on the type of the <input>
* element, set up the WebTextView, its InputType, and IME Options properly.
- * @param type int corresponding to enum "type" defined in WebView.cpp.
+ * @param type int corresponding to enum "Type" defined in CachedInput.h.
* Does not correspond to HTMLInputElement::InputType so this
* is unaffected if that changes, and also because that has no
* type corresponding to textarea (which is its own tag).
@@ -950,47 +960,47 @@
boolean single = true;
boolean inPassword = false;
int maxLength = -1;
- int inputType = EditorInfo.TYPE_CLASS_TEXT;
- if (mWebView.nativeFocusCandidateHasNextTextfield()) {
- inputType |= EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
- }
+ int inputType = EditorInfo.TYPE_CLASS_TEXT
+ | EditorInfo.TYPE_TEXT_VARIATION_WEB_EDIT_TEXT;
int imeOptions = EditorInfo.IME_FLAG_NO_EXTRACT_UI
| EditorInfo.IME_FLAG_NO_FULLSCREEN;
+ if (TEXT_AREA != type
+ && mWebView.nativeFocusCandidateHasNextTextfield()) {
+ imeOptions |= EditorInfo.IME_FLAG_NAVIGATE_NEXT;
+ }
switch (type) {
- case 0: // NORMAL_TEXT_FIELD
+ case NORMAL_TEXT_FIELD:
imeOptions |= EditorInfo.IME_ACTION_GO;
break;
- case 1: // TEXT_AREA
+ case TEXT_AREA:
single = false;
- inputType = EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
+ inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE
| EditorInfo.TYPE_TEXT_FLAG_CAP_SENTENCES
- | EditorInfo.TYPE_CLASS_TEXT
| EditorInfo.TYPE_TEXT_FLAG_AUTO_CORRECT;
imeOptions |= EditorInfo.IME_ACTION_NONE;
break;
- case 2: // PASSWORD
+ case PASSWORD:
inPassword = true;
imeOptions |= EditorInfo.IME_ACTION_GO;
break;
- case 3: // SEARCH
+ case SEARCH:
imeOptions |= EditorInfo.IME_ACTION_SEARCH;
break;
- case 4: // EMAIL
- // TYPE_TEXT_VARIATION_WEB_EDIT_TEXT prevents EMAIL_ADDRESS
- // from working, so exclude it for now.
+ case EMAIL:
+ inputType = EditorInfo.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS;
imeOptions |= EditorInfo.IME_ACTION_GO;
break;
- case 5: // NUMBER
+ case NUMBER:
inputType |= EditorInfo.TYPE_CLASS_NUMBER;
// Number and telephone do not have both a Tab key and an
// action, so set the action to NEXT
imeOptions |= EditorInfo.IME_ACTION_NEXT;
break;
- case 6: // TELEPHONE
+ case TELEPHONE:
inputType |= EditorInfo.TYPE_CLASS_PHONE;
imeOptions |= EditorInfo.IME_ACTION_NEXT;
break;
- case 7: // URL
+ case URL:
// TYPE_TEXT_VARIATION_URI prevents Tab key from showing, so
// exclude it for now.
imeOptions |= EditorInfo.IME_ACTION_GO;
@@ -1004,7 +1014,7 @@
mWebView.requestLabel(mWebView.nativeFocusCandidateFramePointer(),
mNodePointer);
maxLength = mWebView.nativeFocusCandidateMaxLength();
- if (type != 2 /* PASSWORD */) {
+ if (type != PASSWORD) {
String name = mWebView.nativeFocusCandidateName();
if (name != null && name.length() > 0) {
mWebView.requestFormData(name, mNodePointer, mAutoFillable);
diff --git a/core/java/android/widget/AbsListView.java b/core/java/android/widget/AbsListView.java
index 4e90ecd..7629673 100644
--- a/core/java/android/widget/AbsListView.java
+++ b/core/java/android/widget/AbsListView.java
@@ -36,6 +36,7 @@
import android.util.Log;
import android.util.LongSparseArray;
import android.util.SparseBooleanArray;
+import android.util.StateSet;
import android.view.ActionMode;
import android.view.Gravity;
import android.view.HapticFeedbackConstants;
@@ -254,6 +255,17 @@
Drawable mSelector;
/**
+ * Set to true if we would like to have the selector showing itself.
+ * We still need to draw and position it even if this is false.
+ */
+ boolean mSelectorShowing;
+
+ /**
+ * The current position of the selector in the list.
+ */
+ int mSelectorPosition = INVALID_POSITION;
+
+ /**
* Defines the selector's location and dimension at drawing time
*/
Rect mSelectorRect = new Rect();
@@ -1324,6 +1336,7 @@
setSelectedPositionInt(INVALID_POSITION);
// Do this before setting mNeedSync since setNextSelectedPosition looks at mNeedSync
setNextSelectedPositionInt(INVALID_POSITION);
+ mSelectorPosition = INVALID_POSITION;
mNeedSync = true;
mSyncRowId = ss.firstId;
mSyncPosition = ss.position;
@@ -1416,6 +1429,8 @@
setSelectedPositionInt(INVALID_POSITION);
setNextSelectedPositionInt(INVALID_POSITION);
mSelectedTop = 0;
+ mSelectorShowing = false;
+ mSelectorPosition = INVALID_POSITION;
mSelectorRect.setEmpty();
invalidate();
}
@@ -1708,7 +1723,7 @@
}
if (child != scrapView) {
- mRecycler.addScrapView(scrapView);
+ mRecycler.addScrapView(scrapView, position);
if (mCacheColorHint != 0) {
child.setDrawingCacheBackgroundColor(mCacheColorHint);
}
@@ -1734,7 +1749,11 @@
return child;
}
- void positionSelector(View sel) {
+ void positionSelector(int position, View sel) {
+ if (position != INVALID_POSITION) {
+ mSelectorPosition = position;
+ }
+
final Rect selectorRect = mSelectorRect;
selectorRect.set(sel.getLeft(), sel.getTop(), sel.getRight(), sel.getBottom());
positionSelector(selectorRect.left, selectorRect.top, selectorRect.right,
@@ -1743,7 +1762,9 @@
final boolean isChildViewEnabled = mIsChildViewEnabled;
if (sel.isEnabled() != isChildViewEnabled) {
mIsChildViewEnabled = !isChildViewEnabled;
- refreshDrawableState();
+ if (mSelectorShowing) {
+ refreshDrawableState();
+ }
}
}
@@ -1822,7 +1843,7 @@
}
private void drawSelector(Canvas canvas) {
- if (shouldShowSelector() && mSelectorRect != null && !mSelectorRect.isEmpty()) {
+ if (!mSelectorRect.isEmpty()) {
final Drawable selector = mSelector;
selector.setBounds(mSelectorRect);
selector.draw(canvas);
@@ -1866,7 +1887,7 @@
mSelectionRightPadding = padding.right;
mSelectionBottomPadding = padding.bottom;
sel.setCallback(this);
- sel.setState(getDrawableState());
+ updateSelectorState();
}
/**
@@ -1891,7 +1912,7 @@
Drawable selector = mSelector;
Rect selectorRect = mSelectorRect;
if (selector != null && (isFocused() || touchModeDrawsInPressedState())
- && selectorRect != null && !selectorRect.isEmpty()) {
+ && !selectorRect.isEmpty()) {
final View v = getChildAt(mSelectedPosition - mFirstPosition);
@@ -1926,12 +1947,20 @@
mScrollDown = down;
}
+ void updateSelectorState() {
+ if (mSelector != null) {
+ if (shouldShowSelector()) {
+ mSelector.setState(getDrawableState());
+ } else {
+ mSelector.setState(StateSet.NOTHING);
+ }
+ }
+ }
+
@Override
protected void drawableStateChanged() {
super.drawableStateChanged();
- if (mSelector != null) {
- mSelector.setState(getDrawableState());
- }
+ updateSelectorState();
}
@Override
@@ -2141,7 +2170,6 @@
} else {
mTouchMode = TOUCH_MODE_DONE_WAITING;
}
-
}
}
}
@@ -2316,10 +2344,10 @@
mLayoutMode = LAYOUT_NORMAL;
if (!mDataChanged) {
- layoutChildren();
child.setPressed(true);
- positionSelector(child);
setPressed(true);
+ layoutChildren();
+ positionSelector(mMotionPosition, child);
final int longPressTimeout = ViewConfiguration.getLongPressTimeout();
final boolean longClickable = isLongClickable();
@@ -2566,7 +2594,7 @@
setSelectedPositionInt(mMotionPosition);
layoutChildren();
child.setPressed(true);
- positionSelector(child);
+ positionSelector(mMotionPosition, child);
setPressed(true);
if (mSelector != null) {
Drawable d = mSelector.getCurrent();
@@ -2576,16 +2604,17 @@
}
postDelayed(new Runnable() {
public void run() {
+ mTouchMode = TOUCH_MODE_REST;
child.setPressed(false);
setPressed(false);
if (!mDataChanged) {
post(performClick);
}
- mTouchMode = TOUCH_MODE_REST;
}
}, ViewConfiguration.getPressedStateDuration());
} else {
mTouchMode = TOUCH_MODE_REST;
+ updateSelectorState();
}
return true;
} else if (!mDataChanged && mAdapter.isEnabled(motionPosition)) {
@@ -2593,6 +2622,7 @@
}
}
mTouchMode = TOUCH_MODE_REST;
+ updateSelectorState();
break;
case TOUCH_MODE_SCROLL:
final int childCount = getChildCount();
@@ -3507,7 +3537,7 @@
count++;
int position = firstPosition + i;
if (position >= headerViewsCount && position < footerViewsStart) {
- mRecycler.addScrapView(child);
+ mRecycler.addScrapView(child, position);
if (ViewDebug.TRACE_RECYCLER) {
ViewDebug.trace(child,
@@ -3528,7 +3558,7 @@
count++;
int position = firstPosition + i;
if (position >= headerViewsCount && position < footerViewsStart) {
- mRecycler.addScrapView(child);
+ mRecycler.addScrapView(child, position);
if (ViewDebug.TRACE_RECYCLER) {
ViewDebug.trace(child,
@@ -3563,8 +3593,15 @@
if (!inTouchMode && mSelectedPosition != INVALID_POSITION) {
final int childIndex = mSelectedPosition - mFirstPosition;
if (childIndex >= 0 && childIndex < getChildCount()) {
- positionSelector(getChildAt(childIndex));
+ positionSelector(mSelectedPosition, getChildAt(childIndex));
}
+ } else if (mSelectorPosition != INVALID_POSITION) {
+ final int childIndex = mSelectorPosition - mFirstPosition;
+ if (childIndex >= 0 && childIndex < getChildCount()) {
+ positionSelector(INVALID_POSITION, getChildAt(childIndex));
+ }
+ } else {
+ mSelectorRect.setEmpty();
}
mBlockLayoutRequests = false;
@@ -3616,7 +3653,7 @@
setSelectedPositionInt(INVALID_POSITION);
setNextSelectedPositionInt(INVALID_POSITION);
mSelectedTop = 0;
- mSelectorRect.setEmpty();
+ mSelectorShowing = false;
}
}
@@ -3876,6 +3913,7 @@
mNextSelectedPosition = INVALID_POSITION;
mNextSelectedRowId = INVALID_ROW_ID;
mNeedSync = false;
+ mSelectorPosition = INVALID_POSITION;
checkSelectionChanged();
}
@@ -4562,6 +4600,13 @@
@ViewDebug.ExportedProperty(category = "list")
boolean forceAdd;
+ /**
+ * The position the view was removed from when pulled out of the
+ * scrap heap.
+ * @hide
+ */
+ int scrappedFromPosition;
+
public LayoutParams(Context c, AttributeSet attrs) {
super(c, attrs);
}
@@ -4741,23 +4786,12 @@
* @return A view from the ScrapViews collection. These are unordered.
*/
View getScrapView(int position) {
- ArrayList<View> scrapViews;
if (mViewTypeCount == 1) {
- scrapViews = mCurrentScrap;
- int size = scrapViews.size();
- if (size > 0) {
- return scrapViews.remove(size - 1);
- } else {
- return null;
- }
+ return retrieveFromScrap(mCurrentScrap, position);
} else {
int whichScrap = mAdapter.getItemViewType(position);
if (whichScrap >= 0 && whichScrap < mScrapViews.length) {
- scrapViews = mScrapViews[whichScrap];
- int size = scrapViews.size();
- if (size > 0) {
- return scrapViews.remove(size - 1);
- }
+ return retrieveFromScrap(mScrapViews[whichScrap], position);
}
}
return null;
@@ -4768,7 +4802,7 @@
*
* @param scrap The view to add
*/
- void addScrapView(View scrap) {
+ void addScrapView(View scrap, int position) {
AbsListView.LayoutParams lp = (AbsListView.LayoutParams) scrap.getLayoutParams();
if (lp == null) {
return;
@@ -4784,6 +4818,8 @@
return;
}
+ lp.scrappedFromPosition = position;
+
if (mViewTypeCount == 1) {
scrap.dispatchStartTemporaryDetach();
mCurrentScrap.add(scrap);
@@ -4810,7 +4846,9 @@
for (int i = count - 1; i >= 0; i--) {
final View victim = activeViews[i];
if (victim != null) {
- int whichScrap = ((AbsListView.LayoutParams) victim.getLayoutParams()).viewType;
+ final AbsListView.LayoutParams lp
+ = (AbsListView.LayoutParams) victim.getLayoutParams();
+ int whichScrap = lp.viewType;
activeViews[i] = null;
@@ -4826,6 +4864,7 @@
scrapViews = mScrapViews[whichScrap];
}
victim.dispatchStartTemporaryDetach();
+ lp.scrappedFromPosition = mFirstActivePosition + i;
scrapViews.add(victim);
if (hasListener) {
@@ -4911,4 +4950,22 @@
}
}
}
+
+ static View retrieveFromScrap(ArrayList<View> scrapViews, int position) {
+ int size = scrapViews.size();
+ if (size > 0) {
+ // See if we still have a view for this position.
+ for (int i=0; i<size; i++) {
+ View view = scrapViews.get(i);
+ if (((AbsListView.LayoutParams)view.getLayoutParams())
+ .scrappedFromPosition == position) {
+ scrapViews.remove(i);
+ return view;
+ }
+ }
+ return scrapViews.remove(size - 1);
+ } else {
+ return null;
+ }
+ }
}
diff --git a/core/java/android/widget/AdapterView.java b/core/java/android/widget/AdapterView.java
index f5afb94..f16efbd 100644
--- a/core/java/android/widget/AdapterView.java
+++ b/core/java/android/widget/AdapterView.java
@@ -18,7 +18,6 @@
import android.content.Context;
import android.database.DataSetObserver;
-import android.os.Handler;
import android.os.Parcelable;
import android.os.SystemClock;
import android.util.AttributeSet;
diff --git a/core/java/android/widget/GridView.java b/core/java/android/widget/GridView.java
index 46c7d33..936a97d 100644
--- a/core/java/android/widget/GridView.java
+++ b/core/java/android/widget/GridView.java
@@ -1009,7 +1009,7 @@
childHeight = child.getMeasuredHeight();
if (mRecycler.shouldRecycleViewType(p.viewType)) {
- mRecycler.addScrapView(child);
+ mRecycler.addScrapView(child, -1);
}
}
@@ -1148,7 +1148,7 @@
if (dataChanged) {
for (int i = 0; i < childCount; i++) {
- recycleBin.addScrapView(getChildAt(i));
+ recycleBin.addScrapView(getChildAt(i), firstPosition+i);
}
} else {
recycleBin.fillActiveViews(childCount, firstPosition);
@@ -1215,11 +1215,11 @@
recycleBin.scrapActiveViews();
if (sel != null) {
- positionSelector(sel);
+ positionSelector(INVALID_POSITION, sel);
mSelectedTop = sel.getTop();
} else if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
View child = getChildAt(mMotionPosition - mFirstPosition);
- if (child != null) positionSelector(child);
+ if (child != null) positionSelector(mMotionPosition, child);
} else {
mSelectedTop = 0;
mSelectorRect.setEmpty();
@@ -1391,6 +1391,11 @@
if (mCachingStarted) {
child.setDrawingCacheEnabled(true);
}
+
+ if (recycled && (((AbsListView.LayoutParams)child.getLayoutParams()).scrappedFromPosition)
+ != position) {
+ child.jumpDrawablesToCurrentState();
+ }
}
/**
diff --git a/core/java/android/widget/ListView.java b/core/java/android/widget/ListView.java
index b5e103f..e0119e9 100644
--- a/core/java/android/widget/ListView.java
+++ b/core/java/android/widget/ListView.java
@@ -581,7 +581,7 @@
final boolean scroll = scrollYDelta != 0;
if (scroll) {
scrollListItemsBy(-scrollYDelta);
- positionSelector(child);
+ positionSelector(INVALID_POSITION, child);
mSelectedTop = child.getTop();
invalidate();
}
@@ -1086,7 +1086,7 @@
if (recycleOnMeasure() && mRecycler.shouldRecycleViewType(
((LayoutParams) child.getLayoutParams()).viewType)) {
- mRecycler.addScrapView(child);
+ mRecycler.addScrapView(child, -1);
}
}
@@ -1203,7 +1203,7 @@
// Recycle the view before we possibly return from the method
if (recyle && recycleBin.shouldRecycleViewType(
((LayoutParams) child.getLayoutParams()).viewType)) {
- recycleBin.addScrapView(child);
+ recycleBin.addScrapView(child, -1);
}
returnedHeight += child.getMeasuredHeight();
@@ -1507,7 +1507,7 @@
// already cached in mHeaderViews;
if (dataChanged) {
for (int i = 0; i < childCount; i++) {
- recycleBin.addScrapView(getChildAt(i));
+ recycleBin.addScrapView(getChildAt(i), firstPosition+i);
if (ViewDebug.TRACE_RECYCLER) {
ViewDebug.trace(getChildAt(i),
ViewDebug.RecyclerTraceType.MOVE_TO_SCRAP_HEAP, index, i);
@@ -1610,19 +1610,19 @@
if (focused != null) {
focused.clearFocus();
}
- positionSelector(sel);
+ positionSelector(INVALID_POSITION, sel);
} else {
sel.setSelected(false);
mSelectorRect.setEmpty();
}
} else {
- positionSelector(sel);
+ positionSelector(INVALID_POSITION, sel);
}
mSelectedTop = sel.getTop();
} else {
if (mTouchMode > TOUCH_MODE_DOWN && mTouchMode < TOUCH_MODE_SCROLL) {
View child = getChildAt(mMotionPosition - mFirstPosition);
- if (child != null) positionSelector(child);
+ if (child != null) positionSelector(mMotionPosition, child);
} else {
mSelectedTop = 0;
mSelectorRect.setEmpty();
@@ -1703,7 +1703,7 @@
if (!mDataChanged) {
- // Try to use an exsiting view for this position
+ // Try to use an existing view for this position
child = mRecycler.getActiveView(position);
if (child != null) {
if (ViewDebug.TRACE_RECYCLER) {
@@ -1820,6 +1820,11 @@
if (mCachingStarted && !child.isDrawingCacheEnabled()) {
child.setDrawingCacheEnabled(true);
}
+
+ if (recycled && (((AbsListView.LayoutParams)child.getLayoutParams()).scrappedFromPosition)
+ != position) {
+ child.jumpDrawablesToCurrentState();
+ }
}
@Override
@@ -2288,6 +2293,7 @@
}
View selectedView = getSelectedView();
+ int selectedPos = mSelectedPosition;
int nextSelectedPosition = lookForSelectablePositionOnScreen(direction);
int amountToScroll = amountToScroll(direction, nextSelectedPosition);
@@ -2305,6 +2311,7 @@
setSelectedPositionInt(nextSelectedPosition);
setNextSelectedPositionInt(nextSelectedPosition);
selectedView = getSelectedView();
+ selectedPos = nextSelectedPosition;
if (mItemsCanFocus && focusResult == null) {
// there was no new view found to take focus, make sure we
// don't leave focus with the old selection
@@ -2345,7 +2352,7 @@
if (needToRedraw) {
if (selectedView != null) {
- positionSelector(selectedView);
+ positionSelector(selectedPos, selectedView);
mSelectedTop = selectedView.getTop();
}
if (!awakenScrollBars()) {
@@ -2841,7 +2848,7 @@
AbsListView.LayoutParams layoutParams = (LayoutParams) first.getLayoutParams();
if (recycleBin.shouldRecycleViewType(layoutParams.viewType)) {
detachViewFromParent(first);
- recycleBin.addScrapView(first);
+ recycleBin.addScrapView(first, mFirstPosition);
} else {
removeViewInLayout(first);
}
@@ -2872,7 +2879,7 @@
AbsListView.LayoutParams layoutParams = (LayoutParams) last.getLayoutParams();
if (recycleBin.shouldRecycleViewType(layoutParams.viewType)) {
detachViewFromParent(last);
- recycleBin.addScrapView(last);
+ recycleBin.addScrapView(last, mFirstPosition+lastIndex);
} else {
removeViewInLayout(last);
}
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 81c2f65..7c129b0 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -447,7 +447,7 @@
drawableBottom = null;
int drawablePadding = 0;
int ellipsize = -1;
- boolean singleLine = false;
+ boolean singleLine = true;
int maxlength = -1;
CharSequence text = "";
CharSequence hint = null;
@@ -759,11 +759,6 @@
BufferType bufferType = BufferType.EDITABLE;
- if ((inputType & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_MASK_VARIATION))
- == (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)) {
- password = true;
- }
-
if (inputMethod != null) {
Class<?> c;
@@ -796,10 +791,7 @@
? inputType : EditorInfo.TYPE_CLASS_TEXT;
} else if (inputType != EditorInfo.TYPE_NULL) {
setInputType(inputType, true);
- singleLine = (inputType&(EditorInfo.TYPE_MASK_CLASS
- | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE)) !=
- (EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE);
+ singleLine = !isMultilineInputType(inputType);
} else if (phone) {
mInput = DialerKeyListener.getInstance();
mInputType = inputType = EditorInfo.TYPE_CLASS_PHONE;
@@ -818,10 +810,6 @@
TextKeyListener.Capitalize cap;
inputType = EditorInfo.TYPE_CLASS_TEXT;
- if (!singleLine) {
- inputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
- }
-
switch (autocap) {
case 1:
cap = TextKeyListener.Capitalize.SENTENCES;
@@ -848,9 +836,6 @@
} else if (editable) {
mInput = TextKeyListener.getInstance();
mInputType = EditorInfo.TYPE_CLASS_TEXT;
- if (!singleLine) {
- mInputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
- }
} else {
mInput = null;
@@ -867,10 +852,19 @@
}
}
- if (password && (mInputType&EditorInfo.TYPE_MASK_CLASS)
- == EditorInfo.TYPE_CLASS_TEXT) {
- mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
- | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
+ if (password) {
+ // Caller used the deprecated xml attribute "password". Ensure that
+ // the inputType is correct.
+ boolean normalText = (mInputType & EditorInfo.TYPE_MASK_CLASS)
+ == EditorInfo.TYPE_CLASS_TEXT;
+ if (normalText && !isPasswordInputType(mInputType)) {
+ mInputType = (mInputType & ~(EditorInfo.TYPE_MASK_VARIATION))
+ | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD;
+ }
+ } else if (isPasswordInputType(mInputType)) {
+ // Caller did not use the deprecated xml attribute "password", but
+ // did set the input properly. Set password to true.
+ password = true;
}
if (selectallonfocus) {
@@ -884,12 +878,9 @@
drawableLeft, drawableTop, drawableRight, drawableBottom);
setCompoundDrawablePadding(drawablePadding);
- if (singleLine) {
- setSingleLine();
-
- if (mInput == null && ellipsize < 0) {
+ setSingleLine(singleLine);
+ if (singleLine && mInput == null && ellipsize < 0) {
ellipsize = 3; // END
- }
}
switch (ellipsize) {
@@ -1153,14 +1144,7 @@
} catch (IncompatibleClassChangeError e) {
mInputType = EditorInfo.TYPE_CLASS_TEXT;
}
- if ((mInputType&EditorInfo.TYPE_MASK_CLASS)
- == EditorInfo.TYPE_CLASS_TEXT) {
- if (mSingleLine) {
- mInputType &= ~EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
- } else {
- mInputType |= EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
- }
- }
+ setSingleLine(mSingleLine);
} else {
mInputType = EditorInfo.TYPE_NULL;
}
@@ -2988,6 +2972,11 @@
return mHint;
}
+ private boolean isMultilineInputType(int type) {
+ return (type & (EditorInfo.TYPE_MASK_CLASS | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE)) ==
+ (EditorInfo.TYPE_CLASS_TEXT | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE);
+ }
+
/**
* Set the type of the content with a constant as defined for
* {@link EditorInfo#inputType}. This will take care of changing
@@ -3024,17 +3013,14 @@
}
}
- boolean multiLine = (type&(EditorInfo.TYPE_MASK_CLASS
- | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE)) ==
- (EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE);
+ boolean singleLine = !isMultilineInputType(type);
// We need to update the single line mode if it has changed or we
// were previously in password mode.
- if (mSingleLine == multiLine || forceUpdate) {
+ if (mSingleLine != singleLine || forceUpdate) {
// Change single line mode, but only change the transformation if
// we are not in password mode.
- applySingleLine(!multiLine, !isPassword);
+ applySingleLine(singleLine, !isPassword);
}
InputMethodManager imm = InputMethodManager.peekInstance();
@@ -3065,7 +3051,9 @@
| EditorInfo.TYPE_MASK_VARIATION);
return variation
== (EditorInfo.TYPE_CLASS_TEXT
- | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD);
+ | EditorInfo.TYPE_TEXT_VARIATION_PASSWORD)
+ || variation == (EditorInfo.TYPE_CLASS_TEXT
+ | EditorInfo.TYPE_TEXT_VARIATION_WEB_PASSWORD);
}
private boolean isVisiblePasswordInputType(int inputType) {
@@ -4721,10 +4709,7 @@
outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_ENTER_ACTION;
}
}
- if ((outAttrs.inputType & (InputType.TYPE_MASK_CLASS
- | InputType.TYPE_TEXT_FLAG_MULTI_LINE))
- == (InputType.TYPE_CLASS_TEXT
- | InputType.TYPE_TEXT_FLAG_MULTI_LINE)) {
+ if (isMultilineInputType(outAttrs.inputType)) {
// Multi-line text editors should always show an enter key.
outAttrs.imeOptions |= EditorInfo.IME_FLAG_NO_ENTER_ACTION;
}
@@ -6067,8 +6052,7 @@
*/
@android.view.RemotableViewMethod
public void setSingleLine(boolean singleLine) {
- if ((mInputType&EditorInfo.TYPE_MASK_CLASS)
- == EditorInfo.TYPE_CLASS_TEXT) {
+ if ((mInputType & EditorInfo.TYPE_MASK_CLASS) == EditorInfo.TYPE_CLASS_TEXT) {
if (singleLine) {
mInputType &= ~EditorInfo.TYPE_TEXT_FLAG_MULTI_LINE;
} else {
@@ -6084,8 +6068,7 @@
setLines(1);
setHorizontallyScrolling(true);
if (applyTransformation) {
- setTransformationMethod(SingleLineTransformationMethod.
- getInstance());
+ setTransformationMethod(SingleLineTransformationMethod.getInstance());
}
} else {
setMaxLines(Integer.MAX_VALUE);
@@ -7359,8 +7342,10 @@
int variation = mInputType & InputType.TYPE_MASK_VARIATION;
if (variation == InputType.TYPE_TEXT_VARIATION_URI ||
variation == InputType.TYPE_TEXT_VARIATION_PASSWORD ||
+ variation == InputType.TYPE_TEXT_VARIATION_WEB_PASSWORD ||
variation == InputType.TYPE_TEXT_VARIATION_VISIBLE_PASSWORD ||
variation == InputType.TYPE_TEXT_VARIATION_EMAIL_ADDRESS ||
+ variation == InputType.TYPE_TEXT_VARIATION_WEB_EMAIL_ADDRESS ||
variation == InputType.TYPE_TEXT_VARIATION_FILTER) {
return -1;
}
@@ -8042,9 +8027,12 @@
@Override
public void onClick(View v) {
- ClipboardManager clipboard =
- (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
- paste(clipboard, getSelectionStart(), getSelectionEnd());
+ if (canPaste()) {
+ ClipboardManager clipboard =
+ (ClipboardManager) getContext().getSystemService(Context.CLIPBOARD_SERVICE);
+ paste(clipboard, getSelectionStart(), getSelectionEnd());
+ }
+ hide();
}
void positionAtCursor() {
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index 1d612e2..7cf369f 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -65,12 +65,15 @@
private ArrayList<TabImpl> mTabs = new ArrayList<TabImpl>();
private TabImpl mSelectedTab;
+ private int mSavedTabPosition = INVALID_POSITION;
private ActionMode mActionMode;
private static final int CONTEXT_DISPLAY_NORMAL = 0;
private static final int CONTEXT_DISPLAY_SPLIT = 1;
+ private static final int INVALID_POSITION = -1;
+
private int mContextDisplayMode;
private boolean mClosingContext;
@@ -183,6 +186,8 @@
selectTab(null);
}
mTabs.clear();
+ mActionView.removeAllTabs();
+ mSavedTabPosition = INVALID_POSITION;
}
public void setTitle(CharSequence title) {
@@ -310,6 +315,8 @@
@Override
public void removeTabAt(int position) {
+ int selectedTabPosition = mSelectedTab != null
+ ? mSelectedTab.getPosition() : mSavedTabPosition;
mActionView.removeTabAt(position);
mTabs.remove(position);
@@ -318,7 +325,9 @@
mTabs.get(i).setPosition(i);
}
- selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
+ if (selectedTabPosition == position) {
+ selectTab(mTabs.isEmpty() ? null : mTabs.get(Math.max(0, position - 1)));
+ }
}
@Override
@@ -333,7 +342,13 @@
@Override
public void selectTab(Tab tab) {
- final FragmentTransaction trans = mActivity.getFragmentManager().openTransaction();
+ if (getNavigationMode() != NAVIGATION_MODE_TABS) {
+ mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
+ return;
+ }
+
+ final FragmentTransaction trans = mActivity.getFragmentManager().openTransaction()
+ .disallowAddToBackStack();
if (mSelectedTab == tab) {
if (mSelectedTab != null) {
@@ -623,12 +638,52 @@
}
@Override
+ public int getTabCount() {
+ return mTabs.size();
+ }
+
+ @Override
public void setNavigationMode(int mode) {
+ final int oldMode = mActionView.getNavigationMode();
+ switch (oldMode) {
+ case NAVIGATION_MODE_TABS:
+ mSavedTabPosition = getSelectedNavigationIndex();
+ selectTab(null);
+ break;
+ }
mActionView.setNavigationMode(mode);
+ switch (mode) {
+ case NAVIGATION_MODE_TABS:
+ if (mSavedTabPosition != INVALID_POSITION) {
+ setSelectedNavigationItem(mSavedTabPosition);
+ mSavedTabPosition = INVALID_POSITION;
+ }
+ break;
+ }
}
@Override
public Tab getTabAt(int index) {
return mTabs.get(index);
}
+
+ /**
+ * This fragment is added when we're keeping a back stack in a tab switch
+ * transaction. We use it to change the selected tab in the action bar view
+ * when we back out.
+ */
+ private class SwitchSelectedTabViewFragment extends Fragment {
+ private int mSelectedTabIndex;
+
+ public SwitchSelectedTabViewFragment(int oldSelectedTab) {
+ mSelectedTabIndex = oldSelectedTab;
+ }
+
+ @Override
+ public void onDetach() {
+ if (mSelectedTabIndex >= 0 && mSelectedTabIndex < getTabCount()) {
+ mActionView.setTabSelected(mSelectedTabIndex);
+ }
+ }
+ }
}
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 00c4dbe..4ae55fc 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -259,6 +259,7 @@
File destFile = new File(sharedLibraryDir, entry.second);
copyNativeBinaryLI(zipFile, entry.first, sharedLibraryDir, destFile);
}
+ zipFile.close();
} catch (ZipException e) {
Slog.w(TAG, "Failed to extract data from package file", e);
return PackageManager.INSTALL_FAILED_INVALID_APK;
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 95d6dd3..be6a57a 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -487,6 +487,12 @@
}
}
+ public void removeAllTabs() {
+ if (mTabLayout != null) {
+ mTabLayout.removeAllViews();
+ }
+ }
+
@Override
protected LayoutParams generateDefaultLayoutParams() {
// Used by custom nav views if they don't supply layout params. Everything else
@@ -809,7 +815,9 @@
int ypos = 0;
switch (gravity & Gravity.VERTICAL_GRAVITY_MASK) {
case Gravity.CENTER_VERTICAL:
- ypos = ((mBottom - mTop) - mCustomNavView.getMeasuredHeight()) / 2;
+ final int paddedTop = mTop + getPaddingTop();
+ final int paddedBottom = mBottom - getPaddingBottom();
+ ypos = ((paddedBottom - paddedTop) - mCustomNavView.getMeasuredHeight()) / 2;
break;
case Gravity.TOP:
ypos = getPaddingTop() + topMargin;
diff --git a/core/java/com/android/internal/widget/WaveView.java b/core/java/com/android/internal/widget/WaveView.java
index f4ee7ee..f91d3d6 100644
--- a/core/java/com/android/internal/widget/WaveView.java
+++ b/core/java/com/android/internal/widget/WaveView.java
@@ -53,8 +53,10 @@
private static final int STATE_UNLOCK_SUCCESS = 5;
// Animation properties.
- private static final long DURATION = 500; // duration of transitional animations
- private static final long FINAL_DELAY = 1300; // delay for final animations
+ private static final long DURATION = 300; // duration of transitional animations
+ private static final long FINAL_DURATION = 200; // duration of final animations when unlocking
+ private static final long RING_DELAY = 1300; // when to start fading animated rings
+ private static final long FINAL_DELAY = 200; // delay for unlock success animation
private static final long SHORT_DELAY = 100; // for starting one animation after another.
private static final long WAVE_DURATION = 2000; // amount of time for way to expand/decay
private static final long RESET_TIMEOUT = 3000; // elapsed time of inactivity before we reset
@@ -299,11 +301,11 @@
// x:ringX, y:ringY, scaleX: .1, scaleY: .1, ease:Quint.easeOut});
DrawableHolder wave = mLightWaves.get(n);
long delay = 1000L*(6 + n - mCurrentWave)/10L;
- wave.addAnimTo(DURATION, delay, "x", ringX, true);
- wave.addAnimTo(DURATION, delay, "y", ringY, true);
- wave.addAnimTo(DURATION, delay, "scaleX", 0.1f, true);
- wave.addAnimTo(DURATION, delay, "scaleY", 0.1f, true);
- wave.addAnimTo(DURATION, delay, "alpha", 0.0f, true);
+ wave.addAnimTo(FINAL_DURATION, delay, "x", ringX, true);
+ wave.addAnimTo(FINAL_DURATION, delay, "y", ringY, true);
+ wave.addAnimTo(FINAL_DURATION, delay, "scaleX", 0.1f, true);
+ wave.addAnimTo(FINAL_DURATION, delay, "scaleY", 0.1f, true);
+ wave.addAnimTo(FINAL_DURATION, delay, "alpha", 0.0f, true);
}
for (int i = 0; i < mLightWaves.size(); i++) {
mLightWaves.get(i).startAnimations(this);
@@ -311,14 +313,14 @@
//TweenMax.to(unlockRing, .5, {x:ringX, y: ringY, scaleX: .1, scaleY: .1,
// alpha: 0, ease: Quint.easeOut });
- mUnlockRing.addAnimTo(DURATION, 0, "x", ringX, false);
- mUnlockRing.addAnimTo(DURATION, 0, "y", ringY, false);
- mUnlockRing.addAnimTo(DURATION, 0, "scaleX", 0.1f, false);
- mUnlockRing.addAnimTo(DURATION, 0, "scaleY", 0.1f, false);
- mUnlockRing.addAnimTo(DURATION, 0, "alpha", 0.0f, false);
+ mUnlockRing.addAnimTo(FINAL_DURATION, 0, "x", ringX, false);
+ mUnlockRing.addAnimTo(FINAL_DURATION, 0, "y", ringY, false);
+ mUnlockRing.addAnimTo(FINAL_DURATION, 0, "scaleX", 0.1f, false);
+ mUnlockRing.addAnimTo(FINAL_DURATION, 0, "scaleY", 0.1f, false);
+ mUnlockRing.addAnimTo(FINAL_DURATION, 0, "alpha", 0.0f, false);
//TweenMax.to(unlockRing, .5, { delay: 1.3, alpha: 0 , ease: Quint.easeOut });
- mUnlockRing.addAnimTo(DURATION, FINAL_DELAY, "alpha", 0.0f, false);
+ mUnlockRing.addAnimTo(FINAL_DURATION, FINAL_DELAY, "alpha", 0.0f, false);
//TweenMax.to(unlockDefault, 0, { x:ringX, y: ringY, scaleX: .1, scaleY: .1,
// alpha: 0 , overwrite: true });
@@ -332,27 +334,27 @@
//TweenMax.to(unlockDefault, .5, { x:ringX, y: ringY, scaleX: 1, scaleY: 1,
// alpha: 1 , ease: Quint.easeOut , overwrite: true });
- mUnlockDefault.addAnimTo(DURATION, 0, "x", ringX, true);
- mUnlockDefault.addAnimTo(DURATION, 0, "y", ringY, true);
- mUnlockDefault.addAnimTo(DURATION, 0, "scaleX", 1.0f, true);
- mUnlockDefault.addAnimTo(DURATION, 0, "scaleY", 1.0f, true);
- mUnlockDefault.addAnimTo(DURATION, 0, "alpha", 1.0f, true);
+ mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "x", ringX, true);
+ mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "y", ringY, true);
+ mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "scaleX", 1.0f, true);
+ mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "scaleY", 1.0f, true);
+ mUnlockDefault.addAnimTo(FINAL_DURATION, 0, "alpha", 1.0f, true);
//TweenMax.to(unlockDefault, .5, { delay: 1.3, scaleX: 3, scaleY: 3,
// alpha: 1, ease: Quint.easeOut });
- mUnlockDefault.addAnimTo(DURATION, FINAL_DELAY, "scaleX", 3.0f, false);
- mUnlockDefault.addAnimTo(DURATION, FINAL_DELAY, "scaleY", 3.0f, false);
- mUnlockDefault.addAnimTo(DURATION, FINAL_DELAY, "alpha", 1.0f, false);
+ mUnlockDefault.addAnimTo(FINAL_DURATION, FINAL_DELAY, "scaleX", 3.0f, false);
+ mUnlockDefault.addAnimTo(FINAL_DURATION, FINAL_DELAY, "scaleY", 3.0f, false);
+ mUnlockDefault.addAnimTo(FINAL_DURATION, FINAL_DELAY, "alpha", 0.0f, false);
//TweenMax.to(unlockHalo, .5, { x:ringX, y: ringY , ease: Back.easeOut });
- mUnlockHalo.addAnimTo(DURATION, 0, "x", ringX, false);
- mUnlockHalo.addAnimTo(DURATION, 0, "y", ringY, false);
+ mUnlockHalo.addAnimTo(FINAL_DURATION, 0, "x", ringX, false);
+ mUnlockHalo.addAnimTo(FINAL_DURATION, 0, "y", ringY, false);
//TweenMax.to(unlockHalo, .5, { delay: 1.3, scaleX: 3, scaleY: 3,
// alpha: 1, ease: Quint.easeOut });
- mUnlockHalo.addAnimTo(DURATION, FINAL_DELAY, "scaleX", 3.0f, false);
- mUnlockHalo.addAnimTo(DURATION, FINAL_DELAY, "scaleY", 3.0f, false);
- mUnlockHalo.addAnimTo(DURATION, FINAL_DELAY, "alpha", 1.0f, false);
+ mUnlockHalo.addAnimTo(FINAL_DURATION, FINAL_DELAY, "scaleX", 3.0f, false);
+ mUnlockHalo.addAnimTo(FINAL_DURATION, FINAL_DELAY, "scaleY", 3.0f, false);
+ mUnlockHalo.addAnimTo(FINAL_DURATION, FINAL_DELAY, "alpha", 0.0f, false);
removeCallbacks(mLockTimerActions);
@@ -437,7 +439,7 @@
//TweenMax.to(this["lightWave"+currentWave], 1, { delay: 1.3
// , alpha: 0 , ease:Quint.easeOut});
- wave.addAnimTo(1000, FINAL_DELAY, "alpha", 0.0f, false);
+ wave.addAnimTo(1000, RING_DELAY, "alpha", 0.0f, false);
wave.startAnimations(WaveView.this);
mCurrentWave = (mCurrentWave+1) % mWaveCount;
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 755f694..bcd7bae 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -144,7 +144,8 @@
android_backup_FileBackupHelperBase.cpp \
android_backup_BackupHelperDispatcher.cpp \
android_content_res_ObbScanner.cpp \
- android_content_res_Configuration.cpp
+ android_content_res_Configuration.cpp \
+ android_animation_PropertyValuesHolder.cpp
LOCAL_C_INCLUDES += \
$(JNI_H_INCLUDE) \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c38e001..1018ddb 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -171,6 +171,7 @@
extern int register_android_view_MotionEvent(JNIEnv* env);
extern int register_android_content_res_ObbScanner(JNIEnv* env);
extern int register_android_content_res_Configuration(JNIEnv* env);
+extern int register_android_animation_PropertyValuesHolder(JNIEnv *env);
static AndroidRuntime* gCurRuntime = NULL;
@@ -1291,6 +1292,8 @@
REG_JNI(register_android_content_res_ObbScanner),
REG_JNI(register_android_content_res_Configuration),
+
+ REG_JNI(register_android_animation_PropertyValuesHolder),
};
/*
diff --git a/core/jni/android_animation_PropertyValuesHolder.cpp b/core/jni/android_animation_PropertyValuesHolder.cpp
new file mode 100644
index 0000000..5991805
--- /dev/null
+++ b/core/jni/android_animation_PropertyValuesHolder.cpp
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2010 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.
+ */
+
+#include <stdio.h>
+#include <assert.h>
+
+#include "jni.h"
+#include <android_runtime/AndroidRuntime.h>
+#include <utils/misc.h>
+
+// ----------------------------------------------------------------------------
+
+namespace android {
+
+// ----------------------------------------------------------------------------
+
+const char* const kClassPathName = "android/animation/PropertyValuesHolder";
+
+static jmethodID android_animation_PropertyValuesHolder_getIntMethod(
+ JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName)
+{
+ const char *nativeString = env->GetStringUTFChars(methodName, 0);
+ jmethodID mid = env->GetMethodID(targetClass, nativeString, "(I)V");
+ env->ReleaseStringUTFChars(methodName, nativeString);
+ return mid;
+}
+
+static jmethodID android_animation_PropertyValuesHolder_getFloatMethod(
+ JNIEnv* env, jclass pvhClass, jclass targetClass, jstring methodName)
+{
+ const char *nativeString = env->GetStringUTFChars(methodName, 0);
+ jmethodID mid = env->GetMethodID(targetClass, nativeString, "(F)V");
+ env->ReleaseStringUTFChars(methodName, nativeString);
+ return mid;
+}
+
+static void android_animation_PropertyValuesHolder_callIntMethod(
+ JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, int arg)
+{
+ env->CallVoidMethod(target, methodID, arg);
+}
+
+static void android_animation_PropertyValuesHolder_callFloatMethod(
+ JNIEnv* env, jclass pvhObject, jobject target, jmethodID methodID, float arg)
+{
+ env->CallVoidMethod(target, methodID, arg);
+}
+
+static JNINativeMethod gMethods[] = {
+ { "nGetIntMethod", "(Ljava/lang/Class;Ljava/lang/String;)I",
+ (void*)android_animation_PropertyValuesHolder_getIntMethod },
+ { "nGetFloatMethod", "(Ljava/lang/Class;Ljava/lang/String;)I",
+ (void*)android_animation_PropertyValuesHolder_getFloatMethod },
+ { "nCallIntMethod", "(Ljava/lang/Object;II)V",
+ (void*)android_animation_PropertyValuesHolder_callIntMethod },
+ { "nCallFloatMethod", "(Ljava/lang/Object;IF)V",
+ (void*)android_animation_PropertyValuesHolder_callFloatMethod }
+};
+
+int register_android_animation_PropertyValuesHolder(JNIEnv* env)
+{
+ return AndroidRuntime::registerNativeMethods(env,
+ kClassPathName, gMethods, NELEM(gMethods));
+}
+
+};
diff --git a/core/res/res/drawable-en-ldpi/sym_keyboard_delete.png b/core/res/res/drawable-en-ldpi/sym_keyboard_delete.png
new file mode 100644
index 0000000..d9d5653
--- /dev/null
+++ b/core/res/res/drawable-en-ldpi/sym_keyboard_delete.png
Binary files differ
diff --git a/core/res/res/drawable-en-ldpi/sym_keyboard_feedback_delete.png b/core/res/res/drawable-en-ldpi/sym_keyboard_feedback_delete.png
new file mode 100644
index 0000000..8922bf9
--- /dev/null
+++ b/core/res/res/drawable-en-ldpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/bottombar_565.png b/core/res/res/drawable-land-ldpi/bottombar_565.png
new file mode 100644
index 0000000..112c17d
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/bottombar_565.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/btn_lock_normal.9.png b/core/res/res/drawable-land-ldpi/btn_lock_normal.9.png
new file mode 100644
index 0000000..e685adc
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/btn_lock_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/ic_jog_dial_sound_off.png b/core/res/res/drawable-land-ldpi/ic_jog_dial_sound_off.png
new file mode 100644
index 0000000..a4e3edf
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/ic_jog_dial_sound_off.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/ic_jog_dial_sound_on.png b/core/res/res/drawable-land-ldpi/ic_jog_dial_sound_on.png
new file mode 100644
index 0000000..f8190b56
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/ic_jog_dial_sound_on.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/ic_jog_dial_unlock.png b/core/res/res/drawable-land-ldpi/ic_jog_dial_unlock.png
new file mode 100644
index 0000000..16fa0db
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/ic_jog_dial_unlock.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_gray.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_gray.9.png
new file mode 100644
index 0000000..e16e9f6
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_gray.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_green.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_green.9.png
new file mode 100644
index 0000000..90211df
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_green.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_red.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_red.9.png
new file mode 100644
index 0000000..154ae8e
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_red.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_yellow.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_yellow.9.png
new file mode 100644
index 0000000..1e69e4d
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_confirm_yellow.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_normal.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_normal.9.png
new file mode 100644
index 0000000..09710a5
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_pressed.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_pressed.9.png
new file mode 100644
index 0000000..158ce85
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_left_end_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_gray.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_gray.9.png
new file mode 100644
index 0000000..1be54d4
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_gray.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_green.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_green.9.png
new file mode 100644
index 0000000..4ef4d69
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_green.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_red.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_red.9.png
new file mode 100644
index 0000000..dad283e
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_red.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_yellow.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_yellow.9.png
new file mode 100644
index 0000000..f7aa85a
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_confirm_yellow.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_normal.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_normal.9.png
new file mode 100644
index 0000000..23860ce
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_pressed.9.png b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_pressed.9.png
new file mode 100644
index 0000000..1105fe5
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_bar_right_end_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_gray.png b/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_gray.png
new file mode 100644
index 0000000..945851d
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_green.png b/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_green.png
new file mode 100644
index 0000000..0702927
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_red.png b/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_red.png
new file mode 100644
index 0000000..d79f46c
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_red.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_yellow.png b/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_yellow.png
new file mode 100644
index 0000000..8e4ef9a
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_left_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_left_normal.png b/core/res/res/drawable-land-ldpi/jog_tab_left_normal.png
new file mode 100644
index 0000000..ee6d98c
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_left_normal.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_left_pressed.png b/core/res/res/drawable-land-ldpi/jog_tab_left_pressed.png
new file mode 100644
index 0000000..727fdbb
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_left_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_gray.png b/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_gray.png
new file mode 100644
index 0000000..93d0bf4
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_green.png b/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_green.png
new file mode 100644
index 0000000..d49c831
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_red.png b/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_red.png
new file mode 100644
index 0000000..29bddcf
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_red.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_yellow.png b/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_yellow.png
new file mode 100644
index 0000000..4cefb0c
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_right_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_right_normal.png b/core/res/res/drawable-land-ldpi/jog_tab_right_normal.png
new file mode 100644
index 0000000..30fa002
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_right_normal.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_right_pressed.png b/core/res/res/drawable-land-ldpi/jog_tab_right_pressed.png
new file mode 100644
index 0000000..f2d358b
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_right_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_target_gray.png b/core/res/res/drawable-land-ldpi/jog_tab_target_gray.png
new file mode 100644
index 0000000..1e76bc1
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_target_gray.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_target_green.png b/core/res/res/drawable-land-ldpi/jog_tab_target_green.png
new file mode 100644
index 0000000..917769e
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_target_green.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_target_red.png b/core/res/res/drawable-land-ldpi/jog_tab_target_red.png
new file mode 100644
index 0000000..3501ba38
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_target_red.png
Binary files differ
diff --git a/core/res/res/drawable-land-ldpi/jog_tab_target_yellow.png b/core/res/res/drawable-land-ldpi/jog_tab_target_yellow.png
new file mode 100644
index 0000000..ee795a3
--- /dev/null
+++ b/core/res/res/drawable-land-ldpi/jog_tab_target_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/activity_title_bar.9.png b/core/res/res/drawable-ldpi/activity_title_bar.9.png
new file mode 100644
index 0000000..8aaa7d1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/activity_title_bar.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/arrow_down_float.png b/core/res/res/drawable-ldpi/arrow_down_float.png
new file mode 100644
index 0000000..c41340d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/arrow_down_float.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/arrow_up_float.png b/core/res/res/drawable-ldpi/arrow_up_float.png
new file mode 100644
index 0000000..8b60f12
--- /dev/null
+++ b/core/res/res/drawable-ldpi/arrow_up_float.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/battery_charge_background.png b/core/res/res/drawable-ldpi/battery_charge_background.png
new file mode 100644
index 0000000..503c4f9f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/battery_charge_background.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/bottom_bar.png b/core/res/res/drawable-ldpi/bottom_bar.png
new file mode 100644
index 0000000..c80fd4a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/bottom_bar.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_buttonless_off.png b/core/res/res/drawable-ldpi/btn_check_buttonless_off.png
new file mode 100644
index 0000000..327d2c6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_buttonless_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_buttonless_on.png b/core/res/res/drawable-ldpi/btn_check_buttonless_on.png
new file mode 100644
index 0000000..4d0ab2a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_buttonless_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_label_background.9.png b/core/res/res/drawable-ldpi/btn_check_label_background.9.png
new file mode 100644
index 0000000..5b08367
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_label_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_off.png b/core/res/res/drawable-ldpi/btn_check_off.png
new file mode 100644
index 0000000..f333117
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_off_disable.png b/core/res/res/drawable-ldpi/btn_check_off_disable.png
new file mode 100644
index 0000000..c4d7cd9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_off_disable.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_off_disable_focused.png b/core/res/res/drawable-ldpi/btn_check_off_disable_focused.png
new file mode 100644
index 0000000..2bc5899
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_off_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_off_pressed.png b/core/res/res/drawable-ldpi/btn_check_off_pressed.png
new file mode 100644
index 0000000..fe77b08
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_off_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_off_selected.png b/core/res/res/drawable-ldpi/btn_check_off_selected.png
new file mode 100644
index 0000000..58542c4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_off_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_on.png b/core/res/res/drawable-ldpi/btn_check_on.png
new file mode 100644
index 0000000..f4d777a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_on_disable.png b/core/res/res/drawable-ldpi/btn_check_on_disable.png
new file mode 100644
index 0000000..57513ca
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_on_disable.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_on_disable_focused.png b/core/res/res/drawable-ldpi/btn_check_on_disable_focused.png
new file mode 100644
index 0000000..798835e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_on_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_on_pressed.png b/core/res/res/drawable-ldpi/btn_check_on_pressed.png
new file mode 100644
index 0000000..0f00d17
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_on_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_check_on_selected.png b/core/res/res/drawable-ldpi/btn_check_on_selected.png
new file mode 100644
index 0000000..51b3566
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_check_on_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_circle_disable.png b/core/res/res/drawable-ldpi/btn_circle_disable.png
new file mode 100644
index 0000000..87a51c5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_circle_disable.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_circle_disable_focused.png b/core/res/res/drawable-ldpi/btn_circle_disable_focused.png
new file mode 100644
index 0000000..cc28e3b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_circle_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_circle_normal.png b/core/res/res/drawable-ldpi/btn_circle_normal.png
new file mode 100644
index 0000000..b25ad81
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_circle_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_circle_pressed.png b/core/res/res/drawable-ldpi/btn_circle_pressed.png
new file mode 100644
index 0000000..abeedad
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_circle_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_circle_selected.png b/core/res/res/drawable-ldpi/btn_circle_selected.png
new file mode 100644
index 0000000..e3e8d13
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_circle_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_close_normal.png b/core/res/res/drawable-ldpi/btn_close_normal.png
new file mode 100644
index 0000000..e4de088
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_close_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_close_pressed.png b/core/res/res/drawable-ldpi/btn_close_pressed.png
new file mode 100644
index 0000000..5d946bd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_close_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_close_selected.png b/core/res/res/drawable-ldpi/btn_close_selected.png
new file mode 100644
index 0000000..c1ee5a8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_close_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_code_lock_default.png b/core/res/res/drawable-ldpi/btn_code_lock_default.png
new file mode 100644
index 0000000..149da9b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_code_lock_default.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_code_lock_touched.png b/core/res/res/drawable-ldpi/btn_code_lock_touched.png
new file mode 100644
index 0000000..ad9a313
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_code_lock_touched.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_normal.9.png b/core/res/res/drawable-ldpi/btn_default_normal.9.png
new file mode 100644
index 0000000..198da17
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_normal_disable.9.png b/core/res/res/drawable-ldpi/btn_default_normal_disable.9.png
new file mode 100644
index 0000000..2e61b50
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_normal_disable.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_normal_disable_focused.9.png b/core/res/res/drawable-ldpi/btn_default_normal_disable_focused.9.png
new file mode 100644
index 0000000..9fab12e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_normal_disable_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_pressed.9.png b/core/res/res/drawable-ldpi/btn_default_pressed.9.png
new file mode 100644
index 0000000..f5a21b2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_selected.9.png b/core/res/res/drawable-ldpi/btn_default_selected.9.png
new file mode 100644
index 0000000..a09da00
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_small_normal.9.png b/core/res/res/drawable-ldpi/btn_default_small_normal.9.png
new file mode 100644
index 0000000..4e69058
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_small_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_small_normal_disable.9.png b/core/res/res/drawable-ldpi/btn_default_small_normal_disable.9.png
new file mode 100644
index 0000000..64fce65
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_small_normal_disable.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_small_normal_disable_focused.9.png b/core/res/res/drawable-ldpi/btn_default_small_normal_disable_focused.9.png
new file mode 100644
index 0000000..528b5e1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_small_normal_disable_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_small_pressed.9.png b/core/res/res/drawable-ldpi/btn_default_small_pressed.9.png
new file mode 100644
index 0000000..bf70128
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_small_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_small_selected.9.png b/core/res/res/drawable-ldpi/btn_default_small_selected.9.png
new file mode 100644
index 0000000..71938d0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_small_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_default_transparent_normal.9.png b/core/res/res/drawable-ldpi/btn_default_transparent_normal.9.png
new file mode 100644
index 0000000..2c7249e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_default_transparent_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dialog_disable.png b/core/res/res/drawable-ldpi/btn_dialog_disable.png
new file mode 100644
index 0000000..82d13f2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dialog_disable.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dialog_normal.png b/core/res/res/drawable-ldpi/btn_dialog_normal.png
new file mode 100644
index 0000000..e4de088
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dialog_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dialog_pressed.png b/core/res/res/drawable-ldpi/btn_dialog_pressed.png
new file mode 100644
index 0000000..557c13a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dialog_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dialog_selected.png b/core/res/res/drawable-ldpi/btn_dialog_selected.png
new file mode 100644
index 0000000..f63ce27
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dialog_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dropdown_disabled.9.png b/core/res/res/drawable-ldpi/btn_dropdown_disabled.9.png
new file mode 100644
index 0000000..27cb8f5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dropdown_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dropdown_disabled_focused.9.png b/core/res/res/drawable-ldpi/btn_dropdown_disabled_focused.9.png
new file mode 100644
index 0000000..a0231c5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dropdown_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dropdown_normal.9.png b/core/res/res/drawable-ldpi/btn_dropdown_normal.9.png
new file mode 100644
index 0000000..b23e10ffa
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dropdown_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dropdown_pressed.9.png b/core/res/res/drawable-ldpi/btn_dropdown_pressed.9.png
new file mode 100644
index 0000000..c3c08e4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dropdown_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_dropdown_selected.9.png b/core/res/res/drawable-ldpi/btn_dropdown_selected.9.png
new file mode 100644
index 0000000..2660e43
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_dropdown_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_erase_default.9.png b/core/res/res/drawable-ldpi/btn_erase_default.9.png
new file mode 100644
index 0000000..dc592ca
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_erase_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_erase_pressed.9.png b/core/res/res/drawable-ldpi/btn_erase_pressed.9.png
new file mode 100644
index 0000000..48c0570
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_erase_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_erase_selected.9.png b/core/res/res/drawable-ldpi/btn_erase_selected.9.png
new file mode 100644
index 0000000..51f7b86
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_erase_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_global_search_normal.9.png b/core/res/res/drawable-ldpi/btn_global_search_normal.9.png
new file mode 100644
index 0000000..60bd3ce
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_global_search_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal.9.png
new file mode 100644
index 0000000..8cf50b8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal_off.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal_off.9.png
new file mode 100644
index 0000000..d853bf1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal_on.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal_on.9.png
new file mode 100644
index 0000000..f54e948
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed.9.png
new file mode 100644
index 0000000..ad7c951
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed_off.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed_off.9.png
new file mode 100644
index 0000000..1a075d29
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed_on.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed_on.9.png
new file mode 100644
index 0000000..5933f61
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_fulltrans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_normal.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_normal.9.png
new file mode 100644
index 0000000..69db65f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_normal_off.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_normal_off.9.png
new file mode 100644
index 0000000..37c5fed
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_normal_on.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_normal_on.9.png
new file mode 100644
index 0000000..019e6f7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_pressed.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_pressed.9.png
new file mode 100644
index 0000000..d3827f0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_pressed_off.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_pressed_off.9.png
new file mode 100644
index 0000000..2bef004
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_pressed_on.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_pressed_on.9.png
new file mode 100644
index 0000000..25daabe
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal.9.png
new file mode 100644
index 0000000..9d026c4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal_off.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal_off.9.png
new file mode 100644
index 0000000..6ededbe
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal_on.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal_on.9.png
new file mode 100644
index 0000000..987014f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed.9.png
new file mode 100644
index 0000000..d19a0fcc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed_off.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed_off.9.png
new file mode 100644
index 0000000..978ff4c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed_on.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed_on.9.png
new file mode 100644
index 0000000..8355c7d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_keyboard_key_trans_selected.9.png b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_selected.9.png
new file mode 100644
index 0000000..8afb908
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_keyboard_key_trans_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_media_player.9.png b/core/res/res/drawable-ldpi/btn_media_player.9.png
new file mode 100644
index 0000000..7096dbc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_media_player.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_media_player_disabled.9.png b/core/res/res/drawable-ldpi/btn_media_player_disabled.9.png
new file mode 100644
index 0000000..83b1059
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_media_player_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_media_player_disabled_selected.9.png b/core/res/res/drawable-ldpi/btn_media_player_disabled_selected.9.png
new file mode 100644
index 0000000..f55ac21
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_media_player_disabled_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_media_player_pressed.9.png b/core/res/res/drawable-ldpi/btn_media_player_pressed.9.png
new file mode 100644
index 0000000..de58ee2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_media_player_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_media_player_selected.9.png b/core/res/res/drawable-ldpi/btn_media_player_selected.9.png
new file mode 100644
index 0000000..5443580
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_media_player_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_minus_default.png b/core/res/res/drawable-ldpi/btn_minus_default.png
new file mode 100644
index 0000000..19c66e0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_minus_default.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_minus_disable.png b/core/res/res/drawable-ldpi/btn_minus_disable.png
new file mode 100644
index 0000000..7b91ea6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_minus_disable.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_minus_disable_focused.png b/core/res/res/drawable-ldpi/btn_minus_disable_focused.png
new file mode 100644
index 0000000..a347e34
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_minus_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_minus_pressed.png b/core/res/res/drawable-ldpi/btn_minus_pressed.png
new file mode 100644
index 0000000..aaa9746
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_minus_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_minus_selected.png b/core/res/res/drawable-ldpi/btn_minus_selected.png
new file mode 100644
index 0000000..29c6962
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_minus_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_plus_default.png b/core/res/res/drawable-ldpi/btn_plus_default.png
new file mode 100644
index 0000000..8a5c600
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_plus_default.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_plus_disable.png b/core/res/res/drawable-ldpi/btn_plus_disable.png
new file mode 100644
index 0000000..1903ffa
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_plus_disable.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_plus_disable_focused.png b/core/res/res/drawable-ldpi/btn_plus_disable_focused.png
new file mode 100644
index 0000000..92f228a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_plus_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_plus_pressed.png b/core/res/res/drawable-ldpi/btn_plus_pressed.png
new file mode 100644
index 0000000..28f4e02
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_plus_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_plus_selected.png b/core/res/res/drawable-ldpi/btn_plus_selected.png
new file mode 100644
index 0000000..c6fab19
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_plus_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_label_background.9.png b/core/res/res/drawable-ldpi/btn_radio_label_background.9.png
new file mode 100644
index 0000000..d04c41f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_label_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_off.png b/core/res/res/drawable-ldpi/btn_radio_off.png
new file mode 100644
index 0000000..6df3b0d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_off_pressed.png b/core/res/res/drawable-ldpi/btn_radio_off_pressed.png
new file mode 100644
index 0000000..4848ff0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_off_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_off_selected.png b/core/res/res/drawable-ldpi/btn_radio_off_selected.png
new file mode 100644
index 0000000..9336722
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_off_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_on.png b/core/res/res/drawable-ldpi/btn_radio_on.png
new file mode 100644
index 0000000..65e5791
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_on_pressed.png b/core/res/res/drawable-ldpi/btn_radio_on_pressed.png
new file mode 100644
index 0000000..4856c32
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_on_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_radio_on_selected.png b/core/res/res/drawable-ldpi/btn_radio_on_selected.png
new file mode 100644
index 0000000..8b19dc7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_radio_on_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_rating_star_off_normal.png b/core/res/res/drawable-ldpi/btn_rating_star_off_normal.png
new file mode 100644
index 0000000..5967bd3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_rating_star_off_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_rating_star_off_pressed.png b/core/res/res/drawable-ldpi/btn_rating_star_off_pressed.png
new file mode 100644
index 0000000..209e6a4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_rating_star_off_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_rating_star_off_selected.png b/core/res/res/drawable-ldpi/btn_rating_star_off_selected.png
new file mode 100644
index 0000000..c095f7f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_rating_star_off_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_rating_star_on_normal.png b/core/res/res/drawable-ldpi/btn_rating_star_on_normal.png
new file mode 100644
index 0000000..89d26129
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_rating_star_on_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_rating_star_on_pressed.png b/core/res/res/drawable-ldpi/btn_rating_star_on_pressed.png
new file mode 100644
index 0000000..6386eaa
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_rating_star_on_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_rating_star_on_selected.png b/core/res/res/drawable-ldpi/btn_rating_star_on_selected.png
new file mode 100644
index 0000000..e1edf4e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_rating_star_on_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_search_dialog_default.9.png b/core/res/res/drawable-ldpi/btn_search_dialog_default.9.png
new file mode 100644
index 0000000..35111b7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_search_dialog_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_search_dialog_pressed.9.png b/core/res/res/drawable-ldpi/btn_search_dialog_pressed.9.png
new file mode 100644
index 0000000..8ca4c65
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_search_dialog_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_search_dialog_selected.9.png b/core/res/res/drawable-ldpi/btn_search_dialog_selected.9.png
new file mode 100644
index 0000000..0bee0b7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_search_dialog_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_search_dialog_voice_default.9.png b/core/res/res/drawable-ldpi/btn_search_dialog_voice_default.9.png
new file mode 100644
index 0000000..f9e7298
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_search_dialog_voice_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_search_dialog_voice_pressed.9.png b/core/res/res/drawable-ldpi/btn_search_dialog_voice_pressed.9.png
new file mode 100644
index 0000000..a130f65
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_search_dialog_voice_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_search_dialog_voice_selected.9.png b/core/res/res/drawable-ldpi/btn_search_dialog_voice_selected.9.png
new file mode 100644
index 0000000..c055bfe
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_search_dialog_voice_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_square_overlay_disabled.png b/core/res/res/drawable-ldpi/btn_square_overlay_disabled.png
new file mode 100644
index 0000000..3b60946
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_square_overlay_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_square_overlay_disabled_focused.png b/core/res/res/drawable-ldpi/btn_square_overlay_disabled_focused.png
new file mode 100644
index 0000000..a36a9dd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_square_overlay_disabled_focused.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_square_overlay_normal.png b/core/res/res/drawable-ldpi/btn_square_overlay_normal.png
new file mode 100644
index 0000000..4537623
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_square_overlay_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_square_overlay_pressed.png b/core/res/res/drawable-ldpi/btn_square_overlay_pressed.png
new file mode 100644
index 0000000..62f2246
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_square_overlay_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_square_overlay_selected.png b/core/res/res/drawable-ldpi/btn_square_overlay_selected.png
new file mode 100644
index 0000000..264d3fa
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_square_overlay_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_off.png b/core/res/res/drawable-ldpi/btn_star_big_off.png
new file mode 100644
index 0000000..f0f1eb8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_off_disable.png b/core/res/res/drawable-ldpi/btn_star_big_off_disable.png
new file mode 100644
index 0000000..c6f2e20
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_off_disable.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_off_disable_focused.png b/core/res/res/drawable-ldpi/btn_star_big_off_disable_focused.png
new file mode 100644
index 0000000..228a84e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_off_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_off_pressed.png b/core/res/res/drawable-ldpi/btn_star_big_off_pressed.png
new file mode 100644
index 0000000..041f81a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_off_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_off_selected.png b/core/res/res/drawable-ldpi/btn_star_big_off_selected.png
new file mode 100644
index 0000000..adc8151
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_off_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_on.png b/core/res/res/drawable-ldpi/btn_star_big_on.png
new file mode 100644
index 0000000..cf5ed35
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_on_disable.png b/core/res/res/drawable-ldpi/btn_star_big_on_disable.png
new file mode 100644
index 0000000..53e6c65
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_on_disable.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_on_disable_focused.png b/core/res/res/drawable-ldpi/btn_star_big_on_disable_focused.png
new file mode 100644
index 0000000..8535013
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_on_disable_focused.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_on_pressed.png b/core/res/res/drawable-ldpi/btn_star_big_on_pressed.png
new file mode 100644
index 0000000..272787f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_on_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_big_on_selected.png b/core/res/res/drawable-ldpi/btn_star_big_on_selected.png
new file mode 100644
index 0000000..938d743
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_big_on_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_star_label_background.9.png b/core/res/res/drawable-ldpi/btn_star_label_background.9.png
new file mode 100644
index 0000000..3bc13c8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_star_label_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_toggle_off.9.png b/core/res/res/drawable-ldpi/btn_toggle_off.9.png
new file mode 100644
index 0000000..d0245ff
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_toggle_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_toggle_on.9.png b/core/res/res/drawable-ldpi/btn_toggle_on.9.png
new file mode 100644
index 0000000..0987759
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_toggle_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_down_disabled.9.png b/core/res/res/drawable-ldpi/btn_zoom_down_disabled.9.png
new file mode 100644
index 0000000..0346abc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_down_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_down_disabled_focused.9.png b/core/res/res/drawable-ldpi/btn_zoom_down_disabled_focused.9.png
new file mode 100644
index 0000000..b03aa1b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_down_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_down_normal.9.png b/core/res/res/drawable-ldpi/btn_zoom_down_normal.9.png
new file mode 100644
index 0000000..aa2464c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_down_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_down_pressed.9.png b/core/res/res/drawable-ldpi/btn_zoom_down_pressed.9.png
new file mode 100644
index 0000000..caa4d30
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_down_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_down_selected.9.png b/core/res/res/drawable-ldpi/btn_zoom_down_selected.9.png
new file mode 100644
index 0000000..b814785
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_down_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_page_normal.png b/core/res/res/drawable-ldpi/btn_zoom_page_normal.png
new file mode 100644
index 0000000..453bf40
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_page_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_page_press.png b/core/res/res/drawable-ldpi/btn_zoom_page_press.png
new file mode 100644
index 0000000..82c29c8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_page_press.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_up_disabled.9.png b/core/res/res/drawable-ldpi/btn_zoom_up_disabled.9.png
new file mode 100644
index 0000000..e64f178
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_up_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_up_disabled_focused.9.png b/core/res/res/drawable-ldpi/btn_zoom_up_disabled_focused.9.png
new file mode 100644
index 0000000..3b21d0a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_up_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_up_normal.9.png b/core/res/res/drawable-ldpi/btn_zoom_up_normal.9.png
new file mode 100644
index 0000000..f4b56d5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_up_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_up_pressed.9.png b/core/res/res/drawable-ldpi/btn_zoom_up_pressed.9.png
new file mode 100644
index 0000000..45c668c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_up_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/btn_zoom_up_selected.9.png b/core/res/res/drawable-ldpi/btn_zoom_up_selected.9.png
new file mode 100644
index 0000000..1a07a52
--- /dev/null
+++ b/core/res/res/drawable-ldpi/btn_zoom_up_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/button_onoff_indicator_off.png b/core/res/res/drawable-ldpi/button_onoff_indicator_off.png
new file mode 100644
index 0000000..7946356
--- /dev/null
+++ b/core/res/res/drawable-ldpi/button_onoff_indicator_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/button_onoff_indicator_on.png b/core/res/res/drawable-ldpi/button_onoff_indicator_on.png
new file mode 100644
index 0000000..6b817d5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/button_onoff_indicator_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/call_contact.png b/core/res/res/drawable-ldpi/call_contact.png
new file mode 100644
index 0000000..bee1d20
--- /dev/null
+++ b/core/res/res/drawable-ldpi/call_contact.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/checkbox_off_background.png b/core/res/res/drawable-ldpi/checkbox_off_background.png
new file mode 100644
index 0000000..ab77983
--- /dev/null
+++ b/core/res/res/drawable-ldpi/checkbox_off_background.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/checkbox_on_background.png b/core/res/res/drawable-ldpi/checkbox_on_background.png
new file mode 100644
index 0000000..dd92a4c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/checkbox_on_background.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/clock_dial.png b/core/res/res/drawable-ldpi/clock_dial.png
new file mode 100644
index 0000000..cbc9961
--- /dev/null
+++ b/core/res/res/drawable-ldpi/clock_dial.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/clock_hand_hour.png b/core/res/res/drawable-ldpi/clock_hand_hour.png
new file mode 100644
index 0000000..3362fd0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/clock_hand_hour.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/clock_hand_minute.png b/core/res/res/drawable-ldpi/clock_hand_minute.png
new file mode 100644
index 0000000..5c73d45
--- /dev/null
+++ b/core/res/res/drawable-ldpi/clock_hand_minute.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/code_lock_bottom.9.png b/core/res/res/drawable-ldpi/code_lock_bottom.9.png
new file mode 100644
index 0000000..dddac51
--- /dev/null
+++ b/core/res/res/drawable-ldpi/code_lock_bottom.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/code_lock_left.9.png b/core/res/res/drawable-ldpi/code_lock_left.9.png
new file mode 100644
index 0000000..8834f74
--- /dev/null
+++ b/core/res/res/drawable-ldpi/code_lock_left.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/code_lock_top.9.png b/core/res/res/drawable-ldpi/code_lock_top.9.png
new file mode 100644
index 0000000..2a5e353
--- /dev/null
+++ b/core/res/res/drawable-ldpi/code_lock_top.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/compass_arrow.png b/core/res/res/drawable-ldpi/compass_arrow.png
new file mode 100644
index 0000000..f59015c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/compass_arrow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/compass_base.png b/core/res/res/drawable-ldpi/compass_base.png
new file mode 100644
index 0000000..a2eeb07
--- /dev/null
+++ b/core/res/res/drawable-ldpi/compass_base.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/contact_header_bg.9.png b/core/res/res/drawable-ldpi/contact_header_bg.9.png
new file mode 100644
index 0000000..20f0cd3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/contact_header_bg.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/create_contact.png b/core/res/res/drawable-ldpi/create_contact.png
new file mode 100644
index 0000000..c920ef4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/create_contact.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/dark_header.9.png b/core/res/res/drawable-ldpi/dark_header.9.png
new file mode 100644
index 0000000..88fa160
--- /dev/null
+++ b/core/res/res/drawable-ldpi/dark_header.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/dialog_divider_horizontal_light.9.png b/core/res/res/drawable-ldpi/dialog_divider_horizontal_light.9.png
new file mode 100644
index 0000000..75a1534
--- /dev/null
+++ b/core/res/res/drawable-ldpi/dialog_divider_horizontal_light.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_horizontal_bright.9.png b/core/res/res/drawable-ldpi/divider_horizontal_bright.9.png
new file mode 100644
index 0000000..24f2a3f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_horizontal_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_horizontal_bright_opaque.9.png b/core/res/res/drawable-ldpi/divider_horizontal_bright_opaque.9.png
new file mode 100644
index 0000000..24f2a3f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_horizontal_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_horizontal_dark.9.png b/core/res/res/drawable-ldpi/divider_horizontal_dark.9.png
new file mode 100644
index 0000000..470be26
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_horizontal_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_horizontal_dark_opaque.9.png b/core/res/res/drawable-ldpi/divider_horizontal_dark_opaque.9.png
new file mode 100644
index 0000000..24f2a3f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_horizontal_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_horizontal_dim_dark.9.png b/core/res/res/drawable-ldpi/divider_horizontal_dim_dark.9.png
new file mode 100644
index 0000000..e04b49d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_horizontal_dim_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_horizontal_textfield.9.png b/core/res/res/drawable-ldpi/divider_horizontal_textfield.9.png
new file mode 100644
index 0000000..547b180
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_horizontal_textfield.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_vertical_bright.9.png b/core/res/res/drawable-ldpi/divider_vertical_bright.9.png
new file mode 100644
index 0000000..c85f7ab
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_vertical_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_vertical_bright_opaque.9.png b/core/res/res/drawable-ldpi/divider_vertical_bright_opaque.9.png
new file mode 100644
index 0000000..662e033
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_vertical_bright_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_vertical_dark.9.png b/core/res/res/drawable-ldpi/divider_vertical_dark.9.png
new file mode 100644
index 0000000..470be26
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_vertical_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/divider_vertical_dark_opaque.9.png b/core/res/res/drawable-ldpi/divider_vertical_dark_opaque.9.png
new file mode 100644
index 0000000..94d2fda
--- /dev/null
+++ b/core/res/res/drawable-ldpi/divider_vertical_dark_opaque.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/editbox_background_focus_yellow.9.png b/core/res/res/drawable-ldpi/editbox_background_focus_yellow.9.png
new file mode 100644
index 0000000..f8d65bc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/editbox_background_focus_yellow.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/editbox_background_normal.9.png b/core/res/res/drawable-ldpi/editbox_background_normal.9.png
new file mode 100644
index 0000000..f8fb178
--- /dev/null
+++ b/core/res/res/drawable-ldpi/editbox_background_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/editbox_dropdown_background.9.png b/core/res/res/drawable-ldpi/editbox_dropdown_background.9.png
new file mode 100644
index 0000000..8717d34
--- /dev/null
+++ b/core/res/res/drawable-ldpi/editbox_dropdown_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/editbox_dropdown_background_dark.9.png b/core/res/res/drawable-ldpi/editbox_dropdown_background_dark.9.png
new file mode 100644
index 0000000..18885fc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/editbox_dropdown_background_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_angel.png b/core/res/res/drawable-ldpi/emo_im_angel.png
new file mode 100644
index 0000000..eb74cb3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_angel.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_cool.png b/core/res/res/drawable-ldpi/emo_im_cool.png
new file mode 100644
index 0000000..657de3b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_cool.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_crying.png b/core/res/res/drawable-ldpi/emo_im_crying.png
new file mode 100644
index 0000000..292cf0c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_crying.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_foot_in_mouth.png b/core/res/res/drawable-ldpi/emo_im_foot_in_mouth.png
new file mode 100644
index 0000000..b1d9983
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_foot_in_mouth.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_happy.png b/core/res/res/drawable-ldpi/emo_im_happy.png
new file mode 100644
index 0000000..b34a54b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_happy.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_kissing.png b/core/res/res/drawable-ldpi/emo_im_kissing.png
new file mode 100644
index 0000000..d8aaf11
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_kissing.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_laughing.png b/core/res/res/drawable-ldpi/emo_im_laughing.png
new file mode 100644
index 0000000..41ddb6f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_laughing.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_lips_are_sealed.png b/core/res/res/drawable-ldpi/emo_im_lips_are_sealed.png
new file mode 100644
index 0000000..85d0c42
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_lips_are_sealed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_money_mouth.png b/core/res/res/drawable-ldpi/emo_im_money_mouth.png
new file mode 100644
index 0000000..b04a56c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_money_mouth.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_sad.png b/core/res/res/drawable-ldpi/emo_im_sad.png
new file mode 100644
index 0000000..e978231
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_sad.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_surprised.png b/core/res/res/drawable-ldpi/emo_im_surprised.png
new file mode 100644
index 0000000..6f9c8d9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_surprised.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_tongue_sticking_out.png b/core/res/res/drawable-ldpi/emo_im_tongue_sticking_out.png
new file mode 100644
index 0000000..c62447c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_tongue_sticking_out.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_undecided.png b/core/res/res/drawable-ldpi/emo_im_undecided.png
new file mode 100644
index 0000000..27c4ca3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_undecided.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_winking.png b/core/res/res/drawable-ldpi/emo_im_winking.png
new file mode 100644
index 0000000..97b180f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_winking.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_wtf.png b/core/res/res/drawable-ldpi/emo_im_wtf.png
new file mode 100644
index 0000000..8d6a307
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_wtf.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/emo_im_yelling.png b/core/res/res/drawable-ldpi/emo_im_yelling.png
new file mode 100644
index 0000000..ce74375
--- /dev/null
+++ b/core/res/res/drawable-ldpi/emo_im_yelling.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/expander_ic_maximized.9.png b/core/res/res/drawable-ldpi/expander_ic_maximized.9.png
new file mode 100644
index 0000000..732a6f5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/expander_ic_maximized.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/expander_ic_minimized.9.png b/core/res/res/drawable-ldpi/expander_ic_minimized.9.png
new file mode 100644
index 0000000..054e3a4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/expander_ic_minimized.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/focused_application_background_static.png b/core/res/res/drawable-ldpi/focused_application_background_static.png
new file mode 100644
index 0000000..8738bad
--- /dev/null
+++ b/core/res/res/drawable-ldpi/focused_application_background_static.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/frame_gallery_thumb.9.png b/core/res/res/drawable-ldpi/frame_gallery_thumb.9.png
new file mode 100644
index 0000000..d686b77
--- /dev/null
+++ b/core/res/res/drawable-ldpi/frame_gallery_thumb.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/frame_gallery_thumb_pressed.9.png b/core/res/res/drawable-ldpi/frame_gallery_thumb_pressed.9.png
new file mode 100644
index 0000000..c33048a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/frame_gallery_thumb_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/frame_gallery_thumb_selected.9.png b/core/res/res/drawable-ldpi/frame_gallery_thumb_selected.9.png
new file mode 100644
index 0000000..8c4adbc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/frame_gallery_thumb_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/gallery_selected_default.9.png b/core/res/res/drawable-ldpi/gallery_selected_default.9.png
new file mode 100644
index 0000000..3d55225b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/gallery_selected_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/gallery_selected_focused.9.png b/core/res/res/drawable-ldpi/gallery_selected_focused.9.png
new file mode 100644
index 0000000..31aabc2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/gallery_selected_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/gallery_selected_pressed.9.png b/core/res/res/drawable-ldpi/gallery_selected_pressed.9.png
new file mode 100644
index 0000000..d05a36f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/gallery_selected_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/gallery_unselected_default.9.png b/core/res/res/drawable-ldpi/gallery_unselected_default.9.png
new file mode 100644
index 0000000..179c32c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/gallery_unselected_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/gallery_unselected_pressed.9.png b/core/res/res/drawable-ldpi/gallery_unselected_pressed.9.png
new file mode 100644
index 0000000..0e3f652
--- /dev/null
+++ b/core/res/res/drawable-ldpi/gallery_unselected_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/grid_selector_background_focus.9.png b/core/res/res/drawable-ldpi/grid_selector_background_focus.9.png
new file mode 100644
index 0000000..87d47ca
--- /dev/null
+++ b/core/res/res/drawable-ldpi/grid_selector_background_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/grid_selector_background_pressed.9.png b/core/res/res/drawable-ldpi/grid_selector_background_pressed.9.png
new file mode 100644
index 0000000..f2cc507
--- /dev/null
+++ b/core/res/res/drawable-ldpi/grid_selector_background_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/highlight_disabled.9.png b/core/res/res/drawable-ldpi/highlight_disabled.9.png
new file mode 100644
index 0000000..473bdf6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/highlight_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/highlight_pressed.9.png b/core/res/res/drawable-ldpi/highlight_pressed.9.png
new file mode 100644
index 0000000..0ebfbde
--- /dev/null
+++ b/core/res/res/drawable-ldpi/highlight_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/highlight_selected.9.png b/core/res/res/drawable-ldpi/highlight_selected.9.png
new file mode 100644
index 0000000..a4df027
--- /dev/null
+++ b/core/res/res/drawable-ldpi/highlight_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_aggregated.png b/core/res/res/drawable-ldpi/ic_aggregated.png
new file mode 100644
index 0000000..fdb2e90
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_aggregated.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_round_more_disabled.png b/core/res/res/drawable-ldpi/ic_btn_round_more_disabled.png
new file mode 100644
index 0000000..99c7a2f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_round_more_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_round_more_normal.png b/core/res/res/drawable-ldpi/ic_btn_round_more_normal.png
new file mode 100644
index 0000000..a8cb6d5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_round_more_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_search.png b/core/res/res/drawable-ldpi/ic_btn_search.png
new file mode 100644
index 0000000..bdefbf5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_search.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_search_go.png b/core/res/res/drawable-ldpi/ic_btn_search_go.png
new file mode 100644
index 0000000..94e5555
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_search_go.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_speak_now.png b/core/res/res/drawable-ldpi/ic_btn_speak_now.png
new file mode 100644
index 0000000..106e8e6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_speak_now.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_fit_page_disabled.png b/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_fit_page_disabled.png
new file mode 100644
index 0000000..ef71e6c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_fit_page_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_fit_page_normal.png b/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_fit_page_normal.png
new file mode 100644
index 0000000..fc1531c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_fit_page_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_page_overview_disabled.png b/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_page_overview_disabled.png
new file mode 100644
index 0000000..84fcf0a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_page_overview_disabled.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_page_overview_normal.png b/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_page_overview_normal.png
new file mode 100644
index 0000000..70fc818
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_btn_square_browser_zoom_page_overview_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_bullet_key_permission.png b/core/res/res/drawable-ldpi/ic_bullet_key_permission.png
new file mode 100644
index 0000000..016c0f0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_bullet_key_permission.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_contact_picture.png b/core/res/res/drawable-ldpi/ic_contact_picture.png
new file mode 100644
index 0000000..a0444e4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_contact_picture.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_contact_picture_2.png b/core/res/res/drawable-ldpi/ic_contact_picture_2.png
new file mode 100644
index 0000000..42e8d86
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_contact_picture_2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_contact_picture_3.png b/core/res/res/drawable-ldpi/ic_contact_picture_3.png
new file mode 100644
index 0000000..c9c0a65
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_contact_picture_3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_delete.png b/core/res/res/drawable-ldpi/ic_delete.png
new file mode 100644
index 0000000..a4cefa8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_delete.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_alert.png b/core/res/res/drawable-ldpi/ic_dialog_alert.png
new file mode 100644
index 0000000..6c3c624
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_dialog_alert.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_dialer.png b/core/res/res/drawable-ldpi/ic_dialog_dialer.png
new file mode 100644
index 0000000..066efef
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_dialog_dialer.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_email.png b/core/res/res/drawable-ldpi/ic_dialog_email.png
new file mode 100644
index 0000000..194222e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_dialog_email.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_info.png b/core/res/res/drawable-ldpi/ic_dialog_info.png
new file mode 100644
index 0000000..a1dcc5a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_dialog_info.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_map.png b/core/res/res/drawable-ldpi/ic_dialog_map.png
new file mode 100644
index 0000000..9b04476
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_dialog_map.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_time.png b/core/res/res/drawable-ldpi/ic_dialog_time.png
new file mode 100644
index 0000000..5b8722b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_dialog_time.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_dialog_usb.png b/core/res/res/drawable-ldpi/ic_dialog_usb.png
new file mode 100644
index 0000000..eeef46e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_dialog_usb.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_emergency.png b/core/res/res/drawable-ldpi/ic_emergency.png
new file mode 100644
index 0000000..5c4ed5d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_emergency.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_input_add.png b/core/res/res/drawable-ldpi/ic_input_add.png
new file mode 100644
index 0000000..04cc27a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_input_add.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_input_delete.png b/core/res/res/drawable-ldpi/ic_input_delete.png
new file mode 100644
index 0000000..d7eff17
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_input_delete.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_input_get.png b/core/res/res/drawable-ldpi/ic_input_get.png
new file mode 100644
index 0000000..4452993
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_input_get.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_jog_dial_answer.png b/core/res/res/drawable-ldpi/ic_jog_dial_answer.png
new file mode 100644
index 0000000..9c5800a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_jog_dial_answer.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_jog_dial_answer_and_end.png b/core/res/res/drawable-ldpi/ic_jog_dial_answer_and_end.png
new file mode 100644
index 0000000..117c6d8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_jog_dial_answer_and_end.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_jog_dial_answer_and_hold.png b/core/res/res/drawable-ldpi/ic_jog_dial_answer_and_hold.png
new file mode 100644
index 0000000..08280e3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_jog_dial_answer_and_hold.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_jog_dial_decline.png b/core/res/res/drawable-ldpi/ic_jog_dial_decline.png
new file mode 100644
index 0000000..7ccc1ca
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_jog_dial_decline.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_jog_dial_sound_off.png b/core/res/res/drawable-ldpi/ic_jog_dial_sound_off.png
new file mode 100644
index 0000000..a4e3edf
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_jog_dial_sound_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_jog_dial_sound_on.png b/core/res/res/drawable-ldpi/ic_jog_dial_sound_on.png
new file mode 100644
index 0000000..f8190b56
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_jog_dial_sound_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_jog_dial_unlock.png b/core/res/res/drawable-ldpi/ic_jog_dial_unlock.png
new file mode 100644
index 0000000..16fa0db
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_jog_dial_unlock.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_jog_dial_vibrate_on.png b/core/res/res/drawable-ldpi/ic_jog_dial_vibrate_on.png
new file mode 100644
index 0000000..ac5a9b9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_jog_dial_vibrate_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_launcher_android.png b/core/res/res/drawable-ldpi/ic_launcher_android.png
new file mode 100644
index 0000000..628a8de
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_launcher_android.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_airplane_mode.png b/core/res/res/drawable-ldpi/ic_lock_airplane_mode.png
new file mode 100644
index 0000000..65a101b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_airplane_mode.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_airplane_mode_off.png b/core/res/res/drawable-ldpi/ic_lock_airplane_mode_off.png
new file mode 100644
index 0000000..11adeb8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_airplane_mode_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_idle_alarm.png b/core/res/res/drawable-ldpi/ic_lock_idle_alarm.png
new file mode 100644
index 0000000..dc133c5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_idle_alarm.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_idle_charging.png b/core/res/res/drawable-ldpi/ic_lock_idle_charging.png
new file mode 100644
index 0000000..c943b67
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_idle_charging.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_idle_lock.png b/core/res/res/drawable-ldpi/ic_lock_idle_lock.png
new file mode 100644
index 0000000..bc4adfd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_idle_lock.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_idle_low_battery.png b/core/res/res/drawable-ldpi/ic_lock_idle_low_battery.png
new file mode 100644
index 0000000..df7cb22
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_idle_low_battery.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_lock.png b/core/res/res/drawable-ldpi/ic_lock_lock.png
new file mode 100644
index 0000000..bde40f6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_lock.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_power_off.png b/core/res/res/drawable-ldpi/ic_lock_power_off.png
new file mode 100644
index 0000000..074d6d0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_power_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_ringer_off.png b/core/res/res/drawable-ldpi/ic_lock_ringer_off.png
new file mode 100644
index 0000000..50ff3de
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_ringer_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_ringer_on.png b/core/res/res/drawable-ldpi/ic_lock_ringer_on.png
new file mode 100644
index 0000000..7232728
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_ringer_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_silent_mode.png b/core/res/res/drawable-ldpi/ic_lock_silent_mode.png
new file mode 100644
index 0000000..8004f9d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_silent_mode.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_silent_mode_off.png b/core/res/res/drawable-ldpi/ic_lock_silent_mode_off.png
new file mode 100644
index 0000000..81b7a8d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_silent_mode_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_lock_silent_mode_vibrate.png b/core/res/res/drawable-ldpi/ic_lock_silent_mode_vibrate.png
new file mode 100644
index 0000000..5f54f6f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_lock_silent_mode_vibrate.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_maps_indicator_current_position.png b/core/res/res/drawable-ldpi/ic_maps_indicator_current_position.png
new file mode 100644
index 0000000..697b065
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_maps_indicator_current_position.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim1.png b/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim1.png
new file mode 100644
index 0000000..15a8a08
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim2.png b/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim2.png
new file mode 100644
index 0000000..f8b8de2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim3.png b/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim3.png
new file mode 100644
index 0000000..02f7547
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_maps_indicator_current_position_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_media_ff.png b/core/res/res/drawable-ldpi/ic_media_ff.png
new file mode 100644
index 0000000..1b4d9db
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_media_ff.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_media_next.png b/core/res/res/drawable-ldpi/ic_media_next.png
new file mode 100644
index 0000000..99927fd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_media_next.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_media_pause.png b/core/res/res/drawable-ldpi/ic_media_pause.png
new file mode 100644
index 0000000..3b98d66
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_media_pause.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_media_play.png b/core/res/res/drawable-ldpi/ic_media_play.png
new file mode 100644
index 0000000..e7c1972
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_media_play.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_media_previous.png b/core/res/res/drawable-ldpi/ic_media_previous.png
new file mode 100644
index 0000000..df04322
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_media_previous.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_media_rew.png b/core/res/res/drawable-ldpi/ic_media_rew.png
new file mode 100644
index 0000000..28843f9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_media_rew.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_account_list.png b/core/res/res/drawable-ldpi/ic_menu_account_list.png
new file mode 100644
index 0000000..04ededd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_account_list.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_add.png b/core/res/res/drawable-ldpi/ic_menu_add.png
new file mode 100644
index 0000000..89620af
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_add.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_agenda.png b/core/res/res/drawable-ldpi/ic_menu_agenda.png
new file mode 100644
index 0000000..9abcc68
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_agenda.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_allfriends.png b/core/res/res/drawable-ldpi/ic_menu_allfriends.png
new file mode 100644
index 0000000..462d078
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_allfriends.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_always_landscape_portrait.png b/core/res/res/drawable-ldpi/ic_menu_always_landscape_portrait.png
new file mode 100644
index 0000000..2c779ca
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_always_landscape_portrait.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_archive.png b/core/res/res/drawable-ldpi/ic_menu_archive.png
new file mode 100644
index 0000000..719ecd8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_archive.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_attachment.png b/core/res/res/drawable-ldpi/ic_menu_attachment.png
new file mode 100644
index 0000000..8fc2211
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_attachment.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_back.png b/core/res/res/drawable-ldpi/ic_menu_back.png
new file mode 100644
index 0000000..71eb533
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_back.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_block.png b/core/res/res/drawable-ldpi/ic_menu_block.png
new file mode 100644
index 0000000..c8d80cd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_block.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_blocked_user.png b/core/res/res/drawable-ldpi/ic_menu_blocked_user.png
new file mode 100644
index 0000000..c6407b5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_blocked_user.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_call.png b/core/res/res/drawable-ldpi/ic_menu_call.png
new file mode 100644
index 0000000..39d4b10
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_call.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_camera.png b/core/res/res/drawable-ldpi/ic_menu_camera.png
new file mode 100644
index 0000000..4d3a6a5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_camera.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_cc.png b/core/res/res/drawable-ldpi/ic_menu_cc.png
new file mode 100644
index 0000000..d90d70d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_cc.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_chat_dashboard.png b/core/res/res/drawable-ldpi/ic_menu_chat_dashboard.png
new file mode 100644
index 0000000..c417faa
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_chat_dashboard.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_clear_playlist.png b/core/res/res/drawable-ldpi/ic_menu_clear_playlist.png
new file mode 100644
index 0000000..f3e6b51c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_clear_playlist.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_close_clear_cancel.png b/core/res/res/drawable-ldpi/ic_menu_close_clear_cancel.png
new file mode 100644
index 0000000..760b925
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_close_clear_cancel.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_compass.png b/core/res/res/drawable-ldpi/ic_menu_compass.png
new file mode 100644
index 0000000..bf1724b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_compass.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_compose.png b/core/res/res/drawable-ldpi/ic_menu_compose.png
new file mode 100644
index 0000000..1e6767b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_compose.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_crop.png b/core/res/res/drawable-ldpi/ic_menu_crop.png
new file mode 100644
index 0000000..97c9182
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_crop.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_day.png b/core/res/res/drawable-ldpi/ic_menu_day.png
new file mode 100644
index 0000000..f0d661b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_day.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_delete.png b/core/res/res/drawable-ldpi/ic_menu_delete.png
new file mode 100644
index 0000000..dbad3dd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_delete.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_directions.png b/core/res/res/drawable-ldpi/ic_menu_directions.png
new file mode 100644
index 0000000..5d89d46
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_directions.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_edit.png b/core/res/res/drawable-ldpi/ic_menu_edit.png
new file mode 100644
index 0000000..9bb66e3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_edit.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_emoticons.png b/core/res/res/drawable-ldpi/ic_menu_emoticons.png
new file mode 100644
index 0000000..a97db87
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_emoticons.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_end_conversation.png b/core/res/res/drawable-ldpi/ic_menu_end_conversation.png
new file mode 100644
index 0000000..dd2005e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_end_conversation.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_forward.png b/core/res/res/drawable-ldpi/ic_menu_forward.png
new file mode 100644
index 0000000..554cfb7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_forward.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_friendslist.png b/core/res/res/drawable-ldpi/ic_menu_friendslist.png
new file mode 100644
index 0000000..62950da
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_friendslist.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_gallery.png b/core/res/res/drawable-ldpi/ic_menu_gallery.png
new file mode 100644
index 0000000..d57b284
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_gallery.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_goto.png b/core/res/res/drawable-ldpi/ic_menu_goto.png
new file mode 100644
index 0000000..d15ea3d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_goto.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_help.png b/core/res/res/drawable-ldpi/ic_menu_help.png
new file mode 100644
index 0000000..f93a4e6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_help.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_home.png b/core/res/res/drawable-ldpi/ic_menu_home.png
new file mode 100644
index 0000000..fd6f453
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_home.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_info_details.png b/core/res/res/drawable-ldpi/ic_menu_info_details.png
new file mode 100644
index 0000000..55c57d5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_info_details.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_invite.png b/core/res/res/drawable-ldpi/ic_menu_invite.png
new file mode 100644
index 0000000..16de8fe
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_invite.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_login.png b/core/res/res/drawable-ldpi/ic_menu_login.png
new file mode 100644
index 0000000..d4181de
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_login.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_manage.png b/core/res/res/drawable-ldpi/ic_menu_manage.png
new file mode 100644
index 0000000..b137b8c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_manage.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_mapmode.png b/core/res/res/drawable-ldpi/ic_menu_mapmode.png
new file mode 100644
index 0000000..8851005
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_mapmode.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_mark.png b/core/res/res/drawable-ldpi/ic_menu_mark.png
new file mode 100644
index 0000000..1d44027
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_mark.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_month.png b/core/res/res/drawable-ldpi/ic_menu_month.png
new file mode 100644
index 0000000..a3462f6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_month.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_more.png b/core/res/res/drawable-ldpi/ic_menu_more.png
new file mode 100644
index 0000000..9296554
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_more.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_my_calendar.png b/core/res/res/drawable-ldpi/ic_menu_my_calendar.png
new file mode 100644
index 0000000..db3a8b5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_my_calendar.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_mylocation.png b/core/res/res/drawable-ldpi/ic_menu_mylocation.png
new file mode 100644
index 0000000..2db7867
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_mylocation.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_myplaces.png b/core/res/res/drawable-ldpi/ic_menu_myplaces.png
new file mode 100644
index 0000000..9d2e8dc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_myplaces.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_notifications.png b/core/res/res/drawable-ldpi/ic_menu_notifications.png
new file mode 100644
index 0000000..0a22b32
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_notifications.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_play_clip.png b/core/res/res/drawable-ldpi/ic_menu_play_clip.png
new file mode 100644
index 0000000..7d0f11e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_play_clip.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_preferences.png b/core/res/res/drawable-ldpi/ic_menu_preferences.png
new file mode 100644
index 0000000..efc2f3e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_preferences.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_recent_history.png b/core/res/res/drawable-ldpi/ic_menu_recent_history.png
new file mode 100644
index 0000000..c75f6e3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_recent_history.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_refresh.png b/core/res/res/drawable-ldpi/ic_menu_refresh.png
new file mode 100644
index 0000000..b25dc06
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_refresh.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_report_image.png b/core/res/res/drawable-ldpi/ic_menu_report_image.png
new file mode 100644
index 0000000..f2c3a90
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_report_image.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_revert.png b/core/res/res/drawable-ldpi/ic_menu_revert.png
new file mode 100644
index 0000000..b0f2c60
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_revert.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_rotate.png b/core/res/res/drawable-ldpi/ic_menu_rotate.png
new file mode 100644
index 0000000..34dcbce
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_rotate.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_save.png b/core/res/res/drawable-ldpi/ic_menu_save.png
new file mode 100644
index 0000000..ac053b4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_save.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_search.png b/core/res/res/drawable-ldpi/ic_menu_search.png
new file mode 100644
index 0000000..1d95408
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_search.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_send.png b/core/res/res/drawable-ldpi/ic_menu_send.png
new file mode 100644
index 0000000..9043c11
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_send.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_set_as.png b/core/res/res/drawable-ldpi/ic_menu_set_as.png
new file mode 100644
index 0000000..d1997d3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_set_as.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_share.png b/core/res/res/drawable-ldpi/ic_menu_share.png
new file mode 100644
index 0000000..f58d231
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_share.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_slideshow.png b/core/res/res/drawable-ldpi/ic_menu_slideshow.png
new file mode 100644
index 0000000..a0625c4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_slideshow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_sort_alphabetically.png b/core/res/res/drawable-ldpi/ic_menu_sort_alphabetically.png
new file mode 100644
index 0000000..438e854
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_sort_alphabetically.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_sort_by_size.png b/core/res/res/drawable-ldpi/ic_menu_sort_by_size.png
new file mode 100644
index 0000000..bb95da7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_sort_by_size.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_star.png b/core/res/res/drawable-ldpi/ic_menu_star.png
new file mode 100644
index 0000000..b88f010
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_star.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_start_conversation.png b/core/res/res/drawable-ldpi/ic_menu_start_conversation.png
new file mode 100644
index 0000000..1e39928
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_start_conversation.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_stop.png b/core/res/res/drawable-ldpi/ic_menu_stop.png
new file mode 100644
index 0000000..d185ae2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_stop.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_today.png b/core/res/res/drawable-ldpi/ic_menu_today.png
new file mode 100644
index 0000000..2bff751
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_today.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_upload.png b/core/res/res/drawable-ldpi/ic_menu_upload.png
new file mode 100644
index 0000000..fd64fe1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_upload.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_upload_you_tube.png b/core/res/res/drawable-ldpi/ic_menu_upload_you_tube.png
new file mode 100644
index 0000000..8fa7005
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_upload_you_tube.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_view.png b/core/res/res/drawable-ldpi/ic_menu_view.png
new file mode 100644
index 0000000..f1acb3d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_view.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_week.png b/core/res/res/drawable-ldpi/ic_menu_week.png
new file mode 100644
index 0000000..0af314b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_week.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_menu_zoom.png b/core/res/res/drawable-ldpi/ic_menu_zoom.png
new file mode 100644
index 0000000..ff29184
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_menu_zoom.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_notification_clear_all.png b/core/res/res/drawable-ldpi/ic_notification_clear_all.png
new file mode 100644
index 0000000..e779740
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_notification_clear_all.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_notification_overlay.9.png b/core/res/res/drawable-ldpi/ic_notification_overlay.9.png
new file mode 100644
index 0000000..771fa73
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_notification_overlay.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_partial_secure.png b/core/res/res/drawable-ldpi/ic_partial_secure.png
new file mode 100644
index 0000000..a9c05b1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_partial_secure.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_popup_disk_full.png b/core/res/res/drawable-ldpi/ic_popup_disk_full.png
new file mode 100644
index 0000000..f613f38
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_popup_disk_full.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_popup_reminder.png b/core/res/res/drawable-ldpi/ic_popup_reminder.png
new file mode 100644
index 0000000..332daef
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_popup_reminder.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_popup_sync_1.png b/core/res/res/drawable-ldpi/ic_popup_sync_1.png
new file mode 100644
index 0000000..407e8de
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_popup_sync_1.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_popup_sync_2.png b/core/res/res/drawable-ldpi/ic_popup_sync_2.png
new file mode 100644
index 0000000..a867aa7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_popup_sync_2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_popup_sync_3.png b/core/res/res/drawable-ldpi/ic_popup_sync_3.png
new file mode 100644
index 0000000..77bd3d7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_popup_sync_3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_popup_sync_4.png b/core/res/res/drawable-ldpi/ic_popup_sync_4.png
new file mode 100644
index 0000000..131486b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_popup_sync_4.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_popup_sync_5.png b/core/res/res/drawable-ldpi/ic_popup_sync_5.png
new file mode 100644
index 0000000..33fded8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_popup_sync_5.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_popup_sync_6.png b/core/res/res/drawable-ldpi/ic_popup_sync_6.png
new file mode 100644
index 0000000..489dd56
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_popup_sync_6.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_search_category_default.png b/core/res/res/drawable-ldpi/ic_search_category_default.png
new file mode 100644
index 0000000..1d95408
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_search_category_default.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_secure.png b/core/res/res/drawable-ldpi/ic_secure.png
new file mode 100644
index 0000000..02d74d1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_secure.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_text_dot.png b/core/res/res/drawable-ldpi/ic_text_dot.png
new file mode 100644
index 0000000..4aff20c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_text_dot.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_vibrate.png b/core/res/res/drawable-ldpi/ic_vibrate.png
new file mode 100644
index 0000000..726e9dc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_vibrate.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_vibrate_small.png b/core/res/res/drawable-ldpi/ic_vibrate_small.png
new file mode 100644
index 0000000..06bfbb51
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_vibrate_small.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_volume.png b/core/res/res/drawable-ldpi/ic_volume.png
new file mode 100644
index 0000000..b8a3561
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_volume.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_volume_bluetooth_ad2p.png b/core/res/res/drawable-ldpi/ic_volume_bluetooth_ad2p.png
new file mode 100644
index 0000000..facfa4c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_volume_bluetooth_ad2p.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_volume_bluetooth_in_call.png b/core/res/res/drawable-ldpi/ic_volume_bluetooth_in_call.png
new file mode 100644
index 0000000..298ce6b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_volume_bluetooth_in_call.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_volume_off.png b/core/res/res/drawable-ldpi/ic_volume_off.png
new file mode 100644
index 0000000..bad1a68
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_volume_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_volume_off_small.png b/core/res/res/drawable-ldpi/ic_volume_off_small.png
new file mode 100644
index 0000000..5623911
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_volume_off_small.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ic_volume_small.png b/core/res/res/drawable-ldpi/ic_volume_small.png
new file mode 100644
index 0000000..530f6b4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ic_volume_small.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/icon_highlight_rectangle.9.png b/core/res/res/drawable-ldpi/icon_highlight_rectangle.9.png
new file mode 100644
index 0000000..27519b2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/icon_highlight_rectangle.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/icon_highlight_square.9.png b/core/res/res/drawable-ldpi/icon_highlight_square.9.png
new file mode 100644
index 0000000..228ef23
--- /dev/null
+++ b/core/res/res/drawable-ldpi/icon_highlight_square.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/ime_qwerty.png b/core/res/res/drawable-ldpi/ime_qwerty.png
new file mode 100644
index 0000000..11e26db
--- /dev/null
+++ b/core/res/res/drawable-ldpi/ime_qwerty.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_green_up.png b/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_green_up.png
new file mode 100644
index 0000000..9c8610f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_green_up.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_red_up.png
new file mode 100644
index 0000000..ac8e42a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/indicator_code_lock_drag_direction_red_up.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_default.png
new file mode 100644
index 0000000..5b77b9f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_default.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_green.png
new file mode 100644
index 0000000..c7c0b9a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_green.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_code_lock_point_area_red.png b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_red.png
new file mode 100644
index 0000000..ac02dc4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/indicator_code_lock_point_area_red.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/indicator_input_error.png b/core/res/res/drawable-ldpi/indicator_input_error.png
new file mode 100644
index 0000000..f1a804a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/indicator_input_error.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_arrow_long_left_green.png b/core/res/res/drawable-ldpi/jog_dial_arrow_long_left_green.png
new file mode 100644
index 0000000..cb30024
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_arrow_long_left_green.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_arrow_long_left_yellow.png b/core/res/res/drawable-ldpi/jog_dial_arrow_long_left_yellow.png
new file mode 100644
index 0000000..f63e737
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_arrow_long_left_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_arrow_long_middle_yellow.png b/core/res/res/drawable-ldpi/jog_dial_arrow_long_middle_yellow.png
new file mode 100644
index 0000000..249d53d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_arrow_long_middle_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_arrow_long_right_red.png b/core/res/res/drawable-ldpi/jog_dial_arrow_long_right_red.png
new file mode 100644
index 0000000..6a338fe
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_arrow_long_right_red.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_arrow_long_right_yellow.png b/core/res/res/drawable-ldpi/jog_dial_arrow_long_right_yellow.png
new file mode 100644
index 0000000..50f5c47
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_arrow_long_right_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_arrow_short_left.png b/core/res/res/drawable-ldpi/jog_dial_arrow_short_left.png
new file mode 100644
index 0000000..a8ed6987
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_arrow_short_left.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_arrow_short_left_and_right.png b/core/res/res/drawable-ldpi/jog_dial_arrow_short_left_and_right.png
new file mode 100644
index 0000000..bfd6c4e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_arrow_short_left_and_right.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_arrow_short_right.png b/core/res/res/drawable-ldpi/jog_dial_arrow_short_right.png
new file mode 100644
index 0000000..d22d508
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_arrow_short_right.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_bg.png b/core/res/res/drawable-ldpi/jog_dial_bg.png
new file mode 100644
index 0000000..263188b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_bg.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_dimple.png b/core/res/res/drawable-ldpi/jog_dial_dimple.png
new file mode 100644
index 0000000..c6f52ef
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_dimple.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_dial_dimple_dim.png b/core/res/res/drawable-ldpi/jog_dial_dimple_dim.png
new file mode 100644
index 0000000..b85db4e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_dial_dimple_dim.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_gray.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_gray.9.png
new file mode 100644
index 0000000..be9edd1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_gray.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_green.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_green.9.png
new file mode 100644
index 0000000..8b445fb
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_green.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_red.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_red.9.png
new file mode 100644
index 0000000..f9b07f8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_red.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_yellow.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_yellow.9.png
new file mode 100644
index 0000000..473fcb0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_confirm_yellow.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_left_end_normal.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_normal.9.png
new file mode 100644
index 0000000..b8ecac7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_left_end_pressed.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_pressed.9.png
new file mode 100644
index 0000000..95b4f4b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_left_end_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_gray.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_gray.9.png
new file mode 100644
index 0000000..2bec09e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_gray.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_green.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_green.9.png
new file mode 100644
index 0000000..8f8109e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_green.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_red.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_red.9.png
new file mode 100644
index 0000000..a453ac3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_red.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_yellow.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_yellow.9.png
new file mode 100644
index 0000000..f7ef794
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_confirm_yellow.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_right_end_normal.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_normal.9.png
new file mode 100644
index 0000000..74b769b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_bar_right_end_pressed.9.png b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_pressed.9.png
new file mode 100644
index 0000000..d12058d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_bar_right_end_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_left_confirm_gray.png b/core/res/res/drawable-ldpi/jog_tab_left_confirm_gray.png
new file mode 100644
index 0000000..92c4a2e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_left_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_left_confirm_green.png b/core/res/res/drawable-ldpi/jog_tab_left_confirm_green.png
new file mode 100644
index 0000000..13b7c63
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_left_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_left_confirm_red.png b/core/res/res/drawable-ldpi/jog_tab_left_confirm_red.png
new file mode 100644
index 0000000..414c07b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_left_confirm_red.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_left_confirm_yellow.png b/core/res/res/drawable-ldpi/jog_tab_left_confirm_yellow.png
new file mode 100644
index 0000000..afccc39
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_left_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_left_normal.png b/core/res/res/drawable-ldpi/jog_tab_left_normal.png
new file mode 100644
index 0000000..6ba6479
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_left_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_left_pressed.png b/core/res/res/drawable-ldpi/jog_tab_left_pressed.png
new file mode 100644
index 0000000..3dc9c47
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_left_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_right_confirm_gray.png b/core/res/res/drawable-ldpi/jog_tab_right_confirm_gray.png
new file mode 100644
index 0000000..ec1020d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_right_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_right_confirm_green.png b/core/res/res/drawable-ldpi/jog_tab_right_confirm_green.png
new file mode 100644
index 0000000..5b600c9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_right_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_right_confirm_red.png b/core/res/res/drawable-ldpi/jog_tab_right_confirm_red.png
new file mode 100644
index 0000000..b640578
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_right_confirm_red.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_right_confirm_yellow.png b/core/res/res/drawable-ldpi/jog_tab_right_confirm_yellow.png
new file mode 100644
index 0000000..c4490bc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_right_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_right_normal.png b/core/res/res/drawable-ldpi/jog_tab_right_normal.png
new file mode 100644
index 0000000..024d409
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_right_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_right_pressed.png b/core/res/res/drawable-ldpi/jog_tab_right_pressed.png
new file mode 100644
index 0000000..22acd25
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_right_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_target_gray.png b/core/res/res/drawable-ldpi/jog_tab_target_gray.png
new file mode 100644
index 0000000..7921676
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_target_gray.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_target_green.png b/core/res/res/drawable-ldpi/jog_tab_target_green.png
new file mode 100644
index 0000000..df5c273
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_target_green.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_target_red.png b/core/res/res/drawable-ldpi/jog_tab_target_red.png
new file mode 100644
index 0000000..2bb6df9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_target_red.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/jog_tab_target_yellow.png b/core/res/res/drawable-ldpi/jog_tab_target_yellow.png
new file mode 100644
index 0000000..e7e4347
--- /dev/null
+++ b/core/res/res/drawable-ldpi/jog_tab_target_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/keyboard_accessory_bg_landscape.9.png b/core/res/res/drawable-ldpi/keyboard_accessory_bg_landscape.9.png
new file mode 100644
index 0000000..4ab1dd0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/keyboard_accessory_bg_landscape.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/keyboard_background.9.png b/core/res/res/drawable-ldpi/keyboard_background.9.png
new file mode 100644
index 0000000..06d42c0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/keyboard_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/keyboard_key_feedback_background.9.png b/core/res/res/drawable-ldpi/keyboard_key_feedback_background.9.png
new file mode 100644
index 0000000..6f936f1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/keyboard_key_feedback_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/keyboard_key_feedback_more_background.9.png b/core/res/res/drawable-ldpi/keyboard_key_feedback_more_background.9.png
new file mode 100644
index 0000000..7e81c3d4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/keyboard_key_feedback_more_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/keyboard_popup_panel_background.9.png b/core/res/res/drawable-ldpi/keyboard_popup_panel_background.9.png
new file mode 100644
index 0000000..955fecc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/keyboard_popup_panel_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/keyboard_popup_panel_trans_background.9.png b/core/res/res/drawable-ldpi/keyboard_popup_panel_trans_background.9.png
new file mode 100644
index 0000000..78ac46d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/keyboard_popup_panel_trans_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/keyboard_textfield_selected.9.png b/core/res/res/drawable-ldpi/keyboard_textfield_selected.9.png
new file mode 100644
index 0000000..d6478fb
--- /dev/null
+++ b/core/res/res/drawable-ldpi/keyboard_textfield_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/light_header.9.png b/core/res/res/drawable-ldpi/light_header.9.png
new file mode 100644
index 0000000..4318252
--- /dev/null
+++ b/core/res/res/drawable-ldpi/light_header.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/list_selector_background_disabled.9.png b/core/res/res/drawable-ldpi/list_selector_background_disabled.9.png
new file mode 100644
index 0000000..b94396b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/list_selector_background_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/list_selector_background_focus.9.png b/core/res/res/drawable-ldpi/list_selector_background_focus.9.png
new file mode 100644
index 0000000..f2887a9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/list_selector_background_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/list_selector_background_longpress.9.png b/core/res/res/drawable-ldpi/list_selector_background_longpress.9.png
new file mode 100644
index 0000000..1fb46bb
--- /dev/null
+++ b/core/res/res/drawable-ldpi/list_selector_background_longpress.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/list_selector_background_pressed.9.png b/core/res/res/drawable-ldpi/list_selector_background_pressed.9.png
new file mode 100644
index 0000000..4980eab
--- /dev/null
+++ b/core/res/res/drawable-ldpi/list_selector_background_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/maps_google_logo.png b/core/res/res/drawable-ldpi/maps_google_logo.png
new file mode 100644
index 0000000..84cc523
--- /dev/null
+++ b/core/res/res/drawable-ldpi/maps_google_logo.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menu_background.9.png b/core/res/res/drawable-ldpi/menu_background.9.png
new file mode 100644
index 0000000..18c1f40
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menu_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menu_background_fill_parent_width.9.png b/core/res/res/drawable-ldpi/menu_background_fill_parent_width.9.png
new file mode 100644
index 0000000..02de323
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menu_background_fill_parent_width.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menu_separator.9.png b/core/res/res/drawable-ldpi/menu_separator.9.png
new file mode 100644
index 0000000..9e2dd7f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menu_separator.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menu_submenu_background.9.png b/core/res/res/drawable-ldpi/menu_submenu_background.9.png
new file mode 100644
index 0000000..25b27d4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menu_submenu_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menuitem_background_focus.9.png b/core/res/res/drawable-ldpi/menuitem_background_focus.9.png
new file mode 100644
index 0000000..072b665
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menuitem_background_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menuitem_background_pressed.9.png b/core/res/res/drawable-ldpi/menuitem_background_pressed.9.png
new file mode 100644
index 0000000..1def2a1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menuitem_background_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menuitem_background_solid_focused.9.png b/core/res/res/drawable-ldpi/menuitem_background_solid_focused.9.png
new file mode 100644
index 0000000..671e756
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menuitem_background_solid_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menuitem_background_solid_pressed.9.png b/core/res/res/drawable-ldpi/menuitem_background_solid_pressed.9.png
new file mode 100644
index 0000000..5f334d8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menuitem_background_solid_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/menuitem_checkbox_on.png b/core/res/res/drawable-ldpi/menuitem_checkbox_on.png
new file mode 100644
index 0000000..61a4843
--- /dev/null
+++ b/core/res/res/drawable-ldpi/menuitem_checkbox_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/overscroll_edge.png b/core/res/res/drawable-ldpi/overscroll_edge.png
new file mode 100644
index 0000000..b11f7d2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/overscroll_edge.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/overscroll_glow.png b/core/res/res/drawable-ldpi/overscroll_glow.png
new file mode 100644
index 0000000..029296a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/overscroll_glow.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/panel_background.9.png b/core/res/res/drawable-ldpi/panel_background.9.png
new file mode 100644
index 0000000..7ea328d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/panel_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/panel_picture_frame_bg_focus_blue.9.png b/core/res/res/drawable-ldpi/panel_picture_frame_bg_focus_blue.9.png
new file mode 100644
index 0000000..14eb7f7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/panel_picture_frame_bg_focus_blue.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/panel_picture_frame_bg_normal.9.png b/core/res/res/drawable-ldpi/panel_picture_frame_bg_normal.9.png
new file mode 100644
index 0000000..c8cd101
--- /dev/null
+++ b/core/res/res/drawable-ldpi/panel_picture_frame_bg_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/panel_picture_frame_bg_pressed_blue.9.png b/core/res/res/drawable-ldpi/panel_picture_frame_bg_pressed_blue.9.png
new file mode 100644
index 0000000..0badf2b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/panel_picture_frame_bg_pressed_blue.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/password_field_default.9.png b/core/res/res/drawable-ldpi/password_field_default.9.png
new file mode 100644
index 0000000..a84abf2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/password_field_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/picture_emergency.png b/core/res/res/drawable-ldpi/picture_emergency.png
new file mode 100644
index 0000000..dbb738f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/picture_emergency.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/picture_frame.9.png b/core/res/res/drawable-ldpi/picture_frame.9.png
new file mode 100644
index 0000000..f302bf3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/picture_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_bottom_bright.9.png b/core/res/res/drawable-ldpi/popup_bottom_bright.9.png
new file mode 100644
index 0000000..a8d52a2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_bottom_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_bottom_dark.9.png b/core/res/res/drawable-ldpi/popup_bottom_dark.9.png
new file mode 100644
index 0000000..b0b64df
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_bottom_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_bottom_medium.9.png b/core/res/res/drawable-ldpi/popup_bottom_medium.9.png
new file mode 100644
index 0000000..7bdef97
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_bottom_medium.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_center_bright.9.png b/core/res/res/drawable-ldpi/popup_center_bright.9.png
new file mode 100644
index 0000000..0bfe6ba
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_center_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_center_dark.9.png b/core/res/res/drawable-ldpi/popup_center_dark.9.png
new file mode 100644
index 0000000..e76a452
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_center_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_center_medium.9.png b/core/res/res/drawable-ldpi/popup_center_medium.9.png
new file mode 100644
index 0000000..a8de187
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_center_medium.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_full_bright.9.png b/core/res/res/drawable-ldpi/popup_full_bright.9.png
new file mode 100644
index 0000000..b6bbacd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_full_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_full_dark.9.png b/core/res/res/drawable-ldpi/popup_full_dark.9.png
new file mode 100644
index 0000000..ed36fce
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_full_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_inline_error.9.png b/core/res/res/drawable-ldpi/popup_inline_error.9.png
new file mode 100644
index 0000000..cdc66ff
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_inline_error.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_inline_error_above.9.png b/core/res/res/drawable-ldpi/popup_inline_error_above.9.png
new file mode 100644
index 0000000..673685d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_inline_error_above.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_top_bright.9.png b/core/res/res/drawable-ldpi/popup_top_bright.9.png
new file mode 100644
index 0000000..51f1f0f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_top_bright.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/popup_top_dark.9.png b/core/res/res/drawable-ldpi/popup_top_dark.9.png
new file mode 100644
index 0000000..81e1918
--- /dev/null
+++ b/core/res/res/drawable-ldpi/popup_top_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_audio_away.png b/core/res/res/drawable-ldpi/presence_audio_away.png
new file mode 100644
index 0000000..73ad0da
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_audio_away.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_audio_busy.png b/core/res/res/drawable-ldpi/presence_audio_busy.png
new file mode 100644
index 0000000..8b64d45
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_audio_busy.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_audio_online.png b/core/res/res/drawable-ldpi/presence_audio_online.png
new file mode 100644
index 0000000..455db0528
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_audio_online.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_away.png b/core/res/res/drawable-ldpi/presence_away.png
new file mode 100644
index 0000000..5228a4b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_away.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_busy.png b/core/res/res/drawable-ldpi/presence_busy.png
new file mode 100644
index 0000000..79fddf7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_busy.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_invisible.png b/core/res/res/drawable-ldpi/presence_invisible.png
new file mode 100644
index 0000000..fb1654b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_invisible.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_offline.png b/core/res/res/drawable-ldpi/presence_offline.png
new file mode 100644
index 0000000..4546799
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_offline.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_online.png b/core/res/res/drawable-ldpi/presence_online.png
new file mode 100644
index 0000000..c400a18
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_online.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_video_away.png b/core/res/res/drawable-ldpi/presence_video_away.png
new file mode 100644
index 0000000..3695a0e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_video_away.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_video_busy.png b/core/res/res/drawable-ldpi/presence_video_busy.png
new file mode 100644
index 0000000..c4b0728
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_video_busy.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/presence_video_online.png b/core/res/res/drawable-ldpi/presence_video_online.png
new file mode 100644
index 0000000..786d0e6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/presence_video_online.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/pressed_application_background_static.png b/core/res/res/drawable-ldpi/pressed_application_background_static.png
new file mode 100644
index 0000000..d0fd302
--- /dev/null
+++ b/core/res/res/drawable-ldpi/pressed_application_background_static.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/progressbar_indeterminate1.png b/core/res/res/drawable-ldpi/progressbar_indeterminate1.png
new file mode 100644
index 0000000..92a1aee
--- /dev/null
+++ b/core/res/res/drawable-ldpi/progressbar_indeterminate1.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/progressbar_indeterminate2.png b/core/res/res/drawable-ldpi/progressbar_indeterminate2.png
new file mode 100644
index 0000000..1fd2f37
--- /dev/null
+++ b/core/res/res/drawable-ldpi/progressbar_indeterminate2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/progressbar_indeterminate3.png b/core/res/res/drawable-ldpi/progressbar_indeterminate3.png
new file mode 100644
index 0000000..adb8022
--- /dev/null
+++ b/core/res/res/drawable-ldpi/progressbar_indeterminate3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/quickcontact_badge_pressed.9.png b/core/res/res/drawable-ldpi/quickcontact_badge_pressed.9.png
new file mode 100644
index 0000000..ff43fed
--- /dev/null
+++ b/core/res/res/drawable-ldpi/quickcontact_badge_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/quickcontact_badge_small_pressed.9.png b/core/res/res/drawable-ldpi/quickcontact_badge_small_pressed.9.png
new file mode 100644
index 0000000..5aedb70
--- /dev/null
+++ b/core/res/res/drawable-ldpi/quickcontact_badge_small_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/quickcontact_badge_small_unpressed.9.png b/core/res/res/drawable-ldpi/quickcontact_badge_small_unpressed.9.png
new file mode 100644
index 0000000..6e212b6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/quickcontact_badge_small_unpressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/quickcontact_badge_unpressed.9.png b/core/res/res/drawable-ldpi/quickcontact_badge_unpressed.9.png
new file mode 100644
index 0000000..417c11b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/quickcontact_badge_unpressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/radiobutton_off_background.png b/core/res/res/drawable-ldpi/radiobutton_off_background.png
new file mode 100644
index 0000000..d8023c9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/radiobutton_off_background.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/radiobutton_on_background.png b/core/res/res/drawable-ldpi/radiobutton_on_background.png
new file mode 100644
index 0000000..4014d4b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/radiobutton_on_background.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_big_half.png b/core/res/res/drawable-ldpi/rate_star_big_half.png
new file mode 100644
index 0000000..0b4dc17
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_big_half.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_big_off.png b/core/res/res/drawable-ldpi/rate_star_big_off.png
new file mode 100644
index 0000000..1d8eef6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_big_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_big_on.png b/core/res/res/drawable-ldpi/rate_star_big_on.png
new file mode 100644
index 0000000..b6d4d89
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_big_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_med_half.png b/core/res/res/drawable-ldpi/rate_star_med_half.png
new file mode 100644
index 0000000..f9bcc5c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_med_half.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_med_off.png b/core/res/res/drawable-ldpi/rate_star_med_off.png
new file mode 100644
index 0000000..eec4ae5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_med_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_med_on.png b/core/res/res/drawable-ldpi/rate_star_med_on.png
new file mode 100644
index 0000000..03a4cff
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_med_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_small_half.png b/core/res/res/drawable-ldpi/rate_star_small_half.png
new file mode 100644
index 0000000..3e2b99b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_small_half.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_small_off.png b/core/res/res/drawable-ldpi/rate_star_small_off.png
new file mode 100644
index 0000000..19db372
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_small_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/rate_star_small_on.png b/core/res/res/drawable-ldpi/rate_star_small_on.png
new file mode 100644
index 0000000..b3b9a84
--- /dev/null
+++ b/core/res/res/drawable-ldpi/rate_star_small_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/recent_dialog_background.9.png b/core/res/res/drawable-ldpi/recent_dialog_background.9.png
new file mode 100644
index 0000000..ab8d87d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/recent_dialog_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/reticle.png b/core/res/res/drawable-ldpi/reticle.png
new file mode 100644
index 0000000..daaee11
--- /dev/null
+++ b/core/res/res/drawable-ldpi/reticle.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png b/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png
new file mode 100644
index 0000000..0562c03
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrollbar_handle_accelerated_anim2.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrollbar_handle_horizontal.9.png b/core/res/res/drawable-ldpi/scrollbar_handle_horizontal.9.png
new file mode 100644
index 0000000..b3c10cf
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrollbar_handle_horizontal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/scrollbar_handle_vertical.9.png b/core/res/res/drawable-ldpi/scrollbar_handle_vertical.9.png
new file mode 100644
index 0000000..a04e632
--- /dev/null
+++ b/core/res/res/drawable-ldpi/scrollbar_handle_vertical.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/search_dropdown_background.9.png b/core/res/res/drawable-ldpi/search_dropdown_background.9.png
new file mode 100644
index 0000000..b695dcb
--- /dev/null
+++ b/core/res/res/drawable-ldpi/search_dropdown_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/search_plate.9.png b/core/res/res/drawable-ldpi/search_plate.9.png
new file mode 100644
index 0000000..40a351f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/search_plate.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/search_plate_global.9.png b/core/res/res/drawable-ldpi/search_plate_global.9.png
new file mode 100644
index 0000000..2fa2129
--- /dev/null
+++ b/core/res/res/drawable-ldpi/search_plate_global.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/seek_thumb_normal.png b/core/res/res/drawable-ldpi/seek_thumb_normal.png
new file mode 100644
index 0000000..9c2d90d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/seek_thumb_normal.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/seek_thumb_pressed.png b/core/res/res/drawable-ldpi/seek_thumb_pressed.png
new file mode 100644
index 0000000..555cde8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/seek_thumb_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/seek_thumb_selected.png b/core/res/res/drawable-ldpi/seek_thumb_selected.png
new file mode 100644
index 0000000..4f11818
--- /dev/null
+++ b/core/res/res/drawable-ldpi/seek_thumb_selected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/settings_header_raw.9.png b/core/res/res/drawable-ldpi/settings_header_raw.9.png
new file mode 100644
index 0000000..142d8c2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/settings_header_raw.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_black_16.png b/core/res/res/drawable-ldpi/spinner_black_16.png
new file mode 100644
index 0000000..c876d8a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_black_16.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_black_20.png b/core/res/res/drawable-ldpi/spinner_black_20.png
new file mode 100644
index 0000000..7751f9a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_black_20.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_black_48.png b/core/res/res/drawable-ldpi/spinner_black_48.png
new file mode 100644
index 0000000..c7aa517
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_black_48.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_black_76.png b/core/res/res/drawable-ldpi/spinner_black_76.png
new file mode 100644
index 0000000..44f559c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_black_76.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_dropdown_background_down.9.png b/core/res/res/drawable-ldpi/spinner_dropdown_background_down.9.png
new file mode 100644
index 0000000..f9c4610
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_dropdown_background_down.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_dropdown_background_up.9.png b/core/res/res/drawable-ldpi/spinner_dropdown_background_up.9.png
new file mode 100644
index 0000000..f458ad4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_dropdown_background_up.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_normal.9.png b/core/res/res/drawable-ldpi/spinner_normal.9.png
new file mode 100644
index 0000000..151c2e6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_press.9.png b/core/res/res/drawable-ldpi/spinner_press.9.png
new file mode 100644
index 0000000..f3be1fc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_press.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_select.9.png b/core/res/res/drawable-ldpi/spinner_select.9.png
new file mode 100644
index 0000000..092168b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_select.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_white_16.png b/core/res/res/drawable-ldpi/spinner_white_16.png
new file mode 100644
index 0000000..0ad9eb0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_white_16.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_white_48.png b/core/res/res/drawable-ldpi/spinner_white_48.png
new file mode 100644
index 0000000..f0f0827
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_white_48.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/spinner_white_76.png b/core/res/res/drawable-ldpi/spinner_white_76.png
new file mode 100644
index 0000000..8be8f26
--- /dev/null
+++ b/core/res/res/drawable-ldpi/spinner_white_76.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/star_big_off.png b/core/res/res/drawable-ldpi/star_big_off.png
new file mode 100644
index 0000000..d91c3a4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/star_big_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/star_big_on.png b/core/res/res/drawable-ldpi/star_big_on.png
new file mode 100644
index 0000000..69d92a2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/star_big_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/star_off.png b/core/res/res/drawable-ldpi/star_off.png
new file mode 100644
index 0000000..6bc28fc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/star_off.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/star_on.png b/core/res/res/drawable-ldpi/star_on.png
new file mode 100644
index 0000000..d2e3845
--- /dev/null
+++ b/core/res/res/drawable-ldpi/star_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_ecb_mode.png b/core/res/res/drawable-ldpi/stat_ecb_mode.png
new file mode 100644
index 0000000..a17d7db
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_ecb_mode.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_call_mute.png b/core/res/res/drawable-ldpi/stat_notify_call_mute.png
new file mode 100644
index 0000000..d160009
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_call_mute.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_car_mode.png b/core/res/res/drawable-ldpi/stat_notify_car_mode.png
new file mode 100644
index 0000000..22e90aef
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_car_mode.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_chat.png b/core/res/res/drawable-ldpi/stat_notify_chat.png
new file mode 100644
index 0000000..562fbcc
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_chat.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_disk_full.png b/core/res/res/drawable-ldpi/stat_notify_disk_full.png
new file mode 100644
index 0000000..c329486
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_disk_full.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_email_generic.png b/core/res/res/drawable-ldpi/stat_notify_email_generic.png
new file mode 100644
index 0000000..352267c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_email_generic.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_error.png b/core/res/res/drawable-ldpi/stat_notify_error.png
new file mode 100644
index 0000000..a2eab9b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_error.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_gmail.png b/core/res/res/drawable-ldpi/stat_notify_gmail.png
new file mode 100644
index 0000000..8fbfd00
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_gmail.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_missed_call.png b/core/res/res/drawable-ldpi/stat_notify_missed_call.png
new file mode 100644
index 0000000..4c01206
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_missed_call.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_more.png b/core/res/res/drawable-ldpi/stat_notify_more.png
new file mode 100644
index 0000000..a51341d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_more.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_sdcard.png b/core/res/res/drawable-ldpi/stat_notify_sdcard.png
new file mode 100644
index 0000000..265fd8f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_sdcard.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_sdcard_prepare.png b/core/res/res/drawable-ldpi/stat_notify_sdcard_prepare.png
new file mode 100644
index 0000000..84cb224
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_sdcard_prepare.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_sdcard_usb.png b/core/res/res/drawable-ldpi/stat_notify_sdcard_usb.png
new file mode 100644
index 0000000..cb7022b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_sdcard_usb.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_sim_toolkit.png b/core/res/res/drawable-ldpi/stat_notify_sim_toolkit.png
new file mode 100644
index 0000000..d9a62a9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_sim_toolkit.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_sync.png b/core/res/res/drawable-ldpi/stat_notify_sync.png
new file mode 100644
index 0000000..dd63030
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_sync.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_sync_anim0.png b/core/res/res/drawable-ldpi/stat_notify_sync_anim0.png
new file mode 100644
index 0000000..9aa4edf
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_sync_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_sync_error.png b/core/res/res/drawable-ldpi/stat_notify_sync_error.png
new file mode 100644
index 0000000..431a86f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_sync_error.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_voicemail.png b/core/res/res/drawable-ldpi/stat_notify_voicemail.png
new file mode 100644
index 0000000..36d61a4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_voicemail.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_notify_wifi_in_range.png b/core/res/res/drawable-ldpi/stat_notify_wifi_in_range.png
new file mode 100644
index 0000000..1ff50ea
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_notify_wifi_in_range.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_adb.png b/core/res/res/drawable-ldpi/stat_sys_adb.png
new file mode 100644
index 0000000..cdead24
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_adb.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_0.png b/core/res/res/drawable-ldpi/stat_sys_battery_0.png
new file mode 100644
index 0000000..b692c7a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_0.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_10.png b/core/res/res/drawable-ldpi/stat_sys_battery_10.png
new file mode 100644
index 0000000..5e7efd1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_10.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_100.png b/core/res/res/drawable-ldpi/stat_sys_battery_100.png
new file mode 100644
index 0000000..7023ea7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_100.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_20.png b/core/res/res/drawable-ldpi/stat_sys_battery_20.png
new file mode 100644
index 0000000..275ebbb
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_20.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_40.png b/core/res/res/drawable-ldpi/stat_sys_battery_40.png
new file mode 100644
index 0000000..6a46fe0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_40.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_60.png b/core/res/res/drawable-ldpi/stat_sys_battery_60.png
new file mode 100644
index 0000000..f94115a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_60.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_80.png b/core/res/res/drawable-ldpi/stat_sys_battery_80.png
new file mode 100644
index 0000000..8b07df9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_80.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim0.png b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim0.png
new file mode 100644
index 0000000..7c4a783
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim1.png b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim1.png
new file mode 100644
index 0000000..9eea8ae
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim2.png b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim2.png
new file mode 100644
index 0000000..112c869
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim3.png b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim3.png
new file mode 100644
index 0000000..7b5c08b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim4.png b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim4.png
new file mode 100644
index 0000000..ddda4ad
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim5.png b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim5.png
new file mode 100644
index 0000000..52050b2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_charge_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_battery_unknown.png b/core/res/res/drawable-ldpi/stat_sys_battery_unknown.png
new file mode 100644
index 0000000..e095aa4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_battery_unknown.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_data_bluetooth.png b/core/res/res/drawable-ldpi/stat_sys_data_bluetooth.png
new file mode 100644
index 0000000..2ae3355
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_data_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_data_usb.png b/core/res/res/drawable-ldpi/stat_sys_data_usb.png
new file mode 100644
index 0000000..ffaccbd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_data_usb.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_download_anim0.png b/core/res/res/drawable-ldpi/stat_sys_download_anim0.png
new file mode 100644
index 0000000..12c0e21
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_download_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_download_anim1.png b/core/res/res/drawable-ldpi/stat_sys_download_anim1.png
new file mode 100644
index 0000000..f5ec4ac
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_download_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_download_anim2.png b/core/res/res/drawable-ldpi/stat_sys_download_anim2.png
new file mode 100644
index 0000000..4900ebd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_download_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_download_anim3.png b/core/res/res/drawable-ldpi/stat_sys_download_anim3.png
new file mode 100644
index 0000000..aff9ebd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_download_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_download_anim4.png b/core/res/res/drawable-ldpi/stat_sys_download_anim4.png
new file mode 100644
index 0000000..2eb65db
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_download_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_download_anim5.png b/core/res/res/drawable-ldpi/stat_sys_download_anim5.png
new file mode 100644
index 0000000..a9f2448
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_download_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_gps_on.png b/core/res/res/drawable-ldpi/stat_sys_gps_on.png
new file mode 100644
index 0000000..8915c59
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_gps_on.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_headset.png b/core/res/res/drawable-ldpi/stat_sys_headset.png
new file mode 100644
index 0000000..8f143a3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_headset.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_phone_call.png b/core/res/res/drawable-ldpi/stat_sys_phone_call.png
new file mode 100644
index 0000000..275bef2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_phone_call.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_phone_call_forward.png b/core/res/res/drawable-ldpi/stat_sys_phone_call_forward.png
new file mode 100644
index 0000000..bb07c69
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_phone_call_forward.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_phone_call_on_hold.png b/core/res/res/drawable-ldpi/stat_sys_phone_call_on_hold.png
new file mode 100644
index 0000000..b03816a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_phone_call_on_hold.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_r_signal_0_cdma.png b/core/res/res/drawable-ldpi/stat_sys_r_signal_0_cdma.png
new file mode 100644
index 0000000..2c4ff06
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_r_signal_0_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_r_signal_1_cdma.png b/core/res/res/drawable-ldpi/stat_sys_r_signal_1_cdma.png
new file mode 100644
index 0000000..82626ac
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_r_signal_1_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_r_signal_2_cdma.png b/core/res/res/drawable-ldpi/stat_sys_r_signal_2_cdma.png
new file mode 100644
index 0000000..96304b1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_r_signal_2_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_r_signal_3_cdma.png b/core/res/res/drawable-ldpi/stat_sys_r_signal_3_cdma.png
new file mode 100644
index 0000000..9a3f230
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_r_signal_3_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_r_signal_4_cdma.png b/core/res/res/drawable-ldpi/stat_sys_r_signal_4_cdma.png
new file mode 100644
index 0000000..5a607ee
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_r_signal_4_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_ra_signal_0_cdma.png b/core/res/res/drawable-ldpi/stat_sys_ra_signal_0_cdma.png
new file mode 100644
index 0000000..0db564b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_ra_signal_0_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_ra_signal_1_cdma.png b/core/res/res/drawable-ldpi/stat_sys_ra_signal_1_cdma.png
new file mode 100644
index 0000000..ca697db
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_ra_signal_1_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_ra_signal_2_cdma.png b/core/res/res/drawable-ldpi/stat_sys_ra_signal_2_cdma.png
new file mode 100644
index 0000000..816aaaa
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_ra_signal_2_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_ra_signal_3_cdma.png b/core/res/res/drawable-ldpi/stat_sys_ra_signal_3_cdma.png
new file mode 100644
index 0000000..ebb103c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_ra_signal_3_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_ra_signal_4_cdma.png b/core/res/res/drawable-ldpi/stat_sys_ra_signal_4_cdma.png
new file mode 100644
index 0000000..f211201
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_ra_signal_4_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_secure.png b/core/res/res/drawable-ldpi/stat_sys_secure.png
new file mode 100644
index 0000000..096aa95
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_secure.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_0_cdma.png b/core/res/res/drawable-ldpi/stat_sys_signal_0_cdma.png
new file mode 100644
index 0000000..dabba9c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_0_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_1_cdma.png b/core/res/res/drawable-ldpi/stat_sys_signal_1_cdma.png
new file mode 100644
index 0000000..5d99b45
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_1_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_2_cdma.png b/core/res/res/drawable-ldpi/stat_sys_signal_2_cdma.png
new file mode 100644
index 0000000..f68f836
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_2_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_3_cdma.png b/core/res/res/drawable-ldpi/stat_sys_signal_3_cdma.png
new file mode 100644
index 0000000..370b91f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_3_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_4_cdma.png b/core/res/res/drawable-ldpi/stat_sys_signal_4_cdma.png
new file mode 100644
index 0000000..e8b4d38
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_4_cdma.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_evdo_0.png b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_0.png
new file mode 100644
index 0000000..2b360c2
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_0.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_evdo_1.png b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_1.png
new file mode 100644
index 0000000..dfcd1f7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_1.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_evdo_2.png b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_2.png
new file mode 100644
index 0000000..b8a5bda
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_evdo_3.png b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_3.png
new file mode 100644
index 0000000..65c76d3
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_signal_evdo_4.png b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_4.png
new file mode 100644
index 0000000..974f936
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_signal_evdo_4.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_speakerphone.png b/core/res/res/drawable-ldpi/stat_sys_speakerphone.png
new file mode 100644
index 0000000..7fc67a0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_speakerphone.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_tether_bluetooth.png b/core/res/res/drawable-ldpi/stat_sys_tether_bluetooth.png
new file mode 100644
index 0000000..ffe8e8c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_tether_bluetooth.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_tether_general.png b/core/res/res/drawable-ldpi/stat_sys_tether_general.png
new file mode 100644
index 0000000..ca20f73
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_tether_general.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_tether_usb.png b/core/res/res/drawable-ldpi/stat_sys_tether_usb.png
new file mode 100644
index 0000000..65e9075
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_tether_usb.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_tether_wifi.png b/core/res/res/drawable-ldpi/stat_sys_tether_wifi.png
new file mode 100644
index 0000000..b4b3cfd
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_tether_wifi.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_throttled.png b/core/res/res/drawable-ldpi/stat_sys_throttled.png
new file mode 100644
index 0000000..cfeb3b6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_throttled.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_upload_anim0.png b/core/res/res/drawable-ldpi/stat_sys_upload_anim0.png
new file mode 100644
index 0000000..29f9082
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_upload_anim0.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_upload_anim1.png b/core/res/res/drawable-ldpi/stat_sys_upload_anim1.png
new file mode 100644
index 0000000..bd1b72a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_upload_anim1.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_upload_anim2.png b/core/res/res/drawable-ldpi/stat_sys_upload_anim2.png
new file mode 100644
index 0000000..e49d23b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_upload_anim2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_upload_anim3.png b/core/res/res/drawable-ldpi/stat_sys_upload_anim3.png
new file mode 100644
index 0000000..64525ac
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_upload_anim3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_upload_anim4.png b/core/res/res/drawable-ldpi/stat_sys_upload_anim4.png
new file mode 100644
index 0000000..20f8f59
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_upload_anim4.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_upload_anim5.png b/core/res/res/drawable-ldpi/stat_sys_upload_anim5.png
new file mode 100644
index 0000000..0f482df
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_upload_anim5.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_vp_phone_call.png b/core/res/res/drawable-ldpi/stat_sys_vp_phone_call.png
new file mode 100644
index 0000000..504d7a5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_vp_phone_call.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_vp_phone_call_on_hold.png b/core/res/res/drawable-ldpi/stat_sys_vp_phone_call_on_hold.png
new file mode 100644
index 0000000..edeef2b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_vp_phone_call_on_hold.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/stat_sys_warning.png b/core/res/res/drawable-ldpi/stat_sys_warning.png
new file mode 100644
index 0000000..289c6a0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/stat_sys_warning.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/status_bar_background.png b/core/res/res/drawable-ldpi/status_bar_background.png
new file mode 100644
index 0000000..7881bce
--- /dev/null
+++ b/core/res/res/drawable-ldpi/status_bar_background.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/status_bar_header_background.9.png b/core/res/res/drawable-ldpi/status_bar_header_background.9.png
new file mode 100644
index 0000000..74dddb9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/status_bar_header_background.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/status_bar_item_app_background_normal.9.png b/core/res/res/drawable-ldpi/status_bar_item_app_background_normal.9.png
new file mode 100644
index 0000000..f8cfe2c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/status_bar_item_app_background_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/status_bar_item_background_focus.9.png b/core/res/res/drawable-ldpi/status_bar_item_background_focus.9.png
new file mode 100644
index 0000000..07cd873
--- /dev/null
+++ b/core/res/res/drawable-ldpi/status_bar_item_background_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/status_bar_item_background_normal.9.png b/core/res/res/drawable-ldpi/status_bar_item_background_normal.9.png
new file mode 100644
index 0000000..e07f774
--- /dev/null
+++ b/core/res/res/drawable-ldpi/status_bar_item_background_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/status_bar_item_background_pressed.9.png b/core/res/res/drawable-ldpi/status_bar_item_background_pressed.9.png
new file mode 100644
index 0000000..aea2f5f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/status_bar_item_background_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/submenu_arrow_nofocus.png b/core/res/res/drawable-ldpi/submenu_arrow_nofocus.png
new file mode 100644
index 0000000..ce30b58
--- /dev/null
+++ b/core/res/res/drawable-ldpi/submenu_arrow_nofocus.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_action_add.png b/core/res/res/drawable-ldpi/sym_action_add.png
new file mode 100644
index 0000000..7afaede
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_action_add.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_action_call.png b/core/res/res/drawable-ldpi/sym_action_call.png
new file mode 100644
index 0000000..190572d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_action_call.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_action_chat.png b/core/res/res/drawable-ldpi/sym_action_chat.png
new file mode 100644
index 0000000..4eeb59b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_action_chat.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_action_email.png b/core/res/res/drawable-ldpi/sym_action_email.png
new file mode 100644
index 0000000..47dc63a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_action_email.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_app_on_sd_unavailable_icon.png b/core/res/res/drawable-ldpi/sym_app_on_sd_unavailable_icon.png
new file mode 100644
index 0000000..d88250a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_app_on_sd_unavailable_icon.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_call_incoming.png b/core/res/res/drawable-ldpi/sym_call_incoming.png
new file mode 100644
index 0000000..ec609c6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_call_incoming.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_call_missed.png b/core/res/res/drawable-ldpi/sym_call_missed.png
new file mode 100644
index 0000000..8bad634
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_call_missed.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_call_outgoing.png b/core/res/res/drawable-ldpi/sym_call_outgoing.png
new file mode 100644
index 0000000..362df01
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_call_outgoing.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_contact_card.png b/core/res/res/drawable-ldpi/sym_contact_card.png
new file mode 100644
index 0000000..8ffd06e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_contact_card.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_def_app_icon.png b/core/res/res/drawable-ldpi/sym_def_app_icon.png
new file mode 100644
index 0000000..2c205c8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_def_app_icon.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_delete.png b/core/res/res/drawable-ldpi/sym_keyboard_delete.png
new file mode 100644
index 0000000..d9d5653
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_delete.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_delete_dim.png b/core/res/res/drawable-ldpi/sym_keyboard_delete_dim.png
new file mode 100644
index 0000000..d7d9385
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_delete_dim.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_feedback_delete.png b/core/res/res/drawable-ldpi/sym_keyboard_feedback_delete.png
new file mode 100644
index 0000000..8922bf9
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_feedback_delete.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_feedback_ok.png b/core/res/res/drawable-ldpi/sym_keyboard_feedback_ok.png
new file mode 100644
index 0000000..304141b5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_feedback_ok.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_feedback_return.png b/core/res/res/drawable-ldpi/sym_keyboard_feedback_return.png
new file mode 100644
index 0000000..c5f3247
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_feedback_return.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_feedback_shift.png b/core/res/res/drawable-ldpi/sym_keyboard_feedback_shift.png
new file mode 100644
index 0000000..a7bf565
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_feedback_shift.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_feedback_shift_locked.png b/core/res/res/drawable-ldpi/sym_keyboard_feedback_shift_locked.png
new file mode 100644
index 0000000..114abac
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_feedback_shift_locked.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_feedback_space.png b/core/res/res/drawable-ldpi/sym_keyboard_feedback_space.png
new file mode 100644
index 0000000..5d52970
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_feedback_space.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num0_no_plus.png b/core/res/res/drawable-ldpi/sym_keyboard_num0_no_plus.png
new file mode 100644
index 0000000..eb4764d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num0_no_plus.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num1.png b/core/res/res/drawable-ldpi/sym_keyboard_num1.png
new file mode 100644
index 0000000..1339b6d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num1.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num2.png b/core/res/res/drawable-ldpi/sym_keyboard_num2.png
new file mode 100644
index 0000000..bd2379d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num2.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num3.png b/core/res/res/drawable-ldpi/sym_keyboard_num3.png
new file mode 100644
index 0000000..43e8b15
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num3.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num4.png b/core/res/res/drawable-ldpi/sym_keyboard_num4.png
new file mode 100644
index 0000000..70d4f78
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num4.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num5.png b/core/res/res/drawable-ldpi/sym_keyboard_num5.png
new file mode 100644
index 0000000..5acda28
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num5.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num6.png b/core/res/res/drawable-ldpi/sym_keyboard_num6.png
new file mode 100644
index 0000000..950600b0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num6.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num7.png b/core/res/res/drawable-ldpi/sym_keyboard_num7.png
new file mode 100644
index 0000000..caea4bb
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num7.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num8.png b/core/res/res/drawable-ldpi/sym_keyboard_num8.png
new file mode 100644
index 0000000..b528fc7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num8.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_num9.png b/core/res/res/drawable-ldpi/sym_keyboard_num9.png
new file mode 100644
index 0000000..1835e21
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_num9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_ok.png b/core/res/res/drawable-ldpi/sym_keyboard_ok.png
new file mode 100644
index 0000000..70bffc1
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_ok.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_ok_dim.png b/core/res/res/drawable-ldpi/sym_keyboard_ok_dim.png
new file mode 100644
index 0000000..01cf616
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_ok_dim.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_return.png b/core/res/res/drawable-ldpi/sym_keyboard_return.png
new file mode 100644
index 0000000..1c7c58d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_return.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_shift.png b/core/res/res/drawable-ldpi/sym_keyboard_shift.png
new file mode 100644
index 0000000..382a08f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_shift.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_shift_locked.png b/core/res/res/drawable-ldpi/sym_keyboard_shift_locked.png
new file mode 100644
index 0000000..c644eff
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_shift_locked.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/sym_keyboard_space.png b/core/res/res/drawable-ldpi/sym_keyboard_space.png
new file mode 100644
index 0000000..0b91646
--- /dev/null
+++ b/core/res/res/drawable-ldpi/sym_keyboard_space.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_focus.9.png b/core/res/res/drawable-ldpi/tab_focus.9.png
new file mode 100644
index 0000000..59a0b65
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_focus.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_focus_bar_left.9.png b/core/res/res/drawable-ldpi/tab_focus_bar_left.9.png
new file mode 100755
index 0000000..0ee8347
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_focus_bar_left.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_focus_bar_right.9.png b/core/res/res/drawable-ldpi/tab_focus_bar_right.9.png
new file mode 100755
index 0000000..0ee8347
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_focus_bar_right.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_press.9.png b/core/res/res/drawable-ldpi/tab_press.9.png
new file mode 100644
index 0000000..ba9c82d
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_press.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_press_bar_left.9.png b/core/res/res/drawable-ldpi/tab_press_bar_left.9.png
new file mode 100755
index 0000000..ee129ba
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_press_bar_left.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_press_bar_right.9.png b/core/res/res/drawable-ldpi/tab_press_bar_right.9.png
new file mode 100755
index 0000000..ee129ba
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_press_bar_right.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_selected.9.png b/core/res/res/drawable-ldpi/tab_selected.9.png
new file mode 100644
index 0000000..318f09f
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_selected_bar_left.9.png b/core/res/res/drawable-ldpi/tab_selected_bar_left.9.png
new file mode 100755
index 0000000..03bcc13
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_selected_bar_left.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_selected_bar_left_v4.9.png b/core/res/res/drawable-ldpi/tab_selected_bar_left_v4.9.png
new file mode 100644
index 0000000..e7a07255
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_selected_bar_left_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_selected_bar_right.9.png b/core/res/res/drawable-ldpi/tab_selected_bar_right.9.png
new file mode 100755
index 0000000..f228445
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_selected_bar_right.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_selected_bar_right_v4.9.png b/core/res/res/drawable-ldpi/tab_selected_bar_right_v4.9.png
new file mode 100644
index 0000000..e7a07255
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_selected_bar_right_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_selected_v4.9.png b/core/res/res/drawable-ldpi/tab_selected_v4.9.png
new file mode 100644
index 0000000..2ad1757
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_selected_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_unselected.9.png b/core/res/res/drawable-ldpi/tab_unselected.9.png
new file mode 100644
index 0000000..de7c467
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_unselected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/tab_unselected_v4.9.png b/core/res/res/drawable-ldpi/tab_unselected_v4.9.png
new file mode 100644
index 0000000..61d4ef0
--- /dev/null
+++ b/core/res/res/drawable-ldpi/tab_unselected_v4.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/text_select_handle_left.png b/core/res/res/drawable-ldpi/text_select_handle_left.png
new file mode 100644
index 0000000..bded42c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/text_select_handle_left.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/text_select_handle_middle.png b/core/res/res/drawable-ldpi/text_select_handle_middle.png
new file mode 100644
index 0000000..c1d8d17
--- /dev/null
+++ b/core/res/res/drawable-ldpi/text_select_handle_middle.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/text_select_handle_right.png b/core/res/res/drawable-ldpi/text_select_handle_right.png
new file mode 100644
index 0000000..aae0b40
--- /dev/null
+++ b/core/res/res/drawable-ldpi/text_select_handle_right.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_default.9.png b/core/res/res/drawable-ldpi/textfield_default.9.png
new file mode 100644
index 0000000..4cfa745
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_disabled.9.png b/core/res/res/drawable-ldpi/textfield_disabled.9.png
new file mode 100644
index 0000000..e54bf30
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_disabled_selected.9.png b/core/res/res/drawable-ldpi/textfield_disabled_selected.9.png
new file mode 100644
index 0000000..02f6b5e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_disabled_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_pressed.9.png b/core/res/res/drawable-ldpi/textfield_pressed.9.png
new file mode 100644
index 0000000..1433365
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_search_default.9.png b/core/res/res/drawable-ldpi/textfield_search_default.9.png
new file mode 100644
index 0000000..dfb3f7a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_search_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_search_empty_default.9.png b/core/res/res/drawable-ldpi/textfield_search_empty_default.9.png
new file mode 100644
index 0000000..65fbe33
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_search_empty_default.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_search_empty_pressed.9.png b/core/res/res/drawable-ldpi/textfield_search_empty_pressed.9.png
new file mode 100644
index 0000000..2a72142
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_search_empty_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_search_empty_selected.9.png b/core/res/res/drawable-ldpi/textfield_search_empty_selected.9.png
new file mode 100644
index 0000000..162c178
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_search_empty_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_search_pressed.9.png b/core/res/res/drawable-ldpi/textfield_search_pressed.9.png
new file mode 100644
index 0000000..b414f6c
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_search_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_search_selected.9.png b/core/res/res/drawable-ldpi/textfield_search_selected.9.png
new file mode 100644
index 0000000..d6e6a44
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_search_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/textfield_selected.9.png b/core/res/res/drawable-ldpi/textfield_selected.9.png
new file mode 100644
index 0000000..80a6f39
--- /dev/null
+++ b/core/res/res/drawable-ldpi/textfield_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_down_disabled.9.png b/core/res/res/drawable-ldpi/timepicker_down_disabled.9.png
new file mode 100644
index 0000000..a4c2aba
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_down_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_down_disabled_focused.9.png b/core/res/res/drawable-ldpi/timepicker_down_disabled_focused.9.png
new file mode 100644
index 0000000..fdbc9d5
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_down_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_down_normal.9.png b/core/res/res/drawable-ldpi/timepicker_down_normal.9.png
new file mode 100644
index 0000000..c7e8018
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_down_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_down_pressed.9.png b/core/res/res/drawable-ldpi/timepicker_down_pressed.9.png
new file mode 100644
index 0000000..4dd82ae
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_down_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_down_selected.9.png b/core/res/res/drawable-ldpi/timepicker_down_selected.9.png
new file mode 100644
index 0000000..ebb701e
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_down_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_input_disabled.9.png b/core/res/res/drawable-ldpi/timepicker_input_disabled.9.png
new file mode 100644
index 0000000..39cc3d4
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_input_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_input_normal.9.png b/core/res/res/drawable-ldpi/timepicker_input_normal.9.png
new file mode 100644
index 0000000..6ffabe6
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_input_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_input_pressed.9.png b/core/res/res/drawable-ldpi/timepicker_input_pressed.9.png
new file mode 100644
index 0000000..9cfaaab
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_input_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_input_selected.9.png b/core/res/res/drawable-ldpi/timepicker_input_selected.9.png
new file mode 100644
index 0000000..e819e9b
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_input_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_up_disabled.9.png b/core/res/res/drawable-ldpi/timepicker_up_disabled.9.png
new file mode 100644
index 0000000..005a5ae
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_up_disabled.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_up_disabled_focused.9.png b/core/res/res/drawable-ldpi/timepicker_up_disabled_focused.9.png
new file mode 100644
index 0000000..f1c9465
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_up_disabled_focused.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_up_normal.9.png b/core/res/res/drawable-ldpi/timepicker_up_normal.9.png
new file mode 100644
index 0000000..9927539
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_up_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_up_pressed.9.png b/core/res/res/drawable-ldpi/timepicker_up_pressed.9.png
new file mode 100644
index 0000000..7946450
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_up_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/timepicker_up_selected.9.png b/core/res/res/drawable-ldpi/timepicker_up_selected.9.png
new file mode 100644
index 0000000..8c8136a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/timepicker_up_selected.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/title_bar_medium.9.png b/core/res/res/drawable-ldpi/title_bar_medium.9.png
new file mode 100644
index 0000000..ab95aad
--- /dev/null
+++ b/core/res/res/drawable-ldpi/title_bar_medium.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/title_bar_portrait.9.png b/core/res/res/drawable-ldpi/title_bar_portrait.9.png
new file mode 100644
index 0000000..6f868db
--- /dev/null
+++ b/core/res/res/drawable-ldpi/title_bar_portrait.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/title_bar_shadow.9.png b/core/res/res/drawable-ldpi/title_bar_shadow.9.png
new file mode 100644
index 0000000..fc45ee8
--- /dev/null
+++ b/core/res/res/drawable-ldpi/title_bar_shadow.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/title_bar_tall.9.png b/core/res/res/drawable-ldpi/title_bar_tall.9.png
new file mode 100644
index 0000000..b4729b7
--- /dev/null
+++ b/core/res/res/drawable-ldpi/title_bar_tall.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/toast_frame.9.png b/core/res/res/drawable-ldpi/toast_frame.9.png
new file mode 100644
index 0000000..3b344ff
--- /dev/null
+++ b/core/res/res/drawable-ldpi/toast_frame.9.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/unknown_image.png b/core/res/res/drawable-ldpi/unknown_image.png
new file mode 100644
index 0000000..c6255ba
--- /dev/null
+++ b/core/res/res/drawable-ldpi/unknown_image.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/usb_android.png b/core/res/res/drawable-ldpi/usb_android.png
new file mode 100644
index 0000000..d7b1d93
--- /dev/null
+++ b/core/res/res/drawable-ldpi/usb_android.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/usb_android_connected.png b/core/res/res/drawable-ldpi/usb_android_connected.png
new file mode 100644
index 0000000..c9d8439
--- /dev/null
+++ b/core/res/res/drawable-ldpi/usb_android_connected.png
Binary files differ
diff --git a/core/res/res/drawable-ldpi/zoom_plate.9.png b/core/res/res/drawable-ldpi/zoom_plate.9.png
new file mode 100644
index 0000000..5e34e7a
--- /dev/null
+++ b/core/res/res/drawable-ldpi/zoom_plate.9.png
Binary files differ
diff --git a/core/res/res/drawable/activated_background.xml b/core/res/res/drawable/activated_background.xml
index d92fba1..1047e5b 100644
--- a/core/res/res/drawable/activated_background.xml
+++ b/core/res/res/drawable/activated_background.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_activated="true" android:drawable="@android:drawable/list_selector_background_selected" />
<item android:drawable="@color/transparent" />
</selector>
diff --git a/core/res/res/drawable/activated_background_holo_dark.xml b/core/res/res/drawable/activated_background_holo_dark.xml
index febf2c4..a29bcb9 100644
--- a/core/res/res/drawable/activated_background_holo_dark.xml
+++ b/core/res/res/drawable/activated_background_holo_dark.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_activated="true" android:drawable="@android:drawable/list_activated_holo" />
<item android:drawable="@color/transparent" />
</selector>
diff --git a/core/res/res/drawable/activated_background_holo_light.xml b/core/res/res/drawable/activated_background_holo_light.xml
index febf2c4..a29bcb9 100644
--- a/core/res/res/drawable/activated_background_holo_light.xml
+++ b/core/res/res/drawable/activated_background_holo_light.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_activated="true" android:drawable="@android:drawable/list_activated_holo" />
<item android:drawable="@color/transparent" />
</selector>
diff --git a/core/res/res/drawable/activated_background_light.xml b/core/res/res/drawable/activated_background_light.xml
index 5d5681d..7d737db 100644
--- a/core/res/res/drawable/activated_background_light.xml
+++ b/core/res/res/drawable/activated_background_light.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_activated="true" android:drawable="@drawable/list_selector_background_selected_light" />
<item android:drawable="@color/transparent" />
</selector>
diff --git a/core/res/res/drawable/list_selector_background.xml b/core/res/res/drawable/list_selector_background.xml
index 6fb0661..f5eb12d 100644
--- a/core/res/res/drawable/list_selector_background.xml
+++ b/core/res/res/drawable/list_selector_background.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_window_focused="false" android:drawable="@color/transparent" />
diff --git a/core/res/res/drawable/list_selector_background_light.xml b/core/res/res/drawable/list_selector_background_light.xml
index 4da7e21..50a821b 100644
--- a/core/res/res/drawable/list_selector_background_light.xml
+++ b/core/res/res/drawable/list_selector_background_light.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_window_focused="false" android:drawable="@color/transparent" />
diff --git a/core/res/res/drawable/list_selector_holo_dark.xml b/core/res/res/drawable/list_selector_holo_dark.xml
index e4c5c52..9a6cb89 100644
--- a/core/res/res/drawable/list_selector_holo_dark.xml
+++ b/core/res/res/drawable/list_selector_holo_dark.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_window_focused="false" android:drawable="@color/transparent" />
diff --git a/core/res/res/drawable/list_selector_holo_light.xml b/core/res/res/drawable/list_selector_holo_light.xml
index 17631bd..844259e 100644
--- a/core/res/res/drawable/list_selector_holo_light.xml
+++ b/core/res/res/drawable/list_selector_holo_light.xml
@@ -14,7 +14,8 @@
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android">
+<selector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:exitFadeDuration="@android:integer/config_mediumAnimTime">
<item android:state_window_focused="false" android:drawable="@color/transparent" />
diff --git a/core/res/res/layout-xlarge/activity_list.xml b/core/res/res/layout-xlarge/activity_list.xml
new file mode 100644
index 0000000..9d6b8f5
--- /dev/null
+++ b/core/res/res/layout-xlarge/activity_list.xml
@@ -0,0 +1,130 @@
+<?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.
+-->
+
+<com.android.internal.widget.WeightedLinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/parentPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:paddingTop="9dip"
+ android:paddingBottom="3dip"
+ android:paddingLeft="3dip"
+ android:paddingRight="1dip"
+ android:majorWeightMin="0.45"
+ android:minorWeightMin="0.72"
+ android:majorWeightMax="0.45"
+ android:minorWeightMax="0.72">
+
+ <LinearLayout android:id="@+id/topPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="48dip"
+ android:orientation="vertical">
+ <LinearLayout android:id="@+id/title_template"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:gravity="center_vertical"
+ android:layout_marginTop="8dip"
+ android:layout_marginBottom="8dip"
+ android:layout_marginRight="32dip">
+ <ImageView android:id="@+id/icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingRight="16dip"
+ android:src="@null"
+ android:visibility="gone" />
+ <com.android.internal.widget.DialogTitle android:id="@+id/alertTitle"
+ style="?android:attr/textAppearanceLarge"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+ </LinearLayout>
+ <ImageView android:id="@+id/titleDivider"
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:scaleType="fitXY"
+ android:gravity="fill_horizontal"
+ android:src="@android:drawable/divider_horizontal_dark" />
+ <!-- If the client uses a customTitle, it will be added here. -->
+ </LinearLayout>
+
+ <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
+ android:layout_weight="1">
+
+ <ListView
+ android:id="@android:id/list"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+
+ <TextView
+ android:id="@android:id/empty"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:gravity="center"
+ android:text="@string/activity_list_empty"
+ android:visibility="gone"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ />
+ </FrameLayout>
+
+ <ImageView
+ android:layout_width="match_parent"
+ android:layout_height="1dip"
+ android:scaleType="fitXY"
+ android:gravity="fill_horizontal"
+ android:src="@android:drawable/divider_horizontal_dark" />
+
+ <LinearLayout android:id="@+id/buttonPanel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="54dip"
+ android:orientation="vertical" >
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingTop="4dip"
+ android:paddingLeft="2dip"
+ android:paddingRight="2dip"
+ android:measureWithLargestChild="true">
+ <LinearLayout android:id="@+id/leftSpacer"
+ android:layout_weight="0.25"
+ android:layout_width="0dip"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ />
+ <Button android:id="@+id/button1"
+ android:layout_width="0dip"
+ android:layout_gravity="center"
+ android:layout_weight="1"
+ android:maxLines="2"
+ android:text="@string/cancel"
+ android:layout_height="wrap_content" />
+ <LinearLayout android:id="@+id/rightSpacer"
+ android:layout_width="0dip"
+ android:layout_weight="0.25"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ />
+ </LinearLayout>
+ </LinearLayout>
+</com.android.internal.widget.WeightedLinearLayout>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index a2fa1a3..1083452 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -2786,6 +2786,10 @@
same pixel configuration as the screen (for instance: a ARGB 8888 bitmap with
an RGB 565 screen). -->
<attr name="dither" format="boolean" />
+ <!-- Amount of time (in milliseconds) to fade in a new state drawable. -->
+ <attr name="enterFadeDuration" format="integer" />
+ <!-- Amount of time (in milliseconds) to fade out an old state drawable. -->
+ <attr name="exitFadeDuration" format="integer" />
</declare-styleable>
<declare-styleable name="AnimationDrawable">
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index fd7e984..f8752d3 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1358,6 +1358,8 @@
<public type="attr" name="buttonGroupStyle" />
<public type="attr" name="alertDialogButtonGroupStyle" />
<public type="attr" name="homeAsUpIndicator" />
+ <public type="attr" name="enterFadeDuration" />
+ <public type="attr" name="exitFadeDuration" />
<public type="anim" name="animator_fade_in" />
<public type="anim" name="animator_fade_out" />
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index a43e334..9c0fcff 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -515,18 +515,21 @@
<h2><span class="en">Web Applications</span>
</h2>
<ul>
- <li><a href="<?cs var:toroot ?>guide/webapps/targetting.html">
- <span class="en">Targetting Android Devices</span>
- </a> <span class="new">new!</span><!-- 10/8/10 --></li>
+ <li><a href="<?cs var:toroot ?>guide/webapps/index.html">
+ <span class="en">Web Apps Overview</span>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
+ <li><a href="<?cs var:toroot ?>guide/webapps/targeting.html">
+ <span class="en">Targeting Screens from Web Apps</span>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
<li><a href="<?cs var:toroot ?>guide/webapps/webview.html">
<span class="en">Building Web Apps in WebView</span>
- </a> <span class="new">new!</span><!-- 10/8/10 --></li>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
<li><a href="<?cs var:toroot ?>guide/webapps/debugging.html">
<span class="en">Debugging Web Apps</span>
- </a> <span class="new">new!</span><!-- 10/8/10 --></li>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
<li><a href="<?cs var:toroot ?>guide/webapps/best-practices.html">
<span class="en">Best Practices for Web Apps</span>
- </a> <span class="new">new!</span><!-- 10/8/10 --></li>
+ </a> <span class="new">new!</span><!-- 11/1/10 --></li>
</ul>
</li>
diff --git a/docs/html/guide/webapps/best-practices.jd b/docs/html/guide/webapps/best-practices.jd
index 1bde5bf..4e9ae81 100644
--- a/docs/html/guide/webapps/best-practices.jd
+++ b/docs/html/guide/webapps/best-practices.jd
@@ -58,7 +58,7 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
</pre>
<p>For more information about how to use viewport meta data for Android-powered devices, read <a
-href="{@docRoot}guide/webapps/targetting.html">Targetting Android Devices</a>.</p>
+href="{@docRoot}guide/webapps/targeting.html">Targeting Screens from Web Apps</a>.</p>
</li>
diff --git a/docs/html/guide/webapps/debugging.jd b/docs/html/guide/webapps/debugging.jd
index 098e17c..ee4b723 100644
--- a/docs/html/guide/webapps/debugging.jd
+++ b/docs/html/guide/webapps/debugging.jd
@@ -86,7 +86,7 @@
<p>If you've implemented a custom {@link android.webkit.WebView} in your application, all the
same console APIs are supported when debugging your web page in WebView. On Android
1.6 and lower, console messages are automatically sent to logcat with the
-"WebCore" logging tag. If you're targetting Android 2.1 (API Level 7) or higher, then you must
+"WebCore" logging tag. If you're targeting Android 2.1 (API Level 7) or higher, then you must
provide a {@link android.webkit.WebChromeClient}
that implements the {@link android.webkit.WebChromeClient#onConsoleMessage(String,int,String)
onConsoleMessage()} callback method, in order for console messages to appear in logcat.</p>
diff --git a/docs/html/guide/webapps/index.jd b/docs/html/guide/webapps/index.jd
new file mode 100644
index 0000000..280380f
--- /dev/null
+++ b/docs/html/guide/webapps/index.jd
@@ -0,0 +1,71 @@
+page.title=Web Apps Overview
+@jd:body
+
+<div class="figure" style="width:327px">
+ <img src="{@docRoot}images/webapps/webapps.png" alt="" />
+ <p class="img-caption"><strong>Figure 1.</strong> You can make your web content available to
+users in two ways: in a traditional web browser and in an Android application, by
+including a WebView in the layout.</p>
+</div>
+
+<p>There are essentially two ways to deliver an application on Android: as a
+client-side application (developed using the Android SDK and installed on user devices as an {@code
+.apk}) or as a web application (developed using web standards and accessed through a web
+browser—there's nothing to install on user devices).</p>
+
+<p>The approach you choose for your application could depend on several factors, but Android makes
+the decision to develop a web application easier by providing:</p>
+<ul>
+ <li>Support for viewport properties that allow you to properly size your web application
+based on the screen size</li>
+ <li>CSS and JavaScript features that allow you to provide different styles and images
+based on the screen's pixel density (screen resolution)</li>
+</ul>
+
+<p>Thus, your decision to develop a web application for Android can exclude consideration for
+screen support, because it's already easy to make your web pages look good on all types of screens
+powered by Android.</p>
+
+<p>Another great feature of Android is that you don't have to build your application purely on
+the client or purely on the web. You can mix the two together by developing a client-side Android
+application that embeds some web pages (using a {@link android.webkit.WebView} in your Android
+application layout). Figure 1 visualizes how you can provide access to your web pages from either
+a web browser or your Android application. However, you shouldn't develop an Android
+application simply as a means to launch your web site. Rather, the web pages you embed in your
+Android application should be designed especially for that environment. You can even define an
+interface between your Android application and your web pages that allows JavaScript in the web
+pages to call upon APIs in your Android application—providing Android APIs to your web-based
+application.</p>
+
+<p>Since Android 1.0, {@link android.webkit.WebView} has been available for Android
+applications to embed web content in their layout and bind JavaScript to Android APIs. After
+Android added support for more screen densities (adding support for high and low-density
+screens), Android 2.0 added features to the WebKit framework to allow web pages to specify
+viewport properties and query the screen density in order to modify styles
+and image assets, as mentioned above. Because these features are a part of Android's WebKit
+framework, both the Android Browser (the default web browser provided with the platform) and
+{@link android.webkit.WebView} support the same viewport and screen density features.</p>
+
+<p>To develop a web application for Android-powered devices, you should read the
+following documents:</p>
+
+<dl>
+ <dt><a href="{@docRoot}guide/webapps/targeting.html"><strong>Targeting Screens from Web
+Apps</strong></a></dt>
+ <dd>How to properly size your web app on Android-powered devices and support
+multiple screen densities. The information in this document is important if you're building a web
+application that you at least expect to be available on Android-powered devices (which you should
+assume for anything you publish on the web), but especially if you're targeting mobile devices
+or using {@link android.webkit.WebView}.</dd>
+ <dt><a href="{@docRoot}guide/webapps/webview.html"><strong>Building Web Apps in
+WebView</strong></a></dt>
+ <dd>How to embed web pages into your Android application using {@link android.webkit.WebView} and
+bind JavaScript to Android APIs.</dd>
+ <dt><a href="{@docRoot}guide/webapps/debugging.html"><strong>Debugging Web Apps</strong></a></dt>
+ <dd>How to debug web apps using JavaScript Console APIs.</dd>
+ <dt><a href="{@docRoot}guide/webapps/best-practices.html"><strong>Best Practices for Web</strong>
+Apps</a></dt>
+ <dd>A list of practices you should follow, in order to provide an effective web application on
+Android-powered devices.</dd>
+</dl>
+
diff --git a/docs/html/guide/webapps/targeting.jd b/docs/html/guide/webapps/targeting.jd
new file mode 100644
index 0000000..bdc2d5e
--- /dev/null
+++ b/docs/html/guide/webapps/targeting.jd
@@ -0,0 +1,439 @@
+page.title=Targeting Screens from Web Apps
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Quickview</h2>
+<ul>
+ <li>You can target your web page for different screens using viewport metadata, CSS, and
+JavaScript</li>
+ <li>Techniques in this document work for Android 2.0 and greater, and for web pages rendered
+in the default Android Browser and in a {@link android.webkit.WebView}</li>
+</ul>
+
+<h2>In this document</h2>
+<ol>
+<li><a href="#Metadata">Using Viewport Metadata</a>
+ <ol>
+ <li><a href="#ViewportSize">Defining the viewport size</a></li>
+ <li><a href="#ViewportScale">Defining the viewport scale</a></li>
+ <li><a href="#ViewportDensity">Defining the viewport target density</a></li>
+ </ol>
+</li>
+<li><a href="#DensityCSS">Targeting Device Density with CSS</a></li>
+<li><a href="#DensityJS">targeting Device Density with JavaScript</a></li>
+</ol>
+
+</div>
+</div>
+
+
+<p>If you're developing a web application for Android or redesigning one for mobile devices, you
+should carefully consider how your web pages appear on different kinds of screens. Because
+Android is available on devices with different types of screens, you should account for some factors
+that affect the way your web pages appear on Android devices.</p>
+
+<p class="note"><strong>Note:</strong> The features described in this document are supported
+by the Android Browser application (provided with the default Android platform) and {@link
+android.webkit.WebView} (the framework view widget for displaying web pages), on Android 2.0 and
+greater. Third-party web browsers running on Android might not support these features for
+controlling the viewport size and screen densities.</p>
+
+<p>When targeting your web pages for Android devices, there are two fundamental factors that you
+should account for:</p>
+
+<dl>
+ <dt>The size of the viewport and scale of the web page</dt>
+ <dd>When the Android Browser loads a web page, the default behavior is to load the
+page in "overview mode," which provides a zoomed-out perspective of the web page. You can override
+this behavior for your web page by defining the default dimensions of the viewport or the initial
+scale of the viewport. You can also control how much the user can zoom in and out of your web
+page, if at all. The user can also disable overview mode in the
+Browser settings, so you should never assume that your page will load in overview mode. You
+should instead customize the viewport size and/or scale as appropriate for your page.</p>
+ <p>However, when your page is rendered in a {@link android.webkit.WebView}, the page loads at
+full zoom (not in "overview mode"). That is, it appears at the default size for the page,
+instead of zoomed out. (This is also how the page appears if the user disables overview
+mode.)</p></dd>
+
+ <dt>The device's screen density</dt>
+ <dd>The screen density (the number of pixels per inch) on an Android-powered device affects
+the resolution and size at which a web page is displayed. (There are three screen density
+categories: low, medium, and high.) The Android Browser and {@link android.webkit.WebView}
+compensate for variations in the screen
+density by scaling a web page so that all devices display the web page at the same perceivable size
+as a medium-density screen. If graphics are an important element of your web design, you
+should pay close attention to the scaling that occurs on different densities, because image scaling
+can produce artifacts (blurring and pixelation).
+ <p>To provide the best visual representation on all
+screen densities, you should control how scaling occurs by providing viewport metadata about
+your web page's target screen density and providing alternative graphics for different screen
+densities, which you can apply to different screens using CSS or JavaScript.</p></dd>
+</dl>
+
+<p>The rest of this document describes how you can account for these effects and provide a good
+design on multiple types of screens.</p>
+
+
+
+<h2 id="Metadata">Using Viewport Metadata</h2>
+
+<p>The viewport is the area in which your web page is drawn. Although the viewport's visible area
+matches the size of the screen,
+the viewport has its own dimensions that determine the number of pixels available to a web page.
+That is, the number of pixels available to a web page before it exceeds the screen area is
+defined by the dimensions of the viewport,
+not the dimensions of the device screen. For example, although a device screen might have a width of
+480 pixels, the viewport can have a width of 800 pixels, so that a web page designed to be 800
+pixels wide is completely visible on the screen.</p>
+
+<p>You can define properties of the viewport for your web page using the {@code "viewport"}
+property in an HTML {@code <meta>} tag (which must
+be placed in your document {@code <head>}). You can define multiple viewport properties in the
+{@code <meta>} tag's {@code content} attribute. For example, you can define the height and
+width of the viewport, the initial scale of the page, and the target screen density.
+Each viewport property in the {@code content} attribute must be separated by a comma.</p>
+
+<p>For example, the following snippet from an HTML document specifies that the viewport width
+should exactly match the device screen width and that the ability to zoom should be disabled:</p>
+
+<pre>
+<head>
+ <title>Example</title>
+ <meta name="viewport" content="width=device-width, user-scalable=no" />
+</head>
+</pre>
+
+<p>That's an example of just two viewport properties. The following syntax shows all of the
+supported viewport properties and the general types of values accepted by each one:</p>
+
+<pre>
+<meta name="viewport"
+ content="
+ <b>height</b> = [<em>pixel_value</em> | device-height] ,
+ <b>width</b> = [<em>pixel_value</em> | device-width ] ,
+ <b>initial-scale</b> = <em>float_value</em> ,
+ <b>minimum-scale</b> = <em>float_value</em> ,
+ <b>maximum-scale</b> = <em>float_value</em> ,
+ <b>user-scalable</b> = [yes | no] ,
+ <b>target-densitydpi</b> = [<em>dpi_value</em> | device-dpi |
+ high-dpi | medium-dpi | low-dpi]
+ " />
+</pre>
+
+<p>The following sections discuss how to use each of these viewport properties and exactly what the
+accepted values are.</p>
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-default.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 1.</strong> A web page with an image that's 320 pixels
+wide, in the Android Browser when there is no viewport metadata set (with "overview mode"
+enabled, the viewport is 800 pixels wide, by default).</p>
+</div>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-width400.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 2.</strong> A web page with viewport {@code width=400} and
+"overview mode" enabled (the image in the web page is 320 pixels wide).</p>
+</div>
+
+
+<h3 id="ViewportSize">Defining the viewport size</h3>
+
+<p>Viewport's {@code height} and {@code width} properties allow you to specify the size of the
+viewport (the number of pixels available to the web page before it goes off screen).</p>
+
+<p>As mentioned in the introduction above, the Android Browser loads pages in "overview mode" by
+default (unless disable by the user), which sets the minimum viewport width to 800 pixels. So, if
+your web page specifies its size to be 320 pixels wide, then your page appears smaller than the
+visible screen (even if the physical screen is 320 pixels wide, because the viewport simulates a
+drawable area that's 800 pixels wide), as shown in figure 1. To avoid this effect, you should
+explicitly define the viewport {@code width} to match the width for which you have designed your web
+page.</p>
+
+<p>For example, if your web page is designed to be exactly 320 pixels wide, then you might
+want to specify that size for the viewport width:</p>
+
+<pre>
+<meta name="viewport" content="width=320" />
+</pre>
+
+<p>In this case, your web page exactly fits the screen width, because the web page width and
+viewport width are the same.</p>
+
+<p class="note"><strong>Note:</strong> Width values that are greater than 10,000 are ignored and
+values less than (or equal to) 320 result in a value equal to the device-width (discussed below).
+Height values that are greater then 10,000 or less than 200 are also ignored.</p>
+
+<p>To demonstrate how this property affects the size of
+your web page, figure 2 shows a web page that contains an image that's 320 pixels
+wide, but with the viewport width set to 400.</p>
+
+
+<p class="note"><strong>Note:</strong> If you set the viewport width to match your web page width
+and the device's screen width does <em>not</em> match those dimensions, then the web page
+still fits the screen even if the device has a high or low-density screen, because the
+Android Browser and {@link android.webkit.WebView} scale web pages to match the perceived size on a
+medium-density screen, by default (as you can see in figure 2, when comparing the hdpi device to the
+mdpi device). Screen densities are discussed more in <a href="#ViewportDensity">Defining the
+viewport target density</a>.</p>
+
+
+<h4>Automatic sizing</h4>
+
+<p>As an alternative to specifying the viewport dimensions with exact pixels, you can set the
+viewport size to always match the dimensions of the device screen, by defining the
+viewport properties {@code height}
+and {@code width} with the values {@code device-height} and {@code device-width}, respectively. This
+is appropriate when you're developing a web application that has a fluid width (not fixed width),
+but you want it to appear as if it's fixed (to perfectly fit every screen as
+if the web page width is set to match each screen). For example:</p>
+
+<pre>
+<meta name="viewport" content="width=device-width" />
+</pre>
+
+<p>This results in the viewport width matching whatever the current screen width is, as shown in
+figure 3. It's important to notice that, this results in images being scaled to fit the screen
+when the current device does not match the <a href="#ViewportDensity">target
+density</a>, which is medium-density if you don't specify otherwise. As a result, the image
+displayed on the high-density device in figure 3 is scaled up in order to match the width
+of a screen with a medium-density screen.</p>
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-initialscale.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 3.</strong> A web page with viewport {@code
+width=device-width} <em>or</em> {@code initial-scale=1.0}.</p>
+</div>
+
+<p class="note"><strong>Note:</strong> If you instead want {@code
+device-width} and {@code device-height} to match the physical screen pixels for every device,
+instead of scaling your web page to match the target density, then you must also include
+the {@code target-densitydpi} property with a value of {@code device-dpi}. This is discussed more in
+the section about <a href="#ViewportDensity">Defining the viewport density</a>. Otherwise, simply
+using {@code device-height} and {@code device-width} to define the viewport size makes your web page
+fit every device screen, but scaling occurs on your images in order to adjust for different screen
+densities.</p>
+
+
+
+<h3 id="ViewportScale">Defining the viewport scale</h3>
+
+<p>The scale of the viewport defines the level of zoom applied to the web page. Viewport
+properties allow you to specify the scale of your web page in the following ways:</p>
+<dl>
+ <dt>{@code initial-scale}</dt>
+ <dd>The initial scale of the page. The value is a float that indicates a multiplier for your web
+page size, relative to the screen size. For example, if you set the initial scale to "1.0" then the
+web page is displayed to match the resolution of the <a href="#ViewportDensity">target
+density</a> 1-to-1. If set to "2.0", then the page is enlarged (zoomed in) by a factor of 2.
+ <p>The default initial scale is calculated to fit the web page in the viewport size.
+Because the default viewport width is 800 pixels, if the device screen resolution is less than
+800 pixels wide, the initial scale is something less than 1.0, by default, in order to fit the
+800-pixel-wide page on the screen.</p></dd>
+
+ <dt>{@code minimum-scale}</dt>
+ <dd>The minimum scale to allow. The value is a float that indicates the minimum multiplier for
+your web page size, relative to the screen size. For example, if you set this to "1.0", then the
+page can't zoom out because the minimum size is 1-to-1 with the <a href="#ViewportDensity">target
+density</a>.</dd>
+
+ <dt>{@code maximum-scale}</dt>
+ <dd>The maximum scale to allow for the page. The value is a float that indicates the
+maximum multiplier for your web page size,
+relative to the screen size. For example, if you set this to "2.0", then the page can't
+zoom in more than 2 times the target size.</dd>
+
+ <dt>{@code user-scalable}</dt>
+ <dd>Whether the user can change the scale of the page at all (zoom in and out). Set to {@code yes}
+to allow scaling and {@code no} to disallow scaling. The default is {@code yes}. If you set
+this to {@code no}, then the {@code minimum-scale} and {@code maximum-scale} are ignored,
+because scaling is not possible.</dd>
+</dl>
+
+<p>All scale values must be within the range 0.01–10.</p>
+
+<p>For example:</p>
+
+<pre>
+<meta name="viewport" content="initial-scale=1.0" />
+</pre>
+
+<p>This metadata sets the initial scale to be full sized, relative to the viewport's target
+density.</p>
+
+
+
+
+<h3 id="ViewportDensity">Defining the viewport target density</h3>
+
+<p>The density of a device's screen is based on the screen resolution, as defined by the number of
+dots per inch (dpi). There are three screen
+density categories supported by Android: low (ldpi), medium (mdpi), and high (mdpi). A screen
+with low density has fewer available pixels per inch, whereas a screen with high density has more
+pixels per inch (compared to a medium density screen). The Android Browser and {@link
+android.webkit.WebView} target a medium density screen by default.</p>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-initialscale-devicedpi.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 4.</strong> A web page with viewport {@code
+width=device-width} and {@code target-densitydpi=device-dpi}.</p>
+</div>
+
+
+<p>Because the default target density is medium, when users have a device with a low or high density
+screen, the Android Browser and {@link android.webkit.WebView} scale web pages (effectively zoom
+the pages) so they display at a
+size that matches the perceived appearance on a medium density screen. More specifically, the
+Android Browser and {@link android.webkit.WebView} apply approximately 1.5x scaling to web pages
+on a high density screen (because its screen pixels are smaller) and approximately 0.75x scaling to
+pages on a low density screen (because its screen pixels are bigger).</p>
+
+<p>Due to this default scaling, figures 1, 2, and 3 show the example web page at the same physical
+size on both the high and medium density device (the high-density device shows the
+web page with a default scale factor that is 1.5 times larger than the actual pixel resolution, to
+match the target density). This can introduce some undesirable artifacts in your images.
+For example, although an image appears the same size on a medium and high-density device, the image
+on the high-density device appears more blurry, because the image is designed to be 320 pixels
+wide, but is drawn with 480 pixels.</p>
+
+<p>You can change the target screen density for your web page using the {@code target-densitydpi}
+viewport property. It accepts the following values:</p>
+
+<ul>
+<li><code>device-dpi</code> - Use the device's native dpi as the target dpi. Default scaling never
+occurs.</li>
+<li><code>high-dpi</code> - Use hdpi as the target dpi. Medium and low density screens scale down
+as appropriate.</li>
+<li><code>medium-dpi</code> - Use mdpi as the target dpi. High density screens scale up and low
+density screens scale down. This is the default target density.</li>
+<li><code>low-dpi</code> - Use ldpi as the target dpi. Medium and high density screens scale up
+as appropriate.</li>
+<li><em><code><value></code></em> - Specify a dpi value to use as the target dpi. Values must
+be within the range 70–400.</li>
+</ul></p>
+
+<p>For example, to prevent the Android Browser and {@link android.webkit.WebView} from scaling
+your web page for different screen densities, set
+the {@code target-densitydpi} viewport property to {@code device-dpi}. When you do, the page is
+not scaled. Instead, the page is displayed at a size that matches the current screen's
+density. In this case, you should also define the viewport width to match the device width, so your
+web page naturally fits the screen size. For example:</p>
+
+<pre>
+<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
+</pre>
+
+<p>Figure 4 shows a web page using these viewport settings—the high-density device
+now displays the page smaller because its physical pixels are smaller than those on the
+medium-density device, so no scaling occurs and the 320-pixel-wide image is drawn using exactly 320
+pixels on both screens. (This is how you should define your viewport if
+you want to customize your web page based on screen density and provide different image assets for
+different densities, <a href="#DensityCSS">with CSS</a> or
+<a href="#DensityJS">with JavaScript</a>.)</p>
+
+
+<h2 id="DensityCSS">Targeting Device Density with CSS</h2>
+
+<p>The Android Browser and {@link android.webkit.WebView} support a CSS media feature that allows
+you to create styles for specific
+screen densities—the <code>-webkit-device-pixel-ratio</code> CSS media feature. The
+value you apply to this feature should be either
+"0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium density,
+or high density screens, respectively.</p>
+
+<p>For example, you can create separate stylesheets for each density:</p>
+
+<pre>
+<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" />
+<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" />
+<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" />
+</pre>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/webapps/compare-width-devicedpi-css.png" alt="" height="300" />
+ <p class="img-caption"><strong>Figure 5.</strong> A web page with CSS that's targetted to
+specific screen densities using the {@code -webkit-device-pixel-ratio} media feature. Notice
+that the hdpi device shows a different image that's applied in CSS.</p>
+</div>
+
+<p>Or, specify the different styles in one stylesheet:</p>
+
+<pre class="no-pretty-print">
+#header {
+ background:url(medium-density-image.png);
+}
+
+@media screen and (-webkit-device-pixel-ratio: 1.5) {
+ // CSS for high-density screens
+ #header {
+ background:url(high-density-image.png);
+ }
+}
+
+@media screen and (-webkit-device-pixel-ratio: 0.75) {
+ // CSS for low-density screens
+ #header {
+ background:url(low-density-image.png);
+ }
+}
+</pre>
+
+<p class="note"><strong>Note:</strong> The default style for {@code #header} applies the image
+designed for medium-density devices in order to support devices running a version of Android less
+than 2.0, which do not support the {@code -webkit-device-pixel-ratio} media feature.</p>
+
+<p>The types of styles you might want to adjust based on the screen density depend on how you've
+defined your viewport properties. To provide fully-customized styles that tailor your web page for
+each of the supported densities, you should set your viewport properties so the viewport width and
+density match the device. That is:</p>
+
+<pre>
+<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
+</pre>
+
+<p>This way, the Android Browser and {@link android.webkit.WebView} do not perform scaling on your
+web page and the viewport width
+matches the screen width exactly. On their own, these viewport properties create results shown in
+figure 4. However, by adding some custom CSS using the {@code -webkit-device-pixel-ratio} media
+feature, you can apply different styles. For example, figure 5 shows a web page with these viewport
+properties and also some CSS added that applies a high-resolution image for high-density
+screens.</p>
+
+
+
+<h2 id="DensityJS">Targeting Device Density with JavaScript</h2>
+
+<p>The Android Browser and {@link android.webkit.WebView} support a DOM property that allows you to
+query the density of the current
+device—the <code>window.devicePixelRatio</code> DOM property. The value of this property
+specifies the scaling factor used for the current device. For example, if the value
+of <code>window.devicePixelRatio</code> is "1.0", then the device is considered a medium density
+device and no scaling is applied by default; if the value is "1.5", then the device is
+considered a high density device and the page is scaled 1.5x by default; if the value
+is "0.75", then the device is considered a low density device and the page is scaled
+0.75x by default. Of course, the scaling that the Android Browser and {@link android.webkit.WebView}
+apply is based on the web page's
+target density—as described in the section about <a href="#ViewportDensity">Defining the
+viewport target density</a>, the default target is medium-density, but you can change the
+target to affect how your web page is scaled for different screen densities.</p>
+
+<p>For example, here's how you can query the device density with JavaScript:</p>
+
+<pre>
+if (window.devicePixelRatio == 1.5) {
+ alert("This is a high-density screen");
+} else if (window.devicePixelRation == 0.75) {
+ alert("This is a low-density screen");
+}
+</pre>
+
+
+
+
+
+
+
diff --git a/docs/html/guide/webapps/targetting.jd b/docs/html/guide/webapps/targetting.jd
deleted file mode 100644
index 844b9ca..0000000
--- a/docs/html/guide/webapps/targetting.jd
+++ /dev/null
@@ -1,419 +0,0 @@
-page.title=Targetting Android Devices
-@jd:body
-
-<div id="qv-wrapper">
-<div id="qv">
-<h2>Quickview</h2>
-<ul>
- <li>You can target your web page for different screens using viewport metadata, CSS, and
-JavaScript</li>
- <li>Techniques in this document work for Android 2.0 and greater</li>
-</ul>
-
-<h2>In this document</h2>
-<ol>
-<li><a href="#Metadata">Using Viewport Metadata</a>
- <ol>
- <li><a href="#ViewportSize">Defining the viewport size</a></li>
- <li><a href="#ViewportScale">Defining the viewport scale</a></li>
- <li><a href="#ViewportDensity">Defining the viewport target density</a></li>
- </ol>
-</li>
-<li><a href="#DensityCSS">Targetting Device Density with CSS</a></li>
-<li><a href="#DensityJS">Targetting Device Density with JavaScript</a></li>
-</ol>
-
-</div>
-</div>
-
-
-<p>If you're developing a web application for Android or redesigning one for mobile devices, you
-should account for some factors that affect the way the Android Browser renders your web page by
-default. There are two fundamental factors that you should account for:</p>
-
-<dl>
- <dt>The size of the viewport and scale of the web page</dt>
- <dd>When the Android Browser loads a web page, the default behavior is to load the
-page in "overview mode," which provides a zoomed-out perspective of the web page. You can override
-this behavior for your web page by defining the default dimensions of the viewport or the initial
-scale of the viewport. You can also control how much the user can zoom in and out of your web
-page, if at all.
- <p>However, the user can also disable overview mode in the
-Browser settings, so you should not assume that your page will load in overview mode. You
-should instead customize the viewport size and/or scale as appropriate for your page.</p></dd>
-
- <dt>The device's screen density</dt>
- <dd>The screen density (the number of pixels per inch) on an Android-powered device affects
-the resolution and size at which a web page is displayed. (There are three screen density
-categories: low, medium, and high.) The Android Browser compensates for variations in the screen
-density by scaling a web page so that all devices display the web page at the same perceivable size
-as a medium-density screen. If graphics are an important element of your web design, you
-should pay close attention to the scaling that occurs on different densities, because image scaling
-can produce artifacts (blurring and pixelation).
- <p>To provide the best visual representation on all
-screen densities, you should control how scaling occurs by providing viewport metadata about
-your web page's target screen density and providing alternative graphics for different screen
-densities, which you can apply to different screens using CSS or JavaScript.</p></dd>
-</dl>
-
-<p>The rest of this document describes how you can account for these effects, and how to target
-your web page for specific screen configurations.</p>
-
-<p class="note"><strong>Note:</strong> The features described in this document are supported
-by the Android Browser application on Android 2.0 and greater. Third-party web browsers running on
-Android might not support these techniques for controlling the viewport size and targetting
-screen densities.</p>
-
-
-
-<h2 id="Metadata">Using Viewport Metadata</h2>
-
-<p>The viewport is the area in which the Android Browser
-draws a web page. Although the viewport's visible area matches the size of the screen,
-the viewport has its own dimensions that determine the number of pixels available to a web page.
-That is, the number of pixels available to a web page before it exceeds the screen area is
-defined by the dimensions of the viewport,
-not the dimensions of the device screen. For example, although a device screen might have a width of
-480 pixels, the viewport can have a width of 800 pixels, so that a web page designed to be 800
-pixels wide is completely visible on the screen.</p>
-
-<p>You can define properties of the viewport for your web page using the {@code "viewport"}
-property in an HTML {@code <meta>} tag (which must
-be placed in your document {@code <head>}). You can define multiple viewport properties in the
-{@code <meta>} tag's {@code content} attribute. For example, you can define the height and
-width of the viewport, the initial scale of the page, and the target screen density.
-Each viewport property in the {@code content} attribute must be separated by a comma.</p>
-
-<p>For example, the following snippet from an HTML document specifies that the viewport width
-should exactly match the device screen width and that the ability to zoom should be disabled:</p>
-
-<pre>
-<head>
- <title>Example</title>
- <meta name="viewport" content="width=device-width, user-scalable=no" />
-</head>
-</pre>
-
-<p>That's an example of just two viewport properties. The following syntax shows all of the
-supported viewport properties and the general types of values accepted by each one:</p>
-
-<pre>
-<meta name="viewport"
- content="
- <b>height</b> = [<em>pixel_value</em> | device-height] ,
- <b>width</b> = [<em>pixel_value</em> | device-width ] ,
- <b>initial-scale</b> = <em>float_value</em> ,
- <b>minimum-scale</b> = <em>float_value</em> ,
- <b>maximum-scale</b> = <em>float_value</em> ,
- <b>user-scalable</b> = [yes | no] ,
- <b>target-densitydpi</b> = [<em>dpi_value</em> | device-dpi |
- high-dpi | medium-dpi | low-dpi]
- " />
-</pre>
-
-<p>The following sections discuss how to use each of these viewport properties and exactly what the
-accepted values are.</p>
-
-<div class="figure" style="width:300px">
- <img src="{@docRoot}images/webapps/compare-default.png" alt="" height="300" />
- <p class="img-caption"><strong>Figure 1.</strong> A web page with no viewport metadata and an
-image that's 320 pixels wide (the viewport is 800 pixels wide, by default).</p>
-</div>
-
-
-<div class="figure" style="width:300px">
- <img src="{@docRoot}images/webapps/compare-width400.png" alt="" height="300" />
- <p class="img-caption"><strong>Figure 2.</strong> A web page with viewport {@code width=400}
-(the image in the web page is 320 pixels wide).</p>
-</div>
-
-
-<h3 id="ViewportSize">Defining the viewport size</h3>
-
-<p>Viewport's {@code height} and {@code width} properties allow you to specify the size of the
-viewport (the number of pixels available to the web page before it goes off screen). By default, the
-Android Browser's minimum viewport width is 800 pixels, so if your web
-page specifies its size to be 320 pixels wide, then your page renders smaller than the visible
-screen (even if the physical screen is 320 pixels wide, because the viewport simulates a
-drawable area that's 800 pixels wide), as shown in figure 1. So, you should explicitly define the
-viewport {@code width} to match the width for which you have designed your web page.</p>
-
-<p class="note"><strong>Note:</strong> Width values that are greater than 10,000 are ignored and
-values less than (or equal to) 320 result in a value equal to the device-width. Height values that
-are greater then 10,000 or less than 200 are also ignored.</p>
-
-<p>For example, if your web page is designed to be exactly 320 pixels wide, then you might
-want to specify that for the viewport width:</p>
-
-<pre>
-<meta name="viewport" content="width=320" />
-</pre>
-
-<p>In this case, your web page exactly fits the screen width, because the web page width and
-viewport width are the same.</p>
-
-<p>To demonstrate how this property affects the size of
-your web page, figure 2 shows a web page that contains an image that's 320 pixels wide, but with the
-viewport width set to 400.</p>
-
-
-<p class="note"><strong>Note:</strong> If you set the viewport width to match your web page width
-and the device screen width does <em>not</em> match those dimensions, then the web page
-still fits the screen even if the device has a high or low-density screen, because the
-Android Browser scales web pages to match the perceived size on a medium-density
-screen, by default (as you can see in figure 2, when comparing the hdpi device to the mdpi device).
-Screen densities are discussed more in <a href="#ViewportDensity">Defining the viewport target
-density</a>.</p>
-
-
-<h4>Automatic sizing</h4>
-
-<p>As an alternative to specifying the viewport dimensions with exact pixels, you can set the
-viewport size to always match the dimensions of the device screen, by defining the
-viewport properties {@code height}
-and {@code width} with the values {@code device-height} and {@code device-width}, respectively. This
-is appropriate when you're developing a web application that has a fluid width (not fixed width),
-but you want it to appear as if it's fixed (to perfectly fit every screen as
-if the web page width is set to match each screen). For example:</p>
-
-<pre>
-<meta name="viewport" content="width=device-width" />
-</pre>
-
-<p>This results in the viewport width matching whatever the current screen width is, as shown in
-figure 3. It's important to notice that, this results in images being scaled to fit the screen
-when the current device does not match the <a href="#ViewportDensity">target
-density</a>, which is medium-density if you don't specify otherwise. As a result, the image
-displayed on the high-density device in figure 3 is scaled up in order to match the width
-of a screen with a medium-density screen.</p>
-
-<div class="figure" style="width:300px">
- <img src="{@docRoot}images/webapps/compare-initialscale.png" alt="" height="300" />
- <p class="img-caption"><strong>Figure 3.</strong> A web page with viewport {@code
-width=device-width} <em>or</em> {@code initial-scale=1.0}.</p>
-</div>
-
-<p class="note"><strong>Note:</strong> If you instead want {@code
-device-width} and {@code device-height} to match the physical screen pixels for every device,
-instead of scaling your web page to match the target density, then you must also include
-the {@code target-densitydpi} property with a value of {@code device-dpi}. This is discussed more in
-the section about <a href="#ViewportDensity">Defining the viewport density</a>. Otherwise, simply
-using {@code device-height} and {@code device-width} to define the viewport size makes your web page
-fit every device screen, but scaling occurs on your images in order to adjust for different screen
-densities.</p>
-
-
-
-<h3 id="ViewportScale">Defining the viewport scale</h3>
-
-<p>The scale of the viewport defines the level of zoom applied to the web page. Viewport
-properties allow you to specify the scale of your web page in the following ways:</p>
-<dl>
- <dt>{@code initial-scale}</dt>
- <dd>The initial scale of the page. The value is a float that indicates a multiplier for your web
-page size, relative to the screen size. For example, if you set the initial scale to "1.0" then the
-web page is displayed to match the resolution of the <a href="#ViewportDensity">target
-density</a> 1-to-1. If set to "2.0", then the page is enlarged (zoomed in) by a factor of 2.
- <p>The default initial scale is calculated to fit the web page in the viewport size.
-Because the default viewport width is 800 pixels, if the device screen resolution is less than
-800 pixels wide, the initial scale is something less than 1.0, by default, in order to fit the
-800-pixel-wide page on the screen.</p></dd>
-
- <dt>{@code minimum-scale}</dt>
- <dd>The minimum scale to allow. The value is a float that indicates the minimum multiplier for
-your web page size, relative to the screen size. For example, if you set this to "1.0", then the
-page can't zoom out because the minimum size is 1-to-1 with the <a href="#ViewportDensity">target
-density</a>.</dd>
-
- <dt>{@code maximum-scale}</dt>
- <dd>The maximum scale to allow for the page. The value is a float that indicates the
-maximum multiplier for your web page size,
-relative to the screen size. For example, if you set this to "2.0", then the page can't
-zoom in more than 2 times the target size.</dd>
-
- <dt>{@code user-scalable}</dt>
- <dd>Whether the user can change the scale of the page at all (zoom in and out). Set to {@code yes}
-to allow scaling and {@code no} to disallow scaling. The default is {@code yes}. If you set
-this to {@code no}, then the {@code minimum-scale} and {@code maximum-scale} are ignored,
-because scaling is not possible.</dd>
-</dl>
-
-<p>All scale values must be within the range 0.01–10.</p>
-
-<p>For example:</p>
-
-<pre>
-<meta name="viewport" content="initial-scale=1.0" />
-</pre>
-
-<p>This metadata sets the initial scale to be full sized, relative to the viewport's target
-density.</p>
-
-
-
-
-<h3 id="ViewportDensity">Defining the viewport target density</h3>
-
-<p>The density of a device's screen is based on the screen resolution. There are three screen
-density categories supported by Android: low (ldpi), medium (mdpi), and high (mdpi). A screen
-with low density has fewer available pixels per inch, whereas a screen with high density has more
-pixels per inch (compared to a medium density screen). The Android Browser targets a medium density
-screen by default.</p>
-
-
-<div class="figure" style="width:300px">
- <img src="{@docRoot}images/webapps/compare-initialscale-devicedpi.png" alt="" height="300" />
- <p class="img-caption"><strong>Figure 4.</strong> A web page with viewport {@code
-width=device-width} and {@code target-densitydpi=device-dpi}.</p>
-</div>
-
-
-<p>Because the default target density is medium, when users have a device with a low or high density
-screen, the Android Browser scales web pages (effectively zooms the pages) so they display at a
-size that matches the perceived appearance on a medium density screen. Specifically, the Android
-Browser applies approximately 1.5x scaling to web pages on a high density screen
-(because its screen pixels are smaller) and approximately 0.75x scaling to pages on a low density
-screen (because its screen pixels are bigger).</p>
-
-<p>Due to this default scaling, figures 1, 2, and 3 show the example web page at the same physical
-size on both the high and medium density device (the high-density device shows the
-web page with a default scale factor that is 1.5 times larger than the actual pixel resolution, to
-match the target density). This can introduce some undesirable artifacts in your images.
-For example, although an image appears the same size on a medium and high-density device, the image
-on the high-density device appears more blurry, because the image is designed to be 320 pixels
-wide, but is drawn with 480 pixels.</p>
-
-<p>You can change the target screen density for your web page using the {@code target-densitydpi}
-viewport property. It accepts the following values:</p>
-
-<ul>
-<li><code>device-dpi</code> - Use the device's native dpi as the target dpi. Default scaling never
-occurs.</li>
-<li><code>high-dpi</code> - Use hdpi as the target dpi. Medium and low density screens scale down
-as appropriate.</li>
-<li><code>medium-dpi</code> - Use mdpi as the target dpi. High density screens scale up and low
-density screens scale down. This is the default target density.</li>
-<li><code>low-dpi</code> - Use ldpi as the target dpi. Medium and high density screens scale up
-as appropriate.</li>
-<li><em><code><value></code></em> - Specify a dpi value to use as the target dpi. Values must
-be within the range 70–400.</li>
-</ul></p>
-
-<p>For example, to prevent the Android Browser from scaling of your web page for different screen
-densities, set
-the {@code target-densitydpi} viewport property to {@code device-dpi}. When you do, the Android
-Browser does not scale the page and, instead, displays your web page to match the current screen
-density. In this case, you should also define the viewport width to match the device width, so your
-web page naturally fits the screen size. For example:</p>
-
-<pre>
-<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
-</pre>
-
-<p>Figure 4 shows a web page using these viewport settings—the high-density device
-now displays the page smaller because its physical pixels are smaller than those on the
-medium-density device, so no scaling occurs and the 320-pixel-wide image is drawn using exactly 320
-pixels on both screens. (This is how you should define your viewport if
-you want to customize your web page based on screen density and provide different image assets for
-different densities, <a href="#DensityCSS">with CSS</a> or
-<a href="#DensityJS">with JavaScript</a>.)</p>
-
-
-<h2 id="DensityCSS">Targetting Device Density with CSS</h2>
-
-<p>The Android Browser supports a CSS media feature that allows you to create styles for specific
-screen densities—the <code>-webkit-device-pixel-ratio</code> CSS media feature. The
-value you apply to this feature should be either
-"0.75", "1", or "1.5", to indicate that the styles are for devices with low density, medium density,
-or high density screens, respectively.</p>
-
-<p>For example, you can create separate stylesheets for each density:</p>
-
-<pre>
-<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.5)" href="hdpi.css" />
-<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 1.0)" href="mdpi.css" />
-<link rel="stylesheet" media="screen and (-webkit-device-pixel-ratio: 0.75)" href="ldpi.css" />
-</pre>
-
-
-<div class="figure" style="width:300px">
- <img src="{@docRoot}images/webapps/compare-width-devicedpi-css.png" alt="" height="300" />
- <p class="img-caption"><strong>Figure 5.</strong> A web page with CSS that's targetted to
-specific screen densities using the {@code -webkit-device-pixel-ratio} media feature. Notice
-that the hdpi device shows a different image that's applied in CSS.</p>
-</div>
-
-<p>Or, specify the different styles in one stylesheet:</p>
-
-<pre class="no-pretty-print">
-#header {
- background:url(medium-density-image.png);
-}
-
-@media screen and (-webkit-device-pixel-ratio: 1.5) {
- // CSS for high-density screens
- #header {
- background:url(high-density-image.png);
- }
-}
-
-@media screen and (-webkit-device-pixel-ratio: 0.75) {
- // CSS for low-density screens
- #header {
- background:url(low-density-image.png);
- }
-}
-</pre>
-
-<p class="note"><strong>Note:</strong> The default style for {@code #header} applies the image
-designed for medium-density devices in order to support devices running a version of Android less
-than 2.0, which do not support the {@code -webkit-device-pixel-ratio} media feature.</p>
-
-<p>The types of styles you might want to adjust based on the screen density depend on how you've
-defined your viewport properties. To provide fully-customized styles that tailor your web page for
-each of the supported densities, you should set your viewport properties so the viewport width and
-density match the device. That is:</p>
-
-<pre>
-<meta name="viewport" content="target-densitydpi=device-dpi, width=device-width" />
-</pre>
-
-<p>This way, the Android Browser does not perform scaling on your web page and the viewport width
-matches the screen width exactly. On its own, these viewport properties create results shown in
-figure 4. However, by adding some custom CSS using the {@code -webkit-device-pixel-ratio} media
-feature, you can apply different styles. For example, figure 5 shows a web page with these viewport
-properties and also some CSS added that applies a high-resolution image for high-density
-screens.</p>
-
-
-
-<h2 id="DensityJS">Targetting Device Density with JavaScript</h2>
-
-<p>The Android Browser supports a DOM property that allows you to query the density of the current
-device—the <code>window.devicePixelRatio</code> DOM property. The value of this property
-specifies the scaling factor used for the current device. For example, if the value
-of <code>window.devicePixelRatio</code> is "1.0", then the device is considered a medium density
-device and no scaling is applied by default; if the value is "1.5", then the device is
-considered a high density device and the page is scaled 1.5x by default; if the value
-is "0.75", then the device is considered a low density device and the page is scaled
-0.75x by default. Of course, the scaling that the Android Browser applies is based on the web page's
-target density—as described in the section about <a href="#ViewportDensity">Defining the
-viewport target density</a>, the default target is medium-density, but you can change the
-target to affect how your web page is scaled for different screen densities.</p>
-
-<p>For example, here's how you can query the device density with JavaScript:</p>
-
-<pre>
-if (window.devicePixelRatio == 1.5) {
- alert("This is a high-density screen");
-} else if (window.devicePixelRation == 0.75) {
- alert("This is a low-density screen");
-}
-</pre>
-
-
-
-
-
-
-
diff --git a/docs/html/images/webapps/compare-default.png b/docs/html/images/webapps/compare-default.png
index 9495a05..129cb33 100644
--- a/docs/html/images/webapps/compare-default.png
+++ b/docs/html/images/webapps/compare-default.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-initialscale-devicedpi.png b/docs/html/images/webapps/compare-initialscale-devicedpi.png
index 6bb758a..3b0fb6a 100644
--- a/docs/html/images/webapps/compare-initialscale-devicedpi.png
+++ b/docs/html/images/webapps/compare-initialscale-devicedpi.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-initialscale.png b/docs/html/images/webapps/compare-initialscale.png
index 2232d5b..09314bb 100644
--- a/docs/html/images/webapps/compare-initialscale.png
+++ b/docs/html/images/webapps/compare-initialscale.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-width-devicedpi-css.png b/docs/html/images/webapps/compare-width-devicedpi-css.png
index bb4ab31..3efa386 100644
--- a/docs/html/images/webapps/compare-width-devicedpi-css.png
+++ b/docs/html/images/webapps/compare-width-devicedpi-css.png
Binary files differ
diff --git a/docs/html/images/webapps/compare-width400.png b/docs/html/images/webapps/compare-width400.png
index 669a234..d654381 100644
--- a/docs/html/images/webapps/compare-width400.png
+++ b/docs/html/images/webapps/compare-width400.png
Binary files differ
diff --git a/docs/html/images/webapps/webapps.png b/docs/html/images/webapps/webapps.png
new file mode 100644
index 0000000..6ad6205
--- /dev/null
+++ b/docs/html/images/webapps/webapps.png
Binary files differ
diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs
index a2c94fe..1c1ece9 100644
--- a/docs/html/resources/resources_toc.cs
+++ b/docs/html/resources/resources_toc.cs
@@ -87,7 +87,7 @@
?>
<li>
- <h2><span class="en">More</span>
+ <h2><span class="en">More</span>
</h2>
<ul>
<li><a href="<?cs var:toroot ?>resources/faq/commontasks.html">
diff --git a/docs/html/resources/samples/images/SipDemo.png b/docs/html/resources/samples/images/SipDemo.png
new file mode 100755
index 0000000..999bea9
--- /dev/null
+++ b/docs/html/resources/samples/images/SipDemo.png
Binary files differ
diff --git a/docs/html/resources/samples/index.jd b/docs/html/resources/samples/index.jd
index 9fc8e0bf..cbe6ca3 100644
--- a/docs/html/resources/samples/index.jd
+++ b/docs/html/resources/samples/index.jd
@@ -73,6 +73,10 @@
<dd>A sample application that demonstrates Android's search framework,
including how to provide search suggestions for Quick Search Box.</dd>
+ <dt><a href="SipDemo/index.html">SIP Demo</a></dt>
+ <dd>An application that demonstrates how to make an internet-based call using the SIP
+ API.</dd>
+
<dt><a href="Snake/index.html">Snake</a></dt>
<dd>An implementation of the classic game "Snake."</dd>
diff --git a/docs/html/sdk/adding-components.jd b/docs/html/sdk/adding-components.jd
index 755f200..05be0d6 100644
--- a/docs/html/sdk/adding-components.jd
+++ b/docs/html/sdk/adding-components.jd
@@ -22,11 +22,9 @@
</div>
</div>
-<p>Adding and updating components in your Android SDK is fast and easy. To
-perform an update, use the <strong>Android SDK and AVD Manager</strong> to
-install or update the individual SDK components that you need. The Android SDK
-and AVD Manager tool is included in the <a href="index.html">Android SDK
-download</a>.</p>
+<p>Adding and updating components in your Android SDK is fast and easy. To add or
+update the individual SDK components that you need, use the <em>Android SDK and AVD
+Manager</em> (included in the SDK Tools).</p>
<p>It only takes a couple of clicks to install individual versions of the
Android platform, new development tools, new documentation, and SDK add-ons. The
@@ -34,32 +32,17 @@
so you don't need to update your development environment to specify a new SDK
location.</p>
-<p>Because each version of the Android platform can be installed as an
-individual component of your SDK, you can customize your development environment
-to the Android platforms you are targetting. Testing your app on multiple
-versions of the platform is very important in order to successfully operate on
-as many devices as possible. Be sure to install each version of the Android
-platform with which your app is compatible, then test your apps on <a
-href="{@docRoot}guide/developing/tools/avd.html">AVDs</a> that run each
-platform.</p>
+<p>If you're setting up your Android SDK for the first time,
+see <a href="{@docRoot}sdk/installing.html#components">Installing the SDK</a> for information about
+what components to install.</p>
-<p>If you are just getting started and you are not sure what components to install,
-see <a href="installing.html#components">Adding Platforms and Other
-Components</a> for information. </p>
+<p class="note"><strong>Note:</strong> If you develop in Eclipse, you might also need
+to update your ADT plugin when you update your development tools. See the revisions listed in the
+<a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin for Eclipse</a> document.</p>
-<p>If you develop applications using Eclipse, you may also need to update your
-ADT plugin when you update your development tools, in order to compile against
-a new version of the platform. See the revisions listed in the <a
-href="{@docRoot}sdk/tools-notes.html">SDK Tools</a> document for ADT
-Plugin compatibility.</p>
-
-<div style="TEXT-ALIGN:left; width:600px;">
-<img src="{@docRoot}images/sdk_manager_packages.png"
-style="padding-bottom:0;margin-bottom:0;" />
-<p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0
-1em;"><strong>Figure 1.</strong> The Android SDK and AVD Manager's
-<strong>Available Packages</strong>
-panel, which shows the SDK components that are
+<img src="{@docRoot}images/sdk_manager_packages.png" alt="" />
+<p class="img-caption"><strong>Figure 1.</strong> The Android SDK and AVD Manager's
+<strong>Available Packages</strong> panel, which shows the SDK components that are
available for you to download into your environment. </p>
</div>
@@ -68,13 +51,7 @@
<p>The Android SDK and AVD Manager is the tool that you use to install and
upgrade SDK components in your development environment. </p>
-<p>You can access the tool in any of three ways:</p>
-<ul>
-<li>If you are developing in the Eclipse IDE with the ADT Plugin, you can access
-the tool directly from the Eclipse UI.</li>
-<li>On Windows only, you can launch he tool by double-clicking a script file.</li>
-<li>In all environments, you can access the tool from a command line.</li>
-</ul>
+<p>You can launch the Android SDK and AVD Manager in one of the following ways.</p>
<h4>Launching from Eclipse/ADT</h4>
@@ -122,7 +99,7 @@
from the SDK repository.</li>
<li>Select the component(s) you'd like to install and click <strong>Install
Selected</strong>. If you aren't sure which packages to select, read <a
- href="installing.html#which">Which components do I need?</a>.</li>
+ href="installing.html#which">Recommended Components</a>.</li>
<li>Verify and accept the components you want and click <strong>Install
Accepted</strong>. The components will now be installed into your existing
Android SDK directories.</li>
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index 9f3c8b0..632fa4b 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -28,7 +28,7 @@
</div>
</div>
-<p>Android Development Tools (ADT) is a plugin for the Eclipse IDE
+<p>Android Development Tools (ADT) is a plugin for the Eclipse IDE
that is designed to give you a powerful, integrated environment in which
to build Android applications. </p>
@@ -48,7 +48,7 @@
Eclipse IDE and the Android SDK installed. For details, make sure to read <a
href="#installing">Installing the ADT Plugin</a>, below. </p>
-<p>If you are already using ADT, this document also provides instructions on
+<p>If you are already using ADT, this document also provides instructions on
how to update ADT to the latest version or how to uninstall it, if necessary.
</p>
@@ -156,7 +156,7 @@
called <code>src/</code>. There is now support for any number of source folders,
with no name restriction. They can even be in subfolder such as
<code>src/java</code>. If you are already working with library projects created
-in ADT 0.9.7, see <a
+in ADT 0.9.7, see <a
href="{@docRoot}guide/developing/eclipse-adt.html#libraryMigrating">Migrating
library projects to ADT 0.9.8</a> for important information about moving
to the new ADT environment.</li>
@@ -166,7 +166,7 @@
<code>car</code>/<code>desk</code>, <code>night</code>/<code>notnight</code> and
<code>navexposed</code>/<code>navhidden</code>.</li>
<li>Adds more device screen types in the layout editor. All screen
-resolution/density combinations listed in the <a
+resolution/density combinations listed in the <a
href="{@docRoot}guide/practices/screens_support.html#range">Supporting
Multiple Screens</a> are now available.</li>
<li>Fixes problems with handling of library project names that
@@ -195,10 +195,10 @@
library project from other Android projects and, at build time, the tools
compile the shared code and resources as part of the dependent applications.
More information about this feature is available in the <a
-href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing
+href="{@docRoot}guide/developing/eclipse-adt.html#libraryProject">Developing
in Eclipse with ADT</a> document. </p>
-<p>If you are not developing in Eclipse, <a
-href="tools-notes.html">SDK Tools r6</a> provides the equivalent library
+<p>If you are not developing in Eclipse, <a
+href="tools-notes.html">SDK Tools r6</a> provides the equivalent library
project support through the Ant build system.</p>
</dd>
</dl>
@@ -215,7 +215,7 @@
<dl>
<dt>Dependencies:</dt>
-<dd><p>ADT 0.9.6 is designed for use with SDK Tools r5 and later. Before
+<dd><p>ADT 0.9.6 is designed for use with SDK Tools r5 and later. Before
updating to ADT 0.9.6, we highly recommend that you use the Android SDK and
AVD Manager to install SDK Tools r5 into your SDK.</p></dd>
@@ -339,7 +339,7 @@
<ul>
<li>Includes the improvements from the standlone DDMS, revision 3.</li>
<li>Adds an option to open HPROF files into eclipse instead of writing them on
-disk. If a profiler such as MAT (<a href="http://eclipse.org/mat">Memory Analyzer
+disk. If a profiler such as MAT (<a href="http://eclipse.org/mat">Memory Analyzer
Tool</a>) is installed, it'll open the file.</li>
</ul>
</dd>
@@ -347,7 +347,7 @@
<dt>Android SDK and AVD Manager integration:</dt>
<dd>
<ul>
-<li>Includes the improvements from the standalone Android SDK and AVD Manager,
+<li>Includes the improvements from the standalone Android SDK and AVD Manager,
revision 3.</li>
</ul>
</dd>
@@ -408,16 +408,16 @@
<td width="45%">
<!-- 3.4 steps -->
<ol>
- <li>Start Eclipse, then select <strong>Help</strong> > <strong>Software Updates...</strong>.
+ <li>Start Eclipse, then select <strong>Help</strong> > <strong>Software Updates...</strong>.
In the dialog that appears, click the <strong>Available Software</strong> tab. </li>
<li>Click <strong>Add Site...</strong> </li>
<li>In the Add Site dialog that appears, enter this URL in the "Location" field:
<pre style="margin-left:0">https://dl-ssl.google.com/android/eclipse/</pre>
<p>Note: If you have trouble acquiring the plugin, try using "http" in the Location URL,
- instead of "https" (https is preferred for security reasons).</p>
+ instead of "https" (https is preferred for security reasons).</p>
<p>Click <strong>OK</strong>.</p></li>
<li>Back in the Available Software view, you should see the plugin listed by the URL,
- with "Developer Tools" nested within it. Select the checkbox next to
+ with "Developer Tools" nested within it. Select the checkbox next to
Developer Tools and click <strong>Install...</strong></li>
<li>On the subsequent Install window, "Android DDMS" and "Android Development Tools"
should both be checked. Click <strong>Next</strong>. </li>
@@ -433,25 +433,25 @@
New Software</strong>. </li>
<li>In the Available Software dialog, click <strong>Add...</strong>.</li>
<li>In the Add Site dialog that appears, enter a name for the remote site
- (for example, "Android Plugin") in the "Name" field.
+ (for example, "Android Plugin") in the "Name" field.
<p>In the "Location" field, enter this URL:</p>
<pre>https://dl-ssl.google.com/android/eclipse/</pre>
<p>Note: If you have trouble acquiring the plugin, you can try
- using "http" in the URL, instead of "https" (https is preferred for
+ using "http" in the URL, instead of "https" (https is preferred for
security reasons).</p>
<p>Click <strong>OK</strong>.</p>
</li>
<li>Back in the Available Software view, you should now see "Developer
- Tools" added to the list. Select the checkbox next to Developer Tools,
- which will automatically select the nested tools Android DDMS and Android
- Development Tools.
+ Tools" added to the list. Select the checkbox next to Developer Tools,
+ which will automatically select the nested tools Android DDMS and Android
+ Development Tools.
Click <strong>Next</strong>. </li>
- <li>In the resulting Install Details dialog, the Android DDMS and Android
- Development Tools features are listed. Click <strong>Next</strong> to
- read and accept the license agreement and install any dependencies,
+ <li>In the resulting Install Details dialog, the Android DDMS and Android
+ Development Tools features are listed. Click <strong>Next</strong> to
+ read and accept the license agreement and install any dependencies,
then click <strong>Finish</strong>. </li>
<li>Restart Eclipse. </li>
-
+
</ol>
</td>
</tr>
@@ -466,15 +466,15 @@
<li>Select <strong>Window</strong> > <strong>Preferences...</strong> to open the Preferences
panel (Mac OS X: <strong>Eclipse</strong> > <strong>Preferences</strong>).</li>
<li>Select <strong>Android</strong> from the left panel. </li>
- <li>For the <em>SDK Location</em> in the main panel, click <strong>Browse...</strong> and
+ <li>For the <em>SDK Location</em> in the main panel, click <strong>Browse...</strong> and
locate your downloaded SDK directory. </li>
<li>Click <strong>Apply</strong>, then <strong>OK</strong>.</li>
</ol>
<p>Done! If you haven't encountered any problems, then the installation is
-complete. Now read <a href="installing.html#components">Adding Platforms and
-Other Components</a> for instructions on how to complete the setup of your
-SDK environment. </p>
+complete. If you're installing the Android SDK for the first time, return to <a
+href="{@docRoot}sdk/installing.html#InstallingADT">Installing the SDK</a> to complete your setup.
+</p>
<h3 id="troubleshooting">Troubleshooting ADT Installation</h3>
@@ -486,7 +486,7 @@
<li>If Eclipse can not find the remote update site containing the ADT plugin,
try changing the remote site URL to use http, rather than https. That is, set
the Location for the remote site to:
-<pre>http://dl-ssl.google.com/android/eclipse/</pre></li>
+<pre>http://dl-ssl.google.com/android/eclipse/</pre></li>
<li>If you are behind a firewall (such as a corporate firewall), make sure that
you have properly configured your proxy settings in Eclipse. In Eclipse 3.3/3.4,
you can configure proxy information from the main Eclipse menu in
@@ -521,14 +521,14 @@
</li>
</li>
- <li>Follow steps 1 and 2 in the <a href="#installing">default install
+ <li>Follow steps 1 and 2 in the <a href="#installing">default install
instructions</a> (above).</li>
<li>In the Add Site dialog, click <strong>Archive</strong>.</li>
<li>Browse and select the downloaded zip file.</li>
<li>In Eclipse 3.5 only, enter a name for the local update site (e.g.,
"Android Plugin") in the "Name" field.</li>
<li>Click <strong>OK</strong>.
- <li>Follow the remaining procedures as listed for
+ <li>Follow the remaining procedures as listed for
<a href="#installing">default installation</a> above,
starting from step 4.</li>
</ol>
@@ -538,16 +538,16 @@
<h4>Other install errors</h4>
-<p>Note that there are features of ADT that require some optional
-Eclipse components (for example, WST). If you encounter an error when
-installing ADT, your Eclipse installion might not include these components.
-For information about how to quickly add the necessary components to your
-Eclipse installation, see the troubleshooting topic
-<a href="{@docRoot}resources/faq/troubleshooting.html#installeclipsecomponents">ADT
+<p>Note that there are features of ADT that require some optional
+Eclipse components (for example, WST). If you encounter an error when
+installing ADT, your Eclipse installion might not include these components.
+For information about how to quickly add the necessary components to your
+Eclipse installation, see the troubleshooting topic
+<a href="{@docRoot}resources/faq/troubleshooting.html#installeclipsecomponents">ADT
Installation Error: "requires plug-in org.eclipse.wst.sse.ui"</a>.</p>
<h4>For Linux users</h4>
-<p>If you encounter this error when installing the ADT Plugin for Eclipse:
+<p>If you encounter this error when installing the ADT Plugin for Eclipse:
<pre>
An error occurred during provisioning.
Cannot connect to keystore.
@@ -572,12 +572,12 @@
<p>To learn about new features of each ADT revision and also any dependencies on
the SDK Tools, see the listings in the <a href="#notes">Revisions</a>
-section. To determine the version currently installed, open the
+section. To determine the version currently installed, open the
Eclipse Installed Software window using <strong>Help</strong>
-> <strong>Software Updates</strong> and refer to the version listed for
+> <strong>Software Updates</strong> and refer to the version listed for
"Android Development Tools".</p>
-<p>Follow the steps below to check whether an update is available and, if so,
+<p>Follow the steps below to check whether an update is available and, if so,
to install it. </p>
<table style="font-size:100%">
@@ -588,13 +588,13 @@
<ol>
<li>Select <strong>Help</strong> > <strong>Software Updates</strong>.</li>
<li>Select the <strong>Available Software</strong> tab.</li>
- <li>Select the checkboxes next to Android DDMS and Android Developer Tools,
+ <li>Select the checkboxes next to Android DDMS and Android Developer Tools,
then click <strong>Update</strong>.</li>
- <li>In the resulting Available Updates dialog, ensure that both Android DDMS
- and Android Development Tools are selected, then click
+ <li>In the resulting Available Updates dialog, ensure that both Android DDMS
+ and Android Development Tools are selected, then click
<strong>Next</strong>.</li>
<li>Read and accept the license agreement and then click <strong>Finish</strong>.
- This will download and install the latest version of Android DDMS and
+ This will download and install the latest version of Android DDMS and
Android Development Tools.</li>
<li>Restart Eclipse.</li>
</ol>
@@ -603,17 +603,17 @@
<!-- 3.5 steps -->
<ol>
<li>Select <strong>Help</strong> > <strong>Check for Updates</strong>. </li>
- <li>In the resulting Available Updates dialog, locate the Android DDMS and
+ <li>In the resulting Available Updates dialog, locate the Android DDMS and
Android Development Tools features in the list and ensure that the checkboxes
- next to them are selected. Click <strong>Next</strong>.
- <p>If the Available Updates dialog does not list Android DDMS and Android
- Development tools, make sure that you have set up a remote update site
- for them, as described in
- <a href="#installing">Installing the ADT Plugin</a>.
+ next to them are selected. Click <strong>Next</strong>.
+ <p>If the Available Updates dialog does not list Android DDMS and Android
+ Development tools, make sure that you have set up a remote update site
+ for them, as described in
+ <a href="#installing">Installing the ADT Plugin</a>.
</p></li>
<li>In the Update Details dialog, click <strong>Next</strong>.</li>
<li>Read and accept the license agreement and then click <strong>Finish</strong>.
- This will download and install the latest version of Android DDMS and
+ This will download and install the latest version of Android DDMS and
Android Development Tools.</li>
<li>Restart Eclipse.</li>
</ol>
@@ -622,17 +622,17 @@
</table>
-<p>If you encounter problems during the update of ADT, you
+<p>If you encounter problems during the update of ADT, you
can try removing the existing ADT plugin and then performing a fresh
installation. To remove the plugin, follow the instructions in <a
-href="#uninstalling">Uninstalling the ADT Plugin</a>, below. To reinstall
+href="#uninstalling">Uninstalling the ADT Plugin</a>, below. To reinstall
the plugin, follow the instructions in <a
href="#installing">Installing the ADT Plugin</a>, above.</p>
<h2 id="uninstalling">Uninstalling the ADT plugin</h2>
-<p><p>If you encounter problems when installing or updating ADT, you
+<p>If you encounter problems when installing or updating ADT, you
can try removing the existing ADT plugin and then performing a fresh
installation. To remove ADT, follow these steps: </p>
@@ -642,12 +642,12 @@
<td width="50%">
<!-- 3.4 steps -->
<ol>
- <li>Select <strong>Help</strong> > <strong>Software Updates</strong> >
+ <li>Select <strong>Help</strong> > <strong>Software Updates</strong> >
<strong>Manage Configuration</strong>. </li>
<li>Expand the list in the left panel to reveal the installed tools.</li>
- <li>Right-click "Android Editors" and click <strong>Uninstall</strong>. Click <strong>OK</strong>
+ <li>Right-click "Android Editors" and click <strong>Uninstall</strong>. Click <strong>OK</strong>
to confirm.</li>
- <li>Restart Eclipse.
+ <li>Restart Eclipse.
<p>(Do not uninstall "Android Development Tools".)</p></li>
</ol>
</td>
diff --git a/docs/html/sdk/index.jd b/docs/html/sdk/index.jd
index 2e59801..2812ae8 100644
--- a/docs/html/sdk/index.jd
+++ b/docs/html/sdk/index.jd
@@ -57,7 +57,7 @@
installer, this is launched for you when the Wizard is complete). Add some Android platforms
(such as Android 1.6 and Android 2.3) and other components (such as documentation) to your SDK. If
you aren't sure what to add, see <a
-href="installing.html#which">Which components do I need?</a></p>
+href="installing.html#which">Recommended Components</a></p>
<p><strong>Done!</strong></p>
diff --git a/docs/html/sdk/installing.jd b/docs/html/sdk/installing.jd
index 8484bea..5b5c4f4 100644
--- a/docs/html/sdk/installing.jd
+++ b/docs/html/sdk/installing.jd
@@ -3,19 +3,62 @@
@jd:body
+
+<script type="text/javascript">
+function toggleDiv(link) {
+ var toggleable = $(link).parent();
+ if (toggleable.hasClass("closed")) {
+ //$(".toggleme", toggleable).slideDown("fast");
+ toggleable.removeClass("closed");
+ toggleable.addClass("open");
+ $(".toggle-img", toggleable).attr("title", "hide").attr("src", (toRoot +
+"assets/images/triangle-opened.png"));
+ } else {
+ //$(".toggleme", toggleable).slideUp("fast");
+ toggleable.removeClass("open");
+ toggleable.addClass("closed");
+ $(".toggle-img", toggleable).attr("title", "show").attr("src", (toRoot +
+"assets/images/triangle-closed.png"));
+ }
+ return false;
+}
+</script>
+<style>
+.toggleable {
+ padding: .25em 1em 0em 1em;
+ margin-bottom: 0;
+}
+.toggleme {
+ padding: 1em 1em 0 2em;
+ line-height:1em;
+}
+.toggleable a {
+ text-decoration:none;
+}
+.toggleme a {
+ text-decoration:underline;
+}
+.toggleable.closed .toggleme {
+ display:none;
+}
+#jd-content .toggle-img {
+ margin:0;
+}
+</style>
+
<div id="qv-wrapper">
<div id="qv">
<h2>In this document</h2>
<ol>
- <li><a href="#Preparing">Preparing Your Development Computer</a></li>
- <li><a href="#Installing">Downloading the SDK Starter Package</a></li>
- <li><a href="#InstallingADT">Installing the ADT Plugin for Eclipse</a></li>
- <li><a href="#components">Adding Platforms and Other Components</a>
- <ol>
- <li><a href="#which">Which components do I need?</a></li>
- </ol></li>
- <li><a href="#sdkContents">Exploring the SDK</a></li>
+ <li><a href="#Preparing">1. Preparing Your Development Computer</a></li>
+ <li><a href="#Installing">2. Downloading the SDK Starter Package</a></li>
+ <li><a href="#InstallingADT">3. Installing the ADT Plugin for Eclipse</a></li>
+ <li><a href="#components">4. Adding Platforms and Other Components</a>
+ <ol>
+ <li><a href="#which">Recommended Components</a></li>
+ </ol></li>
+ <li><a href="#sdkContents">5. Exploring the SDK</a></li>
<li><a href="#NextSteps">Next Steps</a></li>
<li><a href="#troubleshooting">Troubleshooting</a></li>
</ol>
@@ -38,66 +81,62 @@
<h4>Updating?</h4>
-<p>If you are currently using the Android 1.6 SDK or later and want to update
-to the latest tools or platforms, you do not need to install a new SDK. Instead,
-you can simply update the individual components in your SDK using the
-Android SDK and AVD Manager tool. For information about how to do that, see <a
-href="{@docRoot}sdk/adding-components.html#UpdatingComponents">Updating SDK
-Components</a></p>
-
-<p>If you are using Android 1.5 SDK or earlier, you should install a new SDK as
-described in this document and move your application projects to the new
-SDK environment. </p>
+<p>If you already have an Android SDK, use the <em>Android SDK and AVD Manager</em> tool to install
+updated tools and new Android platforms into your existing environment. For information about how to
+do that, see <a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a></p>
<h2 id="Preparing">Step 1. Preparing Your Development Computer</h2>
<p>Before getting started with the Android SDK, take a moment to confirm that
your development computer meets the <a href="requirements.html">System
-Requirements</a>. In particular, you may need to install the <a
-href="http://java.sun.com/javase/downloads/index.jsp">JDK</a> before
-continuing, if it's not already installed on your computer. </p>
+Requirements</a>. In particular, you might need to install the <a
+href="http://java.sun.com/javase/downloads/index.jsp">JDK</a>, if you don't have it already. </p>
<p>If you will be developing in Eclipse with the Android Development
-Tools (ADT) Plugin — the recommended path if you are new to
-Android — make sure that you have a suitable version of Eclipse
+Tools (ADT) Plugin—the recommended path if you are new to
+Android—make sure that you have a suitable version of Eclipse
installed on your computer (3.4 or newer is recommended). If you need
to install Eclipse, you can download it from this location: </p>
<p style="margin-left:2em;"><a href=
"http://www.eclipse.org/downloads/">http://www.eclipse.org/downloads/</a></p>
-<p>A Java or RCP version of Eclipse is recommended. For Eclipse 3.5, the
-"Eclipse Classic" version is recommended.</p>
+<p>For Eclipse 3.5 or newer, the "Eclipse Classic" version is recommended. Otherwise, a Java or
+RCP version of Eclipse is recommended.</p>
<h2 id="Installing">Step 2. Downloading the SDK Starter Package</h2>
-<p>The first step in setting up your environment for developing Android applications
-is downloading the Android SDK starter package. The starter package is not a full
-development environment — it includes only the core SDK Tools, which you can
-use to download the rest of the SDK components (such as the platform system images). </p>
+<p>The SDK starter package is not a full
+development environment—it includes only the core SDK Tools, which you can
+use to download the rest of the SDK components (such as the latest Android platform).</p>
<p>You can get the latest version of the SDK starter package from the <a
-href="{@docRoot}sdk/index.html">SDK download page</a>. Make sure to download the
-package that is appropriate for your development computer.</p>
+href="{@docRoot}sdk/index.html">SDK download page</a>.</p>
-<p class="note"><strong>Note:</strong> If you're using Windows, we recommend that you download
-the SDK installer (the {@code .exe} file from the download table). It will guide you through the
-installation process and check your computer for the required software.</p>
-
-<p>If you downloaded a {@code .zip} of {@code .tgz} (instead of using the SDK installer), unpack the
-Android SDK archive to a safe location on your machine. By default, the SDK files are unpacked into
-a directory named <code>android-sdk-<machine-platform></code>.</p>
+<p>If you downloaded a {@code .zip} or {@code .tgz} package (instead of the SDK installer), unpack
+it to a safe location on your machine. By default, the SDK files are unpacked
+into a directory named <code>android-sdk-<machine-platform></code>.</p>
<p>Make a note of the name and
-location of the unpacked SDK directory on your system — you will need to
+location of the unpacked SDK directory on your system—you will need to
refer to the SDK directory later, when setting up the ADT plugin and when using
the SDK tools from command line.</p>
-<p>Optionally, you might want to add the location of the SDK's primary
-<code>tools</code> directory and the additional {@code platform-tools/} directory to your system
-<code>PATH</code>. Both tool directories are located at the root of the SDK folder. Adding
+<p>Optionally, you might want to add the location of the SDK's
+<code>tools/</code> directory and {@code platform-tools/} directory to your system
+<code>PATH</code>. Both tool directories are located at the root of the SDK folder.
+
+
+<div class="toggleable closed">
+ <a href="#" onclick="return toggleDiv(this)">
+ <img src="{@docRoot}assets/images/triangle-closed.png" class="toggle-img" height="9px"
+width="9px" />
+ How to update your PATH</a>
+ <div class="toggleme">
+
+<p>Adding
<code>tools/</code> and {@code platform-tools/} to your path lets you run Android Debug Bridge (adb)
and the other command line <a
href="{@docRoot}guide/developing/tools/index.html">tools</a> without needing to
@@ -107,9 +146,10 @@
<li>On Linux, edit your <code>~/.bash_profile</code> or <code>~/.bashrc</code> file. Look
for a line that sets the PATH environment variable and add the
full path to the <code>tools/</code> and {@code platform-tools/} directories to it. If you don't
- see a line setting the path, you can add one:</li>
+ see a line setting the path, you can add one:
- <ul><code>export PATH=${PATH}:<your_sdk_dir>/tools:<your_sdk_dir>/platform-tools</code></ul>
+ <pre>export PATH=${PATH}:<your_sdk_dir>/tools:<your_sdk_dir>/platform-tools</pre>
+ </li>
<li>On a Mac OS X, look in your home directory for <code>.bash_profile</code> and
proceed as for Linux. You can create the <code>.bash_profile</code> if
@@ -121,12 +161,9 @@
<code>tools/</code> and {@code platform-tools/} directories to the path. </li>
</ul>
-<p>If you will be using the Eclipse IDE as your development environment, the
-next section describes how to install the Android Development Tools (ADT) plugin
-and set up Eclipse. If you choose not to use Eclipse, you can develop Android
-applications in an IDE of your choice and then compile, debug and deploy using
-the tools included in the SDK (skip to <a href="#components">Adding Platforms
-and Other Components</a>).</p>
+</div><!-- end toggleme -->
+</div><!-- end toggleable -->
+
<h2 id="InstallingADT">Step 3. Installing the ADT Plugin for Eclipse</h2>
@@ -135,64 +172,75 @@
Development Tools (ADT), that is designed to give you a powerful, integrated
environment in which to build Android applications. It extends the capabilites
of Eclipse to let you quickly set up new Android projects, create an application
-UI, add components based on the Android Framework API, debug your applications
+UI, debug your applications
using the Android SDK tools, and even export signed (or unsigned) APKs in order
to distribute your application. In general, developing in Eclipse with ADT is a
highly recommended approach and is the fastest way to get started with Android.
</p>
<p>If you'd like to use ADT for developing Android applications, install it now.
-Read <a href="{@docRoot}sdk/eclipse-adt.html">ADT Plugin for Eclipse</a> for
-step-by-step installation instructions, then return here to continue with the
-last step in setting up your SDK: adding platforms and other
-components.</p>
+Read <a href="{@docRoot}sdk/eclipse-adt.html#installing">Installing the ADT Plugin</a> for
+step-by-step installation instructions, then return here to continue the
+last step in setting up your Android SDK.</p>
-<p>If you prefer to work in an IDE other than Eclipse, you do not need to
+<p>If you prefer to work in a different IDE, you do not need to
install Eclipse or ADT, instead, you can directly use the SDK tools to build and
-debug your application.</p>
+debug your application. The developer guide has more information about <a
+href="{@docRoot}guide/developing/other-ide.html">Developing in Other IDEs</a>.</p>
+
<h2 id="components">Step 4. Adding Android Platforms and Other Components</h2>
-<div class="sidebox-wrapper" style="margin-right:2.5em;">
-<div class="sidebox"> <h2>Using the Android SDK and AVD Manager</h2>
+<p>The last step in setting up your SDK is using the <em>Android SDK and AVD Manager</em> (a
+tool included in the SDK starter package) to download
+essential SDK components into your development environment.</p>
-<p>The <em>Android SDK and AVD Manager</em> is a tool that you will use often,
-to add components to your SDK environment and manage Android Virtual Devices.
-</p>
+<p>The SDK uses a modular structure that separates the major parts of the SDK—Android platform
+versions, add-ons, tools, samples, and documentation—into a set of separately installable
+components. The SDK starter package, which you've already downloaded, includes only a single
+component: the latest version of the SDK Tools. To develop an Android
+application, you also need to download at least one Android platform and the SDK Platform-tools
+(tools that the latest platform depend upon). However, downloading
+additional components is highly recommended.</p>
-<p style="margin-top:.5em;">The tool is pre-installed in your SDK. See <a
-href="adding-components.html">Adding SDK Components</a> for details on how to
-launch and use the tool.</p>
-</div>
-</div>
+<p>You can launch the Android SDK and AVD Manager in one of the following ways:</p>
+<ul>
+ <li>From within Eclipse, select <strong>Window > Android SDK and AVD Manager</strong>.</li>
+ <li>On Windows, double-click the <code>SDK Manager.ext</code> file at the root of the Android
+SDK directory.</li>
+ <li>On Mac or Linux, open a terminal and navigate to the <code>tools/</code> directory in the
+Android SDK, then execute: <pre>android update sdk</pre> <p>This will automatically select
+the required and recommended components for you to install.</p></li>
+</ul>
-<p>The last step in setting up your SDK is using a tool included the SDK starter
-package — the <em>Android SDK and AVD Manager</em> — to download
-essential components into your development environment. Read the information
-below to understand what components you'll need, then see <a
-href="adding-components.html">Adding SDK Components</a> for step-by-step
-instructions on how to launch the Android SDK and AVD Manager and download the
-components into your environment.</p>
+<p>To download components, use the graphical UI of the Android SDK and AVD
+Manager, shown in Figure 1, to browse the SDK repository and select new or updated
+components. The Android SDK and AVD Manager will install the selected components in
+your SDK environment. For information about which components you should download, see the following
+section about <a href="#which">Recommended Components</a></p>
-<p>The SDK uses a modular structure that separates the major parts of the SDK
-— Android platform versions, add-ons, tools, samples, and the API
-documentation — into a set of separately installable components. The SDK
-starter package, which you've already downloaded, includes only a single
-component: the latest version of the SDK Tools. To develop any Android
-application, you also need to download at least one Android platform into your
-environment, although downloading additional components is highly recommended.
-See <a href="#which">Which components do I need?</a> for information about
-which components are required and which are optional.</p>
+<img src="/images/sdk_manager_packages.png" />
+<p class="img-caption"><strong>Figure 1.</strong> The Android SDK and AVD Manager's
+<strong>Available Packages</strong> panel, which shows the SDK components that are
+available for you to download into your environment.</p>
<p>The SDK repository offers these types of components:</p>
<ul>
<li><strong>SDK Tools</strong> (pre-installed in the Android SDK starter
-package) — Contains the full set of SDK tools for developing, debugging,
-and testing your application code and UI. You can read about the tools in the <a
-href="{@docRoot}guide/developing/tools/index.html">Dev Guide</a> and access them
-in the <code><sdk>/tools/</code> directory. </li>
+package) — Contains tools for debugging
+and testing your application and other utility tools. You can access these
+in the <code><sdk>/tools/</code> directory of your SDK and read more about them in the <a
+href="{@docRoot}guide/developing/tools/index.html">Tools</a> section of the developer guide. </li>
+
+<li><strong>SDK Platform-tools</strong> — Contains tools that are required to develop and
+debug your application, but which are developed alongside the Android platform in order to support
+the latest features. These tools are typically updated only when a new platform becomes
+available. You can access these
+in the <code><sdk>/platform-tools/</code> directory. Read more about them in
+the <a href="{@docRoot}guide/developing/tools/index.html">Tools</a> section of the developer guide.
+</li>
<li><strong>Android platforms</strong> — An SDK platform is
available for every production Android platform deployable to Android-powered
@@ -227,28 +275,13 @@
multiversion documentation for the Android framework API. </li>
</ul>
-<p>To download components, use the graphical UI of the Android SDK and AVD
-Manager, shown in Figure 1, to browse the SDK repository, select new or updated
-components for download, and then install the selected components in your SDK
-environment. </p>
-<div style="TEXT-ALIGN:left;width:600px;">
-<img src="/images/sdk_manager_packages.png"
-style="padding-bottom:0;margin-bottom:0;" />
-<p class="caption" style="margin:0 0 1.5em 1em;padding:0 0 0
-1em;"><strong>Figure 1.</strong> The Android SDK and AVD Manager's
-<strong>Available Packages</strong>
-panel, which shows the SDK components that are
-available for you to download into your environment. </p>
-</div>
-
-
-<h3 id="which">Which components do I need?</h3>
+<h3 id="which">Recommended Components</h3>
<p>The SDK repository contains a range of components that you can download.
Use the table below to determine which components you need, based on whether you
-want to set up a basic (but functionnal) development environment or a
-recommended or full development environment: </p>
+want to set up a basic, recommended, or full development environment:
+</p>
<table style="width:95%">
@@ -259,12 +292,21 @@
</tr>
<tr>
-<td rowspan="2" style="font-size:.9em;background-color:#FFE;">Basic</td>
-<td style="font-size:.9em;background-color:#FFE;color:gray">SDK Tools</td>
-<td style="font-size:.9em;background-color:#FFE;color:gray">If you've installed
-the SDK starter package, then you already have this component preinstalled. The
-SDK Tools and the SDK Platform-tools components are required — you can't develop or build an
-application without these. Make sure you keep these up to date.</td>
+<td rowspan="3" style="font-size:.9em;background-color:#FFE;">Basic</td>
+<td style="font-size:.9em;background-color:#FFE;">SDK Tools</td>
+<td style="font-size:.9em;background-color:#FFE;">If you've just installed
+the SDK starter package, then you already have the latest version of this component. The
+SDK Tools component is required to develop an Android application. Make sure you keep this up to
+date.</td>
+</tr>
+
+<tr>
+<td style="font-size:.9em;background-color:#FFE;">SDK Platform-tools</td>
+<td style="font-size:.9em;background-color:#FFE;">This includes more tools that are required
+for application development. These tools are platform-dependent and typically update only when
+a new SDK platform is made available, in order to support new features in the platform. These
+tools are always backward compatible with older platforms, but you must be sure that you have
+the latest version of these tools when you install a new SDK platform.</td>
</tr>
<tr>
@@ -275,14 +317,15 @@
Device (AVD) to run it on (in the emulator). To start with, just download the
latest version of the platform. Later, if you plan to publish your application,
you will want to download other platforms as well, so that you can test your
-application on the full range of Android platform versions that your customers
-are using.</td>
+application on the full range of Android platform versions that your application supports.</td>
</tr>
<tr>
-<td colspan="3" style="border:none;text-align:center;font-size:1.5em;font-weight:bold;">+</td>
+<td colspan="2"
+style="border:none;text-align:center;font-size:1.5em;font-weight:bold;">+</td><td
+style="border:none"></td>
</tr>
<tr>
-<td rowspan="3">Recommended</td>
+<td rowspan="3">Recommended<br/>(plus Basic)</td>
<td>Documentation</td>
<td>The Documentation component is useful because it lets you work offline and
also look up API reference information from inside Eclipse.</td>
@@ -304,10 +347,12 @@
special driver is needed.</td>
</tr>
<tr>
-<td colspan="3" style="border:none;text-align:center;font-size:1.5em;font-weight:bold;">+</td>
+<td colspan="2"
+style="border:none;text-align:center;font-size:1.5em;font-weight:bold;">+</td><td
+style="border:none"></td>
</tr>
<tr>
-<td rowspan="3">Full</td>
+<td rowspan="3">Full<br/>(plus Recommended)</td>
<td>Google APIs</td>
<td>The Google APIs add-on gives your application access to the Maps external
library, which makes it easy to display and manipulate Maps data in your
@@ -326,13 +371,12 @@
</table>
-<p>For step-by-step instructions on how to use the Android SDK and AVD Manager
-to add components, see the <a href="{@docRoot}sdk/adding-components.html">Adding
-SDK Components</a> document. </p>
+<p>Once you've installed at least the basic configuration of SDK components, you're ready to start
+developing Android apps. The next section describes the contents of the Android SDK to familiarize
+you with the components you've just installed.</p>
-<p>For revision notes and other detailed information about individual SDK
-components, see the documents listed under "Downloadable SDK Components" in
-the navigation at left.</p>
+<p>For more information about using the Android SDK and AVD Manager, see the <a
+href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a> document. </p>
<h2 id="sdkContents">Step 5. Exploring the SDK</h2>
@@ -466,7 +510,7 @@
</li>
</ul>
-<p class="caution">Following the Hello World tutorial is an essential
+<p class="note">Following the Hello World tutorial is an essential
first step in getting started with Android development. </p>
<p><strong>Learn about Android</strong></p>
@@ -506,7 +550,7 @@
and architectural concepts in a moderately complex application.
</li>
</ul>
-<p class="caution">Following the Notepad tutorial is an excellent
+<p class="note">Following the Notepad tutorial is an excellent
second step in getting started with Android development. </p>
<p><strong>Explore some code</strong></p>
diff --git a/graphics/java/android/graphics/drawable/Drawable.java b/graphics/java/android/graphics/drawable/Drawable.java
index 7b2d9d7..baa9d62 100644
--- a/graphics/java/android/graphics/drawable/Drawable.java
+++ b/graphics/java/android/graphics/drawable/Drawable.java
@@ -423,6 +423,13 @@
}
/**
+ * If this Drawable does transition animations between states, ask that
+ * it immediately jump to the current state and skip any active animations.
+ */
+ public void jumpToCurrentState() {
+ }
+
+ /**
* @return The current drawable that will be used by this drawable. For simple drawables, this
* is just the drawable itself. For drawables that change state like
* {@link StateListDrawable} and {@link LevelListDrawable} this will be the child drawable
diff --git a/graphics/java/android/graphics/drawable/DrawableContainer.java b/graphics/java/android/graphics/drawable/DrawableContainer.java
index 124d907..e55a746 100644
--- a/graphics/java/android/graphics/drawable/DrawableContainer.java
+++ b/graphics/java/android/graphics/drawable/DrawableContainer.java
@@ -21,6 +21,7 @@
import android.graphics.ColorFilter;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.os.SystemClock;
/**
* A helper class that contains several {@link Drawable}s and selects which one to use.
@@ -28,6 +29,8 @@
* You can subclass it to create your own DrawableContainers or directly use one its child classes.
*/
public class DrawableContainer extends Drawable implements Drawable.Callback {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "DrawableContainer";
/**
* To be proper, we should have a getter for dither (and alpha, etc.)
@@ -48,6 +51,12 @@
private int mCurIndex = -1;
private boolean mMutated;
+ // Animations.
+ private Runnable mAnimationRunnable;
+ private long mEnterAnimationEnd;
+ private long mExitAnimationEnd;
+ private Drawable mLastDrawable;
+
// overrides from Drawable
@Override
@@ -55,6 +64,9 @@
if (mCurrDrawable != null) {
mCurrDrawable.draw(canvas);
}
+ if (mLastDrawable != null) {
+ mLastDrawable.draw(canvas);
+ }
}
@Override
@@ -83,7 +95,11 @@
if (mAlpha != alpha) {
mAlpha = alpha;
if (mCurrDrawable != null) {
- mCurrDrawable.setAlpha(alpha);
+ if (mEnterAnimationEnd == 0) {
+ mCurrDrawable.setAlpha(alpha);
+ } else {
+ animate(false);
+ }
}
}
}
@@ -108,8 +124,29 @@
}
}
+ /**
+ * Change the global fade duration when a new drawable is entering
+ * the scene.
+ * @param ms The amount of time to fade in milliseconds.
+ */
+ public void setEnterFadeDuration(int ms) {
+ mDrawableContainerState.mEnterFadeDuration = ms;
+ }
+
+ /**
+ * Change the global fade duration when a new drawable is leaving
+ * the scene.
+ * @param ms The amount of time to fade in milliseconds.
+ */
+ public void setExitFadeDuration(int ms) {
+ mDrawableContainerState.mExitFadeDuration = ms;
+ }
+
@Override
protected void onBoundsChange(Rect bounds) {
+ if (mLastDrawable != null) {
+ mLastDrawable.setBounds(bounds);
+ }
if (mCurrDrawable != null) {
mCurrDrawable.setBounds(bounds);
}
@@ -121,7 +158,34 @@
}
@Override
+ public void jumpToCurrentState() {
+ boolean changed = false;
+ if (mLastDrawable != null) {
+ mLastDrawable.jumpToCurrentState();
+ mLastDrawable = null;
+ changed = true;
+ }
+ if (mCurrDrawable != null) {
+ mCurrDrawable.jumpToCurrentState();
+ }
+ if (mExitAnimationEnd != 0) {
+ mExitAnimationEnd = 0;
+ changed = true;
+ }
+ if (mEnterAnimationEnd != 0) {
+ mEnterAnimationEnd = 0;
+ changed = true;
+ }
+ if (changed) {
+ invalidateSelf();
+ }
+ }
+
+ @Override
protected boolean onStateChange(int[] state) {
+ if (mLastDrawable != null) {
+ return mLastDrawable.setState(state);
+ }
if (mCurrDrawable != null) {
return mCurrDrawable.setState(state);
}
@@ -130,6 +194,9 @@
@Override
protected boolean onLevelChange(int level) {
+ if (mLastDrawable != null) {
+ return mLastDrawable.setLevel(level);
+ }
if (mCurrDrawable != null) {
return mCurrDrawable.setLevel(level);
}
@@ -168,22 +235,19 @@
return mCurrDrawable != null ? mCurrDrawable.getMinimumHeight() : 0;
}
- public void invalidateDrawable(Drawable who)
- {
+ public void invalidateDrawable(Drawable who) {
if (who == mCurrDrawable && mCallback != null) {
mCallback.invalidateDrawable(this);
}
}
- public void scheduleDrawable(Drawable who, Runnable what, long when)
- {
+ public void scheduleDrawable(Drawable who, Runnable what, long when) {
if (who == mCurrDrawable && mCallback != null) {
mCallback.scheduleDrawable(this, what, when);
}
}
- public void unscheduleDrawable(Drawable who, Runnable what)
- {
+ public void unscheduleDrawable(Drawable who, Runnable what) {
if (who == mCurrDrawable && mCallback != null) {
mCallback.unscheduleDrawable(this, what);
}
@@ -192,6 +256,9 @@
@Override
public boolean setVisible(boolean visible, boolean restart) {
boolean changed = super.setVisible(visible, restart);
+ if (mLastDrawable != null) {
+ mLastDrawable.setVisible(visible, restart);
+ }
if (mCurrDrawable != null) {
mCurrDrawable.setVisible(visible, restart);
}
@@ -208,16 +275,39 @@
if (idx == mCurIndex) {
return false;
}
+
+ final long now = SystemClock.uptimeMillis();
+
+ if (DEBUG) android.util.Log.i(TAG, toString() + " from " + mCurIndex + " to " + idx
+ + ": exit=" + mDrawableContainerState.mExitFadeDuration
+ + " enter=" + mDrawableContainerState.mEnterFadeDuration);
+
+ if (mDrawableContainerState.mExitFadeDuration > 0) {
+ if (mLastDrawable != null) {
+ mLastDrawable.setVisible(false, false);
+ }
+ if (mCurrDrawable != null) {
+ mLastDrawable = mCurrDrawable;
+ mExitAnimationEnd = now + mDrawableContainerState.mExitFadeDuration;
+ } else {
+ mLastDrawable = null;
+ mExitAnimationEnd = 0;
+ }
+ } else if (mCurrDrawable != null) {
+ mCurrDrawable.setVisible(false, false);
+ }
+
if (idx >= 0 && idx < mDrawableContainerState.mNumChildren) {
Drawable d = mDrawableContainerState.mDrawables[idx];
- if (mCurrDrawable != null) {
- mCurrDrawable.setVisible(false, false);
- }
mCurrDrawable = d;
mCurIndex = idx;
if (d != null) {
+ if (mDrawableContainerState.mEnterFadeDuration > 0) {
+ mEnterAnimationEnd = now + mDrawableContainerState.mEnterFadeDuration;
+ } else {
+ d.setAlpha(mAlpha);
+ }
d.setVisible(isVisible(), true);
- d.setAlpha(mAlpha);
d.setDither(mDrawableContainerState.mDither);
d.setColorFilter(mColorFilter);
d.setState(getState());
@@ -225,16 +315,72 @@
d.setBounds(getBounds());
}
} else {
- if (mCurrDrawable != null) {
- mCurrDrawable.setVisible(false, false);
- }
mCurrDrawable = null;
mCurIndex = -1;
}
+
+ if (mEnterAnimationEnd != 0 || mExitAnimationEnd != 0) {
+ if (mAnimationRunnable == null) {
+ mAnimationRunnable = new Runnable() {
+ @Override public void run() {
+ animate(true);
+ invalidateSelf();
+ }
+ };
+ } else {
+ unscheduleSelf(mAnimationRunnable);
+ }
+ // Compute first frame and schedule next animation.
+ animate(true);
+ }
+
invalidateSelf();
+
return true;
}
+ void animate(boolean schedule) {
+ final long now = SystemClock.uptimeMillis();
+ boolean animating = false;
+ if (mCurrDrawable != null) {
+ if (mEnterAnimationEnd != 0) {
+ if (mEnterAnimationEnd <= now) {
+ mCurrDrawable.setAlpha(mAlpha);
+ mEnterAnimationEnd = 0;
+ } else {
+ int animAlpha = (int)((mEnterAnimationEnd-now)*255)
+ / mDrawableContainerState.mEnterFadeDuration;
+ if (DEBUG) android.util.Log.i(TAG, toString() + " cur alpha " + animAlpha);
+ mCurrDrawable.setAlpha(((255-animAlpha)*mAlpha)/255);
+ animating = true;
+ }
+ }
+ } else {
+ mEnterAnimationEnd = 0;
+ }
+ if (mLastDrawable != null) {
+ if (mExitAnimationEnd != 0) {
+ if (mExitAnimationEnd <= now) {
+ mLastDrawable.setVisible(false, false);
+ mLastDrawable = null;
+ mExitAnimationEnd = 0;
+ } else {
+ int animAlpha = (int)((mExitAnimationEnd-now)*255)
+ / mDrawableContainerState.mExitFadeDuration;
+ if (DEBUG) android.util.Log.i(TAG, toString() + " last alpha " + animAlpha);
+ mLastDrawable.setAlpha((animAlpha*mAlpha)/255);
+ animating = true;
+ }
+ }
+ } else {
+ mExitAnimationEnd = 0;
+ }
+
+ if (schedule && animating) {
+ scheduleSelf(mAnimationRunnable, now + 1000/60);
+ }
+ }
+
@Override
public Drawable getCurrent() {
return mCurrDrawable;
@@ -300,6 +446,9 @@
boolean mDither = DEFAULT_DITHER;
+ int mEnterFadeDuration;
+ int mExitFadeDuration;
+
DrawableContainerState(DrawableContainerState orig, DrawableContainer owner,
Resources res) {
mOwner = owner;
@@ -340,6 +489,9 @@
mDither = orig.mDither;
+ mEnterFadeDuration = orig.mEnterFadeDuration;
+ mExitFadeDuration = orig.mExitFadeDuration;
+
} else {
mDrawables = new Drawable[10];
mNumChildren = 0;
@@ -476,6 +628,22 @@
}
}
+ public final void setEnterFadeDuration(int duration) {
+ mEnterFadeDuration = duration;
+ }
+
+ public final int getEnterFadeDuration() {
+ return mEnterFadeDuration;
+ }
+
+ public final void setExitFadeDuration(int duration) {
+ mExitFadeDuration = duration;
+ }
+
+ public final int getExitFadeDuration() {
+ return mExitFadeDuration;
+ }
+
public final int getOpacity() {
if (mHaveOpacity) {
return mOpacity;
diff --git a/graphics/java/android/graphics/drawable/GradientDrawable.java b/graphics/java/android/graphics/drawable/GradientDrawable.java
index 88f6d43..c558632 100644
--- a/graphics/java/android/graphics/drawable/GradientDrawable.java
+++ b/graphics/java/android/graphics/drawable/GradientDrawable.java
@@ -126,7 +126,7 @@
private boolean mRectIsDirty; // internal state
private boolean mMutated;
private Path mRingPath;
- private boolean mPathIsDirty;
+ private boolean mPathIsDirty = true;
/**
* Controls how the gradient is oriented relative to the drawable's bounds
@@ -179,6 +179,7 @@
*/
public void setCornerRadii(float[] radii) {
mGradientState.setCornerRadii(radii);
+ mPathIsDirty = true;
}
/**
@@ -187,6 +188,7 @@
*/
public void setCornerRadius(float radius) {
mGradientState.setCornerRadius(radius);
+ mPathIsDirty = true;
}
/**
@@ -215,11 +217,13 @@
}
public void setSize(int width, int height) {
- mGradientState.setSize(width, height);
+ mGradientState.setSize(width, height);
+ mPathIsDirty = true;
}
public void setShape(int shape) {
mRingPath = null;
+ mPathIsDirty = true;
mGradientState.setShape(shape);
}
@@ -312,8 +316,11 @@
switch (st.mShape) {
case RECTANGLE:
if (st.mRadiusArray != null) {
- mPath.reset();
- mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW);
+ if (mPathIsDirty || mRectIsDirty) {
+ mPath.reset();
+ mPath.addRoundRect(mRect, st.mRadiusArray, Path.Direction.CW);
+ mPathIsDirty = mRectIsDirty = false;
+ }
canvas.drawPath(mPath, mFillPaint);
if (haveStroke) {
canvas.drawPath(mPath, mStrokePaint);
diff --git a/graphics/java/android/graphics/drawable/StateListDrawable.java b/graphics/java/android/graphics/drawable/StateListDrawable.java
index 239be40..384ca81 100644
--- a/graphics/java/android/graphics/drawable/StateListDrawable.java
+++ b/graphics/java/android/graphics/drawable/StateListDrawable.java
@@ -20,6 +20,7 @@
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
+import java.util.Arrays;
import android.content.res.Resources;
import android.content.res.TypedArray;
@@ -44,6 +45,7 @@
* @attr ref android.R.styleable#DrawableStates_state_checkable
* @attr ref android.R.styleable#DrawableStates_state_checked
* @attr ref android.R.styleable#DrawableStates_state_selected
+ * @attr ref android.R.styleable#DrawableStates_state_activated
* @attr ref android.R.styleable#DrawableStates_state_active
* @attr ref android.R.styleable#DrawableStates_state_single
* @attr ref android.R.styleable#DrawableStates_state_first
@@ -52,6 +54,9 @@
* @attr ref android.R.styleable#DrawableStates_state_pressed
*/
public class StateListDrawable extends DrawableContainer {
+ private static final boolean DEBUG = false;
+ private static final String TAG = "StateListDrawable";
+
/**
* To be proper, we should have a getter for dither (and alpha, etc.)
* so that proxy classes like this can save/restore their delegates'
@@ -93,6 +98,8 @@
@Override
protected boolean onStateChange(int[] stateSet) {
int idx = mStateListState.indexOfStateSet(stateSet);
+ if (DEBUG) android.util.Log.i(TAG, "onStateChange " + this + " states "
+ + Arrays.toString(stateSet) + " found " + idx);
if (idx < 0) {
idx = mStateListState.indexOfStateSet(StateSet.WILD_CARD);
}
@@ -117,6 +124,10 @@
com.android.internal.R.styleable.StateListDrawable_variablePadding, false));
mStateListState.setConstantSize(a.getBoolean(
com.android.internal.R.styleable.StateListDrawable_constantSize, false));
+ mStateListState.setEnterFadeDuration(a.getInt(
+ com.android.internal.R.styleable.StateListDrawable_enterFadeDuration, 0));
+ mStateListState.setExitFadeDuration(a.getInt(
+ com.android.internal.R.styleable.StateListDrawable_exitFadeDuration, 0));
setDither(a.getBoolean(com.android.internal.R.styleable.StateListDrawable_dither,
DEFAULT_DITHER));
@@ -251,7 +262,7 @@
}
static final class StateListState extends DrawableContainerState {
- private int[][] mStateSets;
+ int[][] mStateSets;
StateListState(StateListState orig, StateListDrawable owner, Resources res) {
super(orig, owner, res);
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index 73f42de..5215795 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -33,11 +33,11 @@
public class ScriptC extends Script {
private static final String TAG = "ScriptC";
- ScriptC(int id, RenderScript rs) {
+ protected ScriptC(int id, RenderScript rs) {
super(id, rs);
}
- protected ScriptC(RenderScript rs, Resources resources, int resourceID, boolean isRoot) {
+ protected ScriptC(RenderScript rs, Resources resources, int resourceID) {
super(0, rs);
mID = internalCreate(rs, resources, resourceID);
}
diff --git a/include/media/stagefright/OMXCodec.h b/include/media/stagefright/OMXCodec.h
index 0f4fbfb..b2af9d7 100644
--- a/include/media/stagefright/OMXCodec.h
+++ b/include/media/stagefright/OMXCodec.h
@@ -241,6 +241,8 @@
status_t freeBuffersOnPort(
OMX_U32 portIndex, bool onlyThoseWeOwn = false);
+ status_t freeBuffer(OMX_U32 portIndex, size_t bufIndex);
+
void drainInputBuffer(IOMX::buffer_id buffer);
void fillOutputBuffer(IOMX::buffer_id buffer);
void drainInputBuffer(BufferInfo *info);
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 855a4e0..cad991d 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -260,25 +260,25 @@
const GLuint previousFbo = mSnapshot->fbo;
const int count = saveSnapshot(flags);
- int alpha = 255;
- SkXfermode::Mode mode;
+ if (!mSnapshot->invisible) {
+ int alpha = 255;
+ SkXfermode::Mode mode;
- if (p) {
- alpha = p->getAlpha();
- if (!mCaches.extensions.hasFramebufferFetch()) {
- const bool isMode = SkXfermode::IsMode(p->getXfermode(), &mode);
- if (!isMode) {
- // Assume SRC_OVER
- mode = SkXfermode::kSrcOver_Mode;
+ if (p) {
+ alpha = p->getAlpha();
+ if (!mCaches.extensions.hasFramebufferFetch()) {
+ const bool isMode = SkXfermode::IsMode(p->getXfermode(), &mode);
+ if (!isMode) {
+ // Assume SRC_OVER
+ mode = SkXfermode::kSrcOver_Mode;
+ }
+ } else {
+ mode = getXfermode(p->getXfermode());
}
} else {
- mode = getXfermode(p->getXfermode());
+ mode = SkXfermode::kSrcOver_Mode;
}
- } else {
- mode = SkXfermode::kSrcOver_Mode;
- }
- if (!mSnapshot->previous->invisible) {
createLayer(mSnapshot, left, top, right, bottom, alpha, mode, flags, previousFbo);
}
@@ -379,8 +379,7 @@
bounds.getHeight() > mCaches.maxTextureSize) {
snapshot->invisible = true;
} else {
- snapshot->invisible = snapshot->previous->invisible ||
- (alpha <= ALPHA_THRESHOLD && fboLayer);
+ snapshot->invisible = snapshot->invisible || (alpha <= ALPHA_THRESHOLD && fboLayer);
}
// Bail out if we won't draw in this snapshot
@@ -942,8 +941,11 @@
}
void OpenGLRenderer::drawLines(float* points, int count, SkPaint* paint) {
+ // TODO: Should do quickReject for each line
if (mSnapshot->invisible) return;
+ setupDraw();
+
int alpha;
SkXfermode::Mode mode;
getAlphaAndMode(paint, &alpha, &mode);
@@ -962,7 +964,7 @@
mode, false, true, (GLvoid*) 0, (GLvoid*) gMeshTextureOffset,
mCaches.line.getMeshBuffer());
} else {
- setupColorRect(0.0f, 0.0f, 1.0f, 1.0f, r, g, b, a, mode, false);
+ setupColorRect(0.0f, 0.0f, 1.0f, 1.0f, r, g, b, a, mode, false, true);
}
const float strokeWidth = paint->getStrokeWidth();
@@ -1011,6 +1013,9 @@
}
void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) {
+ // No need to check against the clip, we fill the clip region
+ if (mSnapshot->invisible) return;
+
Rect& clip(*mSnapshot->clipRect);
clip.snapToPixelBoundaries();
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
@@ -1406,7 +1411,8 @@
}
void OpenGLRenderer::setupColorRect(float left, float top, float right, float bottom,
- float r, float g, float b, float a, SkXfermode::Mode mode, bool ignoreTransform) {
+ float r, float g, float b, float a, SkXfermode::Mode mode,
+ bool ignoreTransform, bool ignoreMatrix) {
GLuint textureUnit = 0;
// Describe the required shaders
@@ -1431,21 +1437,24 @@
glVertexAttribPointer(mCaches.currentProgram->position, 2, GL_FLOAT, GL_FALSE,
gMeshStride, 0);
- // Setup uniforms
- mModelView.loadTranslate(left, top, 0.0f);
- mModelView.scale(right - left, bottom - top, 1.0f);
- if (!ignoreTransform) {
- mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
- dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
- } else {
- mat4 identity;
- mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
- dirtyLayer(left, top, right, bottom);
+ if (!ignoreMatrix) {
+ // Setup uniforms
+ mModelView.loadTranslate(left, top, 0.0f);
+ mModelView.scale(right - left, bottom - top, 1.0f);
+ if (!ignoreTransform) {
+ mCaches.currentProgram->set(mOrthoMatrix, mModelView, *mSnapshot->transform);
+ dirtyLayer(left, top, right, bottom, *mSnapshot->transform);
+ } else {
+ mat4 identity;
+ mCaches.currentProgram->set(mOrthoMatrix, mModelView, identity);
+ dirtyLayer(left, top, right, bottom);
+ }
}
mCaches.currentProgram->setColor(r, g, b, a);
// Setup attributes and uniforms required by the shaders
if (mShader) {
+ if (ignoreMatrix) mModelView.loadIdentity();
mShader->setupProgram(mCaches.currentProgram, mModelView, *mSnapshot, &textureUnit);
}
if (mColorFilter) {
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 2d612d4..93c2e6c 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -233,7 +233,8 @@
* Setups shaders to draw a colored rect.
*/
void setupColorRect(float left, float top, float right, float bottom,
- float r, float g, float b, float a, SkXfermode::Mode mode, bool ignoreTransform);
+ float r, float g, float b, float a, SkXfermode::Mode mode,
+ bool ignoreTransform, bool ignoreMatrix = false);
/**
* Draws a textured rectangle with the specified texture. The specified coordinates
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 377727b..b58785a 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -173,9 +173,15 @@
bitmap.allocPixels();
bitmap.eraseColor(0);
+ SkPaint pathPaint(*paint);
+ if (!pathPaint.getXfermode()) {
+ SkXfermode* mode = SkXfermode::Create(SkXfermode::kSrc_Mode);
+ pathPaint.setXfermode(mode)->safeUnref();
+ }
+
SkCanvas canvas(bitmap);
canvas.translate(-bounds.fLeft + offset, -bounds.fTop + offset);
- canvas.drawPath(*path, *paint);
+ canvas.drawPath(*path, pathPaint);
generateTexture(bitmap, texture);
diff --git a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
index f76a011..9c845aa 100644
--- a/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
+++ b/libs/rs/java/Balls/src/com/android/balls/BallsRS.java
@@ -107,9 +107,9 @@
smb.addIndexType(Primitive.LINE);
Mesh smA = smb.create();
- mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics, true);
+ mPhysicsScript = new ScriptC_ball_physics(mRS, mRes, R.raw.ball_physics);
- mScript = new ScriptC_balls(mRS, mRes, R.raw.balls, true);
+ mScript = new ScriptC_balls(mRS, mRes, R.raw.balls);
mScript.set_partMesh(smP);
mScript.set_arcMesh(smA);
mScript.set_physics_script(mPhysicsScript);
diff --git a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
index 0b26cfd..eb46e950 100644
--- a/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
+++ b/libs/rs/java/Fountain/src/com/android/fountain/FountainRS.java
@@ -45,7 +45,7 @@
smb.addIndexType(Primitive.POINT);
Mesh sm = smb.create();
- mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain, true);
+ mScript = new ScriptC_fountain(mRS, mRes, R.raw.fountain);
mScript.set_partMesh(sm);
mScript.bind_point(points);
mRS.contextBindRootScript(mScript);
diff --git a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
index e806969..16f404f 100644
--- a/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
+++ b/libs/rs/java/ImageProcessing/src/com/android/rs/image/ImageProcessingActivity.java
@@ -380,10 +380,10 @@
mScratchPixelsAllocation1 = Allocation.createTyped(mRS, tb.create());
mScratchPixelsAllocation2 = Allocation.createTyped(mRS, tb.create());
- mScriptVBlur = new ScriptC_vertical_blur(mRS, getResources(), R.raw.vertical_blur, false);
- mScriptHBlur = new ScriptC_horizontal_blur(mRS, getResources(), R.raw.horizontal_blur, false);
+ mScriptVBlur = new ScriptC_vertical_blur(mRS, getResources(), R.raw.vertical_blur);
+ mScriptHBlur = new ScriptC_horizontal_blur(mRS, getResources(), R.raw.horizontal_blur);
- mScript = new ScriptC_threshold(mRS, getResources(), R.raw.threshold, false);
+ mScript = new ScriptC_threshold(mRS, getResources(), R.raw.threshold);
mScript.set_width(mBitmapIn.getWidth());
mScript.set_height(mBitmapIn.getHeight());
mScript.set_radius(mRadius);
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
index 81bd578..1531d09 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SceneGraphRS.java
@@ -172,8 +172,8 @@
private void initRS() {
- mScript = new ScriptC_scenegraph(mRS, mRes, R.raw.scenegraph, true);
- mTransformScript = new ScriptC_transform(mRS, mRes, R.raw.transform, false);
+ mScript = new ScriptC_scenegraph(mRS, mRes, R.raw.scenegraph);
+ mTransformScript = new ScriptC_transform(mRS, mRes, R.raw.transform);
mTransformScript.set_transformScript(mTransformScript);
mScript.set_gTransformRS(mTransformScript);
diff --git a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
index ccbecd8..edf40e9 100644
--- a/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
+++ b/libs/rs/java/ModelViewer/src/com/android/modelviewer/SimpleModelRS.java
@@ -138,7 +138,7 @@
private void initRS() {
- mScript = new ScriptC_simplemodel(mRS, mRes, R.raw.simplemodel, true);
+ mScript = new ScriptC_simplemodel(mRS, mRes, R.raw.simplemodel);
initPFS();
initPF();
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
index aaeea876..ce9ab01 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsListRS.java
@@ -121,7 +121,7 @@
private void initRS() {
- mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist, true);
+ mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist);
mListAllocs = new ScriptField_ListAllocs_s(mRS, DATA_LIST.length);
for(int i = 0; i < DATA_LIST.length; i ++) {
diff --git a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
index 0990da3..85c2557 100644
--- a/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
+++ b/libs/rs/java/Samples/src/com/android/samples/RsRenderStatesRS.java
@@ -332,7 +332,7 @@
private void initRS() {
- mScript = new ScriptC_rsrenderstates(mRS, mRes, R.raw.rsrenderstates, true);
+ mScript = new ScriptC_rsrenderstates(mRS, mRes, R.raw.rsrenderstates);
initSamplers();
initProgramStore();
diff --git a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
index acce886..8054779 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/RSTestCore.java
@@ -57,7 +57,7 @@
mHeight = height;
stopTesting = false;
- mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist, true);
+ mScript = new ScriptC_rslist(mRS, mRes, R.raw.rslist);
unitTests = new ArrayList<UnitTest>();
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
index 9d57e90..e2cff00 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_fp_mad.java
@@ -29,7 +29,7 @@
public void run() {
RenderScript pRS = RenderScript.create();
- ScriptC_fp_mad s = new ScriptC_fp_mad(pRS, mRes, R.raw.fp_mad, true);
+ ScriptC_fp_mad s = new ScriptC_fp_mad(pRS, mRes, R.raw.fp_mad);
pRS.mMessageCallback = mRsMessage;
s.invoke_fp_mad_test(0, 0);
pRS.finish();
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
index da995da..2da43fc 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_primitives.java
@@ -88,7 +88,7 @@
public void run() {
RenderScript pRS = RenderScript.create();
- ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives, true);
+ ScriptC_primitives s = new ScriptC_primitives(pRS, mRes, R.raw.primitives);
pRS.mMessageCallback = mRsMessage;
if (!initializeGlobals(s)) {
// initializeGlobals failed
diff --git a/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java b/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java
index c555658..7ad77c7 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java
+++ b/libs/rs/java/tests/src/com/android/rs/test/UT_rsdebug.java
@@ -29,7 +29,7 @@
public void run() {
RenderScript pRS = RenderScript.create();
- ScriptC_rsdebug s = new ScriptC_rsdebug(pRS, mRes, R.raw.rsdebug, true);
+ ScriptC_rsdebug s = new ScriptC_rsdebug(pRS, mRes, R.raw.rsdebug);
pRS.mMessageCallback = mRsMessage;
s.invoke_test_rsdebug(0, 0);
pRS.finish();
diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp
index 3c3bd93..e1c06a6 100644
--- a/media/libstagefright/OMXCodec.cpp
+++ b/media/libstagefright/OMXCodec.cpp
@@ -1901,11 +1901,8 @@
if (mPortStatus[kPortIndexInput] == DISABLING) {
CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
- status_t err =
- mOMX->freeBuffer(mNode, kPortIndexInput, buffer);
+ status_t err = freeBuffer(kPortIndexInput, i);
CHECK_EQ(err, OK);
-
- buffers->removeAt(i);
} else if (mState != ERROR
&& mPortStatus[kPortIndexInput] != SHUTTING_DOWN) {
CHECK_EQ(mPortStatus[kPortIndexInput], ENABLED);
@@ -1945,20 +1942,9 @@
if (mPortStatus[kPortIndexOutput] == DISABLING) {
CODEC_LOGV("Port is disabled, freeing buffer %p", buffer);
- status_t err =
- mOMX->freeBuffer(mNode, kPortIndexOutput, buffer);
+ status_t err = freeBuffer(kPortIndexOutput, i);
CHECK_EQ(err, OK);
- // Cancel the buffer if it belongs to an ANativeWindow.
- if (info->mMediaBuffer != NULL) {
- sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
- if (!info->mOwnedByNativeWindow && graphicBuffer != 0) {
- cancelBufferToNativeWindow(info);
- // Ignore any errors
- }
- }
-
- buffers->removeAt(i);
#if 0
} else if (mPortStatus[kPortIndexOutput] == ENABLED
&& (flags & OMX_BUFFERFLAG_EOS)) {
@@ -2436,32 +2422,12 @@
CODEC_LOGV("freeing buffer %p on port %ld", info->mBuffer, portIndex);
- status_t err =
- mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
+ status_t err = freeBuffer(portIndex, i);
if (err != OK) {
stickyErr = err;
}
- if (info->mMediaBuffer != NULL) {
- info->mMediaBuffer->setObserver(NULL);
-
- // Make sure nobody but us owns this buffer at this point.
- CHECK_EQ(info->mMediaBuffer->refcount(), 0);
-
- // Cancel the buffer if it belongs to an ANativeWindow.
- sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
- if (!info->mOwnedByNativeWindow && graphicBuffer != 0) {
- status_t err = cancelBufferToNativeWindow(info);
- if (err != OK) {
- stickyErr = err;
- }
- }
-
- info->mMediaBuffer->release();
- }
-
- buffers->removeAt(i);
}
CHECK(onlyThoseWeOwn || buffers->isEmpty());
@@ -2469,6 +2435,35 @@
return stickyErr;
}
+status_t OMXCodec::freeBuffer(OMX_U32 portIndex, size_t bufIndex) {
+ Vector<BufferInfo> *buffers = &mPortBuffers[portIndex];
+
+ BufferInfo *info = &buffers->editItemAt(bufIndex);
+
+ status_t err = mOMX->freeBuffer(mNode, portIndex, info->mBuffer);
+
+ if (err == OK && info->mMediaBuffer != NULL) {
+ info->mMediaBuffer->setObserver(NULL);
+
+ // Make sure nobody but us owns this buffer at this point.
+ CHECK_EQ(info->mMediaBuffer->refcount(), 0);
+
+ // Cancel the buffer if it belongs to an ANativeWindow.
+ sp<GraphicBuffer> graphicBuffer = info->mMediaBuffer->graphicBuffer();
+ if (!info->mOwnedByNativeWindow && graphicBuffer != 0) {
+ err = cancelBufferToNativeWindow(info);
+ }
+
+ info->mMediaBuffer->release();
+ }
+
+ if (err == OK) {
+ buffers->removeAt(bufIndex);
+ }
+
+ return err;
+}
+
void OMXCodec::onPortSettingsChanged(OMX_U32 portIndex) {
CODEC_LOGV("PORT_SETTINGS_CHANGED(%ld)", portIndex);
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index 8de507e..8a6e82d 100644
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -103,4 +103,6 @@
0x120016=0x03050601:0x03040501:0x03030401:0x03020301:0x03070301:0x03010301:0x03000301;
</string>
+ <!-- Default for Settings.System.USER_ROTATION -->
+ <integer name="def_user_rotation">0</integer>
</resources>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 9ac832b..593edc8 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -61,7 +61,7 @@
// database gets upgraded properly. At a minimum, please confirm that 'upgradeVersion'
// is properly propagated through your change. Not doing so will result in a loss of user
// settings.
- private static final int DATABASE_VERSION = 59;
+ private static final int DATABASE_VERSION = 60;
private Context mContext;
@@ -775,6 +775,23 @@
upgradeVersion = 59;
}
+ if (upgradeVersion == 59) {
+ // Persistence for the rotation lock feature.
+ db.beginTransaction();
+ SQLiteStatement stmt = null;
+ try {
+ stmt = db.compileStatement("INSERT INTO system(name,value)"
+ + " VALUES(?,?);");
+ loadBooleanSetting(stmt, Settings.System.USER_ROTATION,
+ R.integer.def_user_rotation); // should be zero degrees
+ db.setTransactionSuccessful();
+ } finally {
+ db.endTransaction();
+ if (stmt != null) stmt.close();
+ }
+ upgradeVersion = 60;
+ }
+
// *** Remember to update DATABASE_VERSION above!
if (upgradeVersion != currentVersion) {
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png b/packages/SystemUI/res/drawable-land-mdpi/ic_sysbar_rotate_off.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png
rename to packages/SystemUI/res/drawable-land-mdpi/ic_sysbar_rotate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off.png
new file mode 100644
index 0000000..9e6793a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png b/packages/SystemUI/res/drawable-port-mdpi/ic_sysbar_rotate_off.png
similarity index 100%
rename from packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png
rename to packages/SystemUI/res/drawable-port-mdpi/ic_sysbar_rotate_off.png
Binary files differ
diff --git a/packages/SystemUI/res/values-land/strings.xml b/packages/SystemUI/res/values-land/strings.xml
new file mode 100644
index 0000000..e05e36b
--- /dev/null
+++ b/packages/SystemUI/res/values-land/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Rotation lock toast text: shown when rotation lock is turned on in landscape orientation.
+ -->
+ <string name="toast_rotation_locked">Screen is now locked in landscape orientation.</string>
+</resources>
diff --git a/packages/SystemUI/res/values-port/strings.xml b/packages/SystemUI/res/values-port/strings.xml
new file mode 100644
index 0000000..d3ab67b
--- /dev/null
+++ b/packages/SystemUI/res/values-port/strings.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/**
+ * Copyright (c) 2010, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-->
+<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
+ <!-- Rotation lock toast text: shown when rotation lock is turned on in portrait orientation.
+ -->
+ <string name="toast_rotation_locked">Screen is now locked in portrait orientation.</string>
+</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index 701aa9f..f34dc22 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -84,5 +84,11 @@
-->
<string name="recent_tasks_empty">No recent applications.</string>
+ <!-- Rotation lock toast text: shown when rotation lock is turned off (and the screen will
+ auto-rotate based on the accelerometer). -->
+ <string name="toast_rotation_free">Screen will rotate automatically.</string>
+ <!-- Rotation lock toast text: shown when rotation lock is turned on and the orientation is
+ undefined. -->
+ <string name="toast_rotation_locked">Screen rotation is now locked.</string>
</resources>
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
index a0f5be6..b4a9d76 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java
@@ -55,6 +55,7 @@
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
+import android.view.IWindowManager;
import android.view.WindowManager;
import android.view.WindowManagerImpl;
import android.widget.Button;
@@ -74,6 +75,8 @@
import com.android.internal.telephony.cdma.EriInfo;
import com.android.internal.telephony.cdma.TtyIntent;
+import com.android.server.WindowManagerService;
+
import com.android.systemui.statusbar.*;
import com.android.systemui.R;
@@ -102,6 +105,8 @@
private TextView mBatteryText;
private TextView mSignalText;
+ private final IWindowManager mWM;
+
private final AudioManager mAudioManager;
private final WifiManager mWifiManager;
private final TelephonyManager mPhone;
@@ -397,6 +402,11 @@
public SystemPanel(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
+ // our mighty overlord
+ mWM = IWindowManager.Stub.asInterface(
+ ServiceManager.getService("window"));
+
+
// get notified of phone state changes
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
@@ -437,6 +447,7 @@
});
mSoundButton = (ImageButton)findViewById(R.id.sound);
+ mSoundButton.setAlpha(getSilentMode() ? 0x7F : 0xFF);
mSoundButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
setSilentMode(!getSilentMode());
@@ -444,9 +455,22 @@
}
});
mOrientationButton = (ImageButton)findViewById(R.id.orientation);
+ mOrientationButton.setImageResource(
+ getAutoRotate()
+ ? R.drawable.ic_sysbar_rotate_on
+ : R.drawable.ic_sysbar_rotate_off);
mOrientationButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
- Toast.makeText(getContext(), "Orientation control not implemented; please adjust neck angle.", Toast.LENGTH_SHORT).show();
+ setAutoRotate(!getAutoRotate());
+ mOrientationButton.setImageResource(
+ getAutoRotate()
+ ? R.drawable.ic_sysbar_rotate_on
+ : R.drawable.ic_sysbar_rotate_off);
+ Toast.makeText(getContext(),
+ getAutoRotate()
+ ? R.string.toast_rotation_free
+ : R.string.toast_rotation_locked,
+ Toast.LENGTH_SHORT).show();
}
});
@@ -709,4 +733,31 @@
? R.drawable.sysbar_toggle_bg_on
: R.drawable.sysbar_toggle_bg_off);
}
+
+ void setAutoRotate(boolean rot) {
+ try {
+ ContentResolver cr = getContext().getContentResolver();
+ if (rot) {
+ mWM.thawRotation();
+ } else {
+ mWM.freezeRotation();
+ }
+ } catch (android.os.RemoteException exc) {
+ }
+ }
+
+ boolean getAutoRotate() {
+ ContentResolver cr = getContext().getContentResolver();
+ return 1 == Settings.System.getInt(cr,
+ Settings.System.ACCELEROMETER_ROTATION,
+ 1);
+ }
+
+ int getDisplayRotation() {
+ try {
+ return mWM.getRotation();
+ } catch (android.os.RemoteException exc) {
+ return 0;
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
index d024dd0..1383216 100644
--- a/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/usb/UsbStorageActivity.java
@@ -34,6 +34,7 @@
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.storage.IMountService;
import android.os.storage.StorageManager;
@@ -71,6 +72,12 @@
private static final int DLG_ERROR_SHARING = 2;
static final boolean localLOGV = false;
+ // UI thread
+ private Handler mUIHandler;
+
+ // thread for working with the storage services, which can be slow
+ private Handler mAsyncStorageHandler;
+
/** Used to detect when the USB cable is unplugged, so we can call finish() */
private BroadcastReceiver mUsbStateReceiver = new BroadcastReceiver() {
@Override
@@ -99,6 +106,12 @@
Log.w(TAG, "Failed to get StorageManager");
}
}
+
+ mUIHandler = new Handler();
+
+ HandlerThread thr = new HandlerThread("SystemUI UsbStorageActivity");
+ thr.start();
+ mAsyncStorageHandler = new Handler(thr.getLooper());
requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
setProgressBarIndeterminateVisibility(true);
@@ -123,7 +136,16 @@
mProgressBar = (ProgressBar) findViewById(com.android.internal.R.id.progress);
}
- private void switchDisplay(boolean usbStorageInUse) {
+ private void switchDisplay(final boolean usbStorageInUse) {
+ mUIHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ switchDisplayAsync(usbStorageInUse);
+ }
+ });
+ }
+
+ private void switchDisplayAsync(boolean usbStorageInUse) {
if (usbStorageInUse) {
mProgressBar.setVisibility(View.GONE);
mUnmountButton.setVisibility(View.VISIBLE);
@@ -148,7 +170,12 @@
mStorageManager.registerListener(mStorageListener);
registerReceiver(mUsbStateReceiver, new IntentFilter(Usb.ACTION_USB_STATE));
try {
- switchDisplay(mStorageManager.isUsbMassStorageEnabled());
+ mAsyncStorageHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ switchDisplay(mStorageManager.isUsbMassStorageEnabled());
+ }
+ });
} catch (Exception ex) {
Log.e(TAG, "Failed to read UMS enable state", ex);
}
@@ -188,7 +215,7 @@
.setTitle(R.string.dlg_confirm_kill_storage_users_title)
.setPositiveButton(R.string.dlg_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
- switchUsbMassStorageAsync(true);
+ switchUsbMassStorage(true);
}})
.setNegativeButton(R.string.cancel, null)
.setMessage(R.string.dlg_confirm_kill_storage_users_text)
@@ -210,26 +237,42 @@
showDialog(id);
}
- private void switchUsbMassStorageAsync(boolean on) {
- mUnmountButton.setVisibility(View.GONE);
- mMountButton.setVisibility(View.GONE);
-
- mProgressBar.setVisibility(View.VISIBLE);
- // will be hidden once USB mass storage kicks in (or fails)
-
- final boolean _on = on;
- new Thread() {
+ private void switchUsbMassStorage(final boolean on) {
+ // things to do on the UI thread
+ mUIHandler.post(new Runnable() {
+ @Override
public void run() {
- if (_on) {
+ mUnmountButton.setVisibility(View.GONE);
+ mMountButton.setVisibility(View.GONE);
+
+ mProgressBar.setVisibility(View.VISIBLE);
+ // will be hidden once USB mass storage kicks in (or fails)
+ }
+ });
+
+ // things to do elsewhere
+ mAsyncStorageHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ if (on) {
mStorageManager.enableUsbMassStorage();
} else {
mStorageManager.disableUsbMassStorage();
}
}
- }.start();
+ });
}
private void checkStorageUsers() {
+ mAsyncStorageHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ checkStorageUsersAsync();
+ }
+ });
+ }
+
+ private void checkStorageUsersAsync() {
IMountService ims = getMountService();
if (ims == null) {
// Display error dialog
@@ -258,7 +301,7 @@
showDialogInner(DLG_CONFIRM_KILL_STORAGE_USERS);
} else {
if (localLOGV) Log.i(TAG, "Enabling UMS");
- switchUsbMassStorageAsync(true);
+ switchUsbMassStorage(true);
}
}
@@ -268,7 +311,7 @@
checkStorageUsers();
} else if (v == mUnmountButton) {
if (localLOGV) Log.i(TAG, "Disabling UMS");
- switchUsbMassStorageAsync(false);
+ switchUsbMassStorage(false);
}
}
diff --git a/policy/src/com/android/internal/policy/impl/LockScreen.java b/policy/src/com/android/internal/policy/impl/LockScreen.java
index 4644a7c..50d10bf 100644
--- a/policy/src/com/android/internal/policy/impl/LockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/LockScreen.java
@@ -219,7 +219,7 @@
}
class WaveViewMethods implements WaveView.OnTriggerListener {
- private static final int WAIT_FOR_ANIMATION_TIMEOUT = 500;
+ private static final int WAIT_FOR_ANIMATION_TIMEOUT = 0;
private static final int STAY_ON_WHILE_GRABBED_TIMEOUT = 30000;
/** {@inheritDoc} */
diff --git a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
index af1bf59..2f2f943 100755
--- a/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
+++ b/policy/src/com/android/internal/policy/impl/PhoneWindowManager.java
@@ -230,6 +230,10 @@
int mLidOpenRotation;
int mCarDockRotation;
int mDeskDockRotation;
+
+ int mUserRotationMode = WindowManagerPolicy.USER_ROTATION_FREE;
+ int mUserRotation = Surface.ROTATION_0;
+
boolean mCarDockEnablesAccelerometer;
boolean mDeskDockEnablesAccelerometer;
int mLidKeyboardAccessibility;
@@ -336,6 +340,8 @@
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.ACCELEROMETER_ROTATION), false, this);
resolver.registerContentObserver(Settings.System.getUriFor(
+ Settings.System.USER_ROTATION), false, this);
+ resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.SCREEN_OFF_TIMEOUT), false, this);
resolver.registerContentObserver(Settings.System.getUriFor(
Settings.System.POINTER_LOCATION), false, this);
@@ -678,10 +684,20 @@
"fancy_rotation_anim", 0) != 0 ? 0x80 : 0;
int accelerometerDefault = Settings.System.getInt(resolver,
Settings.System.ACCELEROMETER_ROTATION, DEFAULT_ACCELEROMETER_ROTATION);
+
+ // set up rotation lock state
+ mUserRotationMode = (mAccelerometerDefault == 0)
+ ? WindowManagerPolicy.USER_ROTATION_LOCKED
+ : WindowManagerPolicy.USER_ROTATION_FREE;
+ mUserRotation = Settings.System.getInt(resolver,
+ Settings.System.USER_ROTATION,
+ Surface.ROTATION_0);
+
if (mAccelerometerDefault != accelerometerDefault) {
mAccelerometerDefault = accelerometerDefault;
updateOrientationListenerLp();
}
+
if (mSystemReady) {
int pointerLocation = Settings.System.getInt(resolver,
Settings.System.POINTER_LOCATION, 0);
@@ -2280,6 +2296,8 @@
return mCarDockRotation;
} else if (mDockMode == Intent.EXTRA_DOCK_STATE_DESK && mDeskDockRotation >= 0) {
return mDeskDockRotation;
+ } else if (mUserRotationMode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
+ return mUserRotation;
} else {
if (useSensorForOrientationLp(orientation)) {
return mOrientationListener.getCurrentRotation(lastRotation);
@@ -2323,6 +2341,26 @@
return sensorRotation == mPortraitRotation || sensorRotation == mUpsideDownRotation;
}
+
+ // User rotation: to be used when all else fails in assigning an orientation to the device
+ public void setUserRotationMode(int mode, int rot) {
+ ContentResolver res = mContext.getContentResolver();
+ mUserRotationMode = mode;
+ if (mode == WindowManagerPolicy.USER_ROTATION_LOCKED) {
+ mUserRotation = rot;
+ Settings.System.putInt(res,
+ Settings.System.ACCELEROMETER_ROTATION,
+ 0);
+ Settings.System.putInt(res,
+ Settings.System.USER_ROTATION,
+ rot);
+ } else {
+ Settings.System.putInt(res,
+ Settings.System.ACCELEROMETER_ROTATION,
+ 1);
+ }
+ }
+
public boolean detectSafeMode() {
try {
int menuState = mWindowManager.getKeycodeState(KeyEvent.KEYCODE_MENU);
diff --git a/services/java/com/android/server/DockObserver.java b/services/java/com/android/server/DockObserver.java
index f993093..dea9007 100644
--- a/services/java/com/android/server/DockObserver.java
+++ b/services/java/com/android/server/DockObserver.java
@@ -102,6 +102,7 @@
try {
FileReader file = new FileReader(DOCK_STATE_PATH);
int len = file.read(buffer, 0, 1024);
+ file.close();
mPreviousDockState = mDockState = Integer.valueOf((new String(buffer, 0, len)).trim());
} catch (FileNotFoundException e) {
Slog.w(TAG, "This kernel does not have dock station support");
diff --git a/services/java/com/android/server/InputManager.java b/services/java/com/android/server/InputManager.java
index e7eb129..13be984 100644
--- a/services/java/com/android/server/InputManager.java
+++ b/services/java/com/android/server/InputManager.java
@@ -493,7 +493,9 @@
CALIBRATION_DIR_PATH + deviceName + ".idc");
if (calibrationFile.exists()) {
try {
- properties.load(new FileInputStream(calibrationFile));
+ FileInputStream fis = new FileInputStream(calibrationFile);
+ properties.load(fis);
+ fis.close();
} catch (IOException ex) {
Slog.w(TAG, "Error reading input device calibration properties for device "
+ deviceName + " from " + calibrationFile + ".", ex);
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 155c397..41471d9 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -116,6 +116,8 @@
static final long TIME_TO_RECONNECT = 10*1000;
private static final int NOT_A_SUBTYPE_ID = -1;
+ // If IME doesn't support the system locale, the default subtype will be the first defined one.
+ private static final int DEFAULT_SUBTYPE_ID = 0;
final Context mContext;
final Handler mHandler;
@@ -993,7 +995,6 @@
if (mCurMethod != null) {
try {
putSelectedInputMethodSubtype(info, subtypeId);
- mCurrentSubtype = subtype;
if (mInputShown) {
// If mInputShown is false, there is no IME button on the
// system bar.
@@ -1016,11 +1017,7 @@
mCurMethodId = id;
// Set a subtype to this input method.
// subtypeId the name of a subtype which will be set.
- if (putSelectedInputMethodSubtype(info, subtypeId)) {
- mCurrentSubtype = info.getSubtypes().get(subtypeId);
- } else {
- mCurrentSubtype = null;
- }
+ putSelectedInputMethodSubtype(info, subtypeId);
Settings.Secure.putString(mContext.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD, id);
@@ -1820,16 +1817,16 @@
Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE, NOT_A_SUBTYPE_ID);
}
- private boolean putSelectedInputMethodSubtype(InputMethodInfo imi, int subtypeId) {
- ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
+ private void putSelectedInputMethodSubtype(InputMethodInfo imi, int subtypeId) {
+ final ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
if (subtypeId >= 0 && subtypeId < subtypes.size()) {
Settings.Secure.putInt(mContext.getContentResolver(),
Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE,
subtypes.get(subtypeId).hashCode());
- return true;
+ mCurrentSubtype = subtypes.get(subtypeId);
} else {
resetSelectedInputMethodSubtype();
- return false;
+ mCurrentSubtype = null;
}
}
@@ -1855,10 +1852,64 @@
return NOT_A_SUBTYPE_ID;
}
+ // If there are no selected subtypes, tries finding the most applicable one according to the
+ // current system locale
+ private int findApplicableSubtype(String id) {
+ InputMethodInfo imi = mMethodMap.get(id);
+ if (imi == null) {
+ return NOT_A_SUBTYPE_ID;
+ }
+ ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
+ if (subtypes == null || subtypes.size() == 0) {
+ return NOT_A_SUBTYPE_ID;
+ }
+ final String locale = mContext.getResources().getConfiguration().locale.toString();
+ final String language = locale.substring(0, 2);
+ boolean partialMatchFound = false;
+ int applicableSubtypeId = DEFAULT_SUBTYPE_ID;
+ for (int i = 0; i < subtypes.size(); ++i) {
+ final String subtypeLocale = subtypes.get(i).getLocale();
+ if (locale.equals(subtypeLocale)) {
+ // Exact match (e.g. system locale is "en_US" and subtype locale is "en_US")
+ applicableSubtypeId = i;
+ break;
+ } else if (!partialMatchFound && subtypeLocale.startsWith(language)) {
+ // Partial match (e.g. system locale is "en_US" and subtype locale is "en")
+ applicableSubtypeId = i;
+ partialMatchFound = true;
+ }
+ }
+
+ // The first subtype applicable to the system locale will be defined as the most applicable
+ // subtype.
+ if (DEBUG) {
+ Slog.d(TAG, "Applicable InputMethodSubtype was found: " + applicableSubtypeId
+ + subtypes.get(applicableSubtypeId).getLocale());
+ }
+ return applicableSubtypeId;
+ }
+
/**
* @return Return the current subtype of this input method.
*/
public InputMethodSubtype getCurrentInputMethodSubtype() {
+ boolean subtypeIsSelected = false;
+ try {
+ subtypeIsSelected = Settings.Secure.getInt(mContext.getContentResolver(),
+ Settings.Secure.SELECTED_INPUT_METHOD_SUBTYPE) != NOT_A_SUBTYPE_ID;
+ } catch (SettingNotFoundException e) {
+ }
+ if (!subtypeIsSelected || mCurrentSubtype == null) {
+ String lastInputMethodId = Settings.Secure.getString(mContext
+ .getContentResolver(), Settings.Secure.DEFAULT_INPUT_METHOD);
+ int subtypeId = getSelectedInputMethodSubtypeId(lastInputMethodId);
+ if (subtypeId == NOT_A_SUBTYPE_ID) {
+ subtypeId = findApplicableSubtype(lastInputMethodId);
+ }
+ if (subtypeId != NOT_A_SUBTYPE_ID) {
+ mCurrentSubtype = mMethodMap.get(lastInputMethodId).getSubtypes().get(subtypeId);
+ }
+ }
return mCurrentSubtype;
}
diff --git a/services/java/com/android/server/PackageManagerService.java b/services/java/com/android/server/PackageManagerService.java
index 7c758a2..7ad95da 100644
--- a/services/java/com/android/server/PackageManagerService.java
+++ b/services/java/com/android/server/PackageManagerService.java
@@ -1225,6 +1225,7 @@
}
}
+ permReader.close();
} catch (XmlPullParserException e) {
Slog.w(TAG, "Got execption parsing permissions.", e);
} catch (IOException e) {
diff --git a/services/java/com/android/server/UsbObserver.java b/services/java/com/android/server/UsbObserver.java
index 546e5f8..cfa83be 100644
--- a/services/java/com/android/server/UsbObserver.java
+++ b/services/java/com/android/server/UsbObserver.java
@@ -119,6 +119,7 @@
try {
FileReader file = new FileReader(USB_CONFIGURATION_PATH);
int len = file.read(buffer, 0, 1024);
+ file.close();
mPreviousUsbConfig = mUsbConfig = Integer.valueOf((new String(buffer, 0, len)).trim());
} catch (FileNotFoundException e) {
@@ -133,6 +134,7 @@
File file = new File(files[i], "enable");
FileReader reader = new FileReader(file);
int len = reader.read(buffer, 0, 1024);
+ reader.close();
int value = Integer.valueOf((new String(buffer, 0, len)).trim());
String functionName = files[i].getName();
if (value == 1) {
diff --git a/services/java/com/android/server/VibratorService.java b/services/java/com/android/server/VibratorService.java
index f0b5955..2fcdb5d 100755
--- a/services/java/com/android/server/VibratorService.java
+++ b/services/java/com/android/server/VibratorService.java
@@ -112,6 +112,10 @@
context.registerReceiver(mIntentReceiver, filter);
}
+ public boolean hasVibrator() {
+ return vibratorExists();
+ }
+
public void vibrate(long milliseconds, IBinder token) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.VIBRATE)
!= PackageManager.PERMISSION_GRANTED) {
@@ -380,6 +384,7 @@
volatile VibrateThread mThread;
+ native static boolean vibratorExists();
native static void vibratorOn(long milliseconds);
native static void vibratorOff();
}
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 1cbc8324..41b3da6 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -85,6 +85,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.StrictMode;
import android.os.SystemClock;
import android.os.SystemProperties;
import android.os.TokenWatcher;
@@ -920,6 +921,11 @@
notifyAll();
}
+ // For debug builds, log event loop stalls to dropbox for analysis.
+ if (StrictMode.conditionallyEnableDebugLogging()) {
+ Slog.i(TAG, "Enabled StrictMode logging for WMThread's Looper");
+ }
+
Looper.loop();
}
}
@@ -957,6 +963,11 @@
notifyAll();
}
+ // For debug builds, log event loop stalls to dropbox for analysis.
+ if (StrictMode.conditionallyEnableDebugLogging()) {
+ Slog.i(TAG, "Enabled StrictMode for PolicyThread's Looper");
+ }
+
Looper.loop();
}
}
@@ -4831,6 +4842,26 @@
}
}
+ public void freezeRotation() {
+ if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
+ "setRotation()")) {
+ throw new SecurityException("Requires SET_ORIENTATION permission");
+ }
+
+ mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_LOCKED, mRotation);
+ setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
+ }
+
+ public void thawRotation() {
+ if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
+ "setRotation()")) {
+ throw new SecurityException("Requires SET_ORIENTATION permission");
+ }
+
+ mPolicy.setUserRotationMode(WindowManagerPolicy.USER_ROTATION_FREE, 0);
+ setRotationUnchecked(WindowManagerPolicy.USE_LAST_ROTATION, false, 0);
+ }
+
public void setRotation(int rotation,
boolean alwaysSendConfiguration, int animFlags) {
if (!checkCallingPermission(android.Manifest.permission.SET_ORIENTATION,
diff --git a/services/java/com/android/server/WiredAccessoryObserver.java b/services/java/com/android/server/WiredAccessoryObserver.java
index 2046473..d97d41c 100644
--- a/services/java/com/android/server/WiredAccessoryObserver.java
+++ b/services/java/com/android/server/WiredAccessoryObserver.java
@@ -75,7 +75,7 @@
// At any given time both headsets could be inserted
// one on the board and one on the dock
// observe two UEVENTs
- for (int i = 0; i <= MAX_AUDIO_PORTS; i++) {
+ for (int i = 0; i < MAX_AUDIO_PORTS; i++) {
startObserving(uEventInfo[i][0]);
}
init(); // set initial status
@@ -120,7 +120,7 @@
int newState = mHeadsetState;
mPrevHeadsetState = mHeadsetState;
- for (int i = 0; i <= MAX_AUDIO_PORTS; i++) {
+ for (int i = 0; i < MAX_AUDIO_PORTS; i++) {
try {
FileReader file = new FileReader(uEventInfo[i][1]);
int len = file.read(buffer, 0, 1024);
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 60b2b67..84839b6 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -1334,6 +1334,11 @@
}
}
+ // For debug builds, log event loop stalls to dropbox for analysis.
+ if (StrictMode.conditionallyEnableDebugLogging()) {
+ Slog.i(TAG, "Enabled StrictMode logging for AThread's Looper");
+ }
+
Looper.loop();
}
}
diff --git a/services/jni/com_android_server_VibratorService.cpp b/services/jni/com_android_server_VibratorService.cpp
index 6ec5c07..0912d43 100644
--- a/services/jni/com_android_server_VibratorService.cpp
+++ b/services/jni/com_android_server_VibratorService.cpp
@@ -29,6 +29,11 @@
namespace android
{
+static jboolean vibratorExists(JNIEnv *env, jobject clazz)
+{
+ return vibrator_exists() > 0 ? JNI_TRUE : JNI_FALSE;
+}
+
static void vibratorOn(JNIEnv *env, jobject clazz, jlong timeout_ms)
{
// LOGI("vibratorOn\n");
@@ -42,6 +47,7 @@
}
static JNINativeMethod method_table[] = {
+ { "vibratorExists", "()Z", (void*)vibratorExists },
{ "vibratorOn", "(J)V", (void*)vibratorOn },
{ "vibratorOff", "()V", (void*)vibratorOff }
};
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index 185d413..c3ad9e6 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -261,8 +261,10 @@
protected static final int EVENT_LOG_BAD_DNS_ADDRESS = 50100;
//***** Member Variables
+ protected int mId;
protected int mTag;
protected PhoneBase phone;
+ protected RetryManager mRetryMgr;
protected int cid;
protected LinkProperties mLinkProperties = new LinkProperties();
protected LinkCapabilities mCapabilities = new LinkCapabilities();
@@ -285,10 +287,11 @@
//***** Constructor
- protected DataConnection(PhoneBase phone, String name) {
+ protected DataConnection(PhoneBase phone, String name, RetryManager rm) {
super(name);
if (DBG) log("DataConnection constructor E");
this.phone = phone;
+ mRetryMgr = rm;
this.cid = -1;
clearSettings();
@@ -358,8 +361,8 @@
if (dp.onCompletedMsg != null) {
Message msg = dp.onCompletedMsg;
- log(String.format("msg.what=%d msg.obj=%s",
- msg.what, ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
+ log(String.format("msg=%s msg.obj=%s", msg.toString(),
+ ((msg.obj instanceof String) ? (String) msg.obj : "<no-reason>")));
AsyncResult.forMessage(msg);
msg.sendToTarget();
}
@@ -372,6 +375,10 @@
clearSettings();
}
+ public RetryManager getRetryMgr() {
+ return mRetryMgr;
+ }
+
/**
* Clear all settings called when entering mInactiveState.
*/
@@ -857,13 +864,13 @@
/**
* Connect to the apn and return an AsyncResult in onCompletedMsg.
- * Used for cellular networks that use Acess Point Names (APN) such
+ * Used for cellular networks that use Acesss Point Names (APN) such
* as GSM networks.
*
* @param onCompletedMsg is sent with its msg.obj as an AsyncResult object.
* With AsyncResult.userObj set to the original msg.obj,
* AsyncResult.result = FailCause and AsyncResult.exception = Exception().
- * @param apn is the Acces Point Name to connect to
+ * @param apn is the Access Point Name to connect to
*/
public void connect(Message onCompletedMsg, ApnSetting apn) {
sendMessage(obtainMessage(EVENT_CONNECT, new ConnectionParams(apn, onCompletedMsg)));
@@ -915,6 +922,13 @@
}
/**
+ * Get the DataConnection ID
+ */
+ public int getDataConnectionId() {
+ return mId;
+ }
+
+ /**
* Return the LinkProperties for the connection.
*
* @return a copy of the LinkProperties, is never null.
diff --git a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
index 52839be..f8812ec 100644
--- a/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/DataConnectionTracker.java
@@ -16,27 +16,38 @@
package com.android.internal.telephony;
+import com.android.internal.telephony.cdma.CDMAPhone;
+
import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.SharedPreferences;
+import android.net.IConnectivityManager;
import android.net.LinkCapabilities;
import android.net.LinkProperties;
+import android.net.NetworkInfo;
+import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Message;
+import android.os.ServiceManager;
+import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.text.TextUtils;
import android.util.Log;
import java.util.ArrayList;
-
+import java.util.HashMap;
+import java.util.concurrent.atomic.AtomicInteger;
/**
* {@hide}
- *
*/
public abstract class DataConnectionTracker extends Handler {
- protected static final boolean DBG = false;
- protected final String LOG_TAG = "DataConnectionTracker";
+ protected static final boolean DBG = true;
/**
* IDLE: ready to start data connection setup, default state
@@ -121,9 +132,10 @@
protected boolean mMasterDataEnabled = true;
protected boolean[] dataEnabled = new boolean[APN_NUM_TYPES];
+
protected int enabledCount = 0;
- /* Currently requested APN type */
+ /* Currently requested APN type (TODO: This should probably be a parameter not a member) */
protected String mRequestedApnType = Phone.APN_TYPE_DEFAULT;
/** Retry configuration: A doubling of retry times from 5secs to 30minutes */
@@ -165,20 +177,27 @@
// represents an invalid IP address
protected static final String NULL_IP = "0.0.0.0";
+ // TODO: See if we can remove INTENT_RECONNECT_ALARM
+ // having to have different values for GSM and
+ // CDMA. If so we can then remove the need for
+ // getActionIntentReconnectAlarm.
+ protected static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
// member variables
- protected PhoneBase phone;
- protected Activity activity = Activity.NONE;
- protected State state = State.IDLE;
+ protected PhoneBase mPhone;
+ protected Activity mActivity = Activity.NONE;
+ protected State mState = State.IDLE;
protected Handler mDataConnectionTracker = null;
- protected long txPkts, rxPkts, sentSinceLastRecv;
- protected int netStatPollPeriod;
+ protected long mTxPkts;
+ protected long mRxPkts;
+ protected long mSentSinceLastRecv;
+ protected int mNetStatPollPeriod;
protected int mNoRecvPollCount = 0;
- protected boolean netStatPollEnabled = false;
+ protected boolean mNetStatPollEnabled = false;
- /** Manage the behavior of data retry after failure */
+ /** Manage the behavior of data retry after failure (TODO: One per connection in the future?) */
protected RetryManager mRetryMgr = new RetryManager();
// wifi connection status will be updated by sticky intent
@@ -188,37 +207,125 @@
protected PendingIntent mReconnectIntent = null;
/** CID of active data connection */
- protected int cidActive;
+ protected int mCidActive;
/** indication of our availability (preconditions to trysetupData are met) **/
protected boolean mAvailability = false;
+ // When false we will not auto attach and manully attaching is required.
+ protected boolean mAutoAttachOnCreation = false;
+
+ // State of screen
+ // (TODO: Reconsider tying directly to screen, maybe this is
+ // really a lower power mode")
+ protected boolean mIsScreenOn = true;
+
/** The link properties (dns, gateway, ip, etc) */
protected LinkProperties mLinkProperties = new LinkProperties();
/** The link capabilities */
protected LinkCapabilities mLinkCapabilities = new LinkCapabilities();
+ /** Allows the generation of unique Id's for DataConnection objects */
+ protected AtomicInteger mUniqueIdGenerator = new AtomicInteger(0);
+
+ /** The data connections. */
+ protected HashMap<Integer, DataConnection> mDataConnections =
+ new HashMap<Integer, DataConnection>();
+
+ protected BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
+ {
+ @Override
+ public void onReceive(Context context, Intent intent)
+ {
+ String action = intent.getAction();
+ if (action.equals(Intent.ACTION_SCREEN_ON)) {
+ mIsScreenOn = true;
+ stopNetStatPoll();
+ startNetStatPoll();
+ } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
+ mIsScreenOn = false;
+ stopNetStatPoll();
+ startNetStatPoll();
+ } else if (action.equals(getActionIntentReconnectAlarm())) {
+ log("Reconnect alarm. Previous state was " + mState);
+
+ String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
+ if (mState == State.FAILED) {
+ Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
+ msg.arg1 = 0; // tearDown is false
+ msg.obj = reason;
+ sendMessage(msg);
+ }
+ sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
+ } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
+ final android.net.NetworkInfo networkInfo = (NetworkInfo)
+ intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
+ mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
+ } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
+ final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+ WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
+
+ if (!enabled) {
+ // when WiFi got disabled, the NETWORK_STATE_CHANGED_ACTION
+ // quit and won't report disconnected until next enabling.
+ mIsWifiConnected = false;
+ }
+ }
+ }
+ };
+
/**
* Default constructor
*/
protected DataConnectionTracker(PhoneBase phone) {
super();
- this.phone = phone;
+ mPhone = phone;
+
+ IntentFilter filter = new IntentFilter();
+ filter.addAction(getActionIntentReconnectAlarm());
+ filter.addAction(Intent.ACTION_SCREEN_ON);
+ filter.addAction(Intent.ACTION_SCREEN_OFF);
+ filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
+ filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+
+ // TODO: Why is this registering the phone as the receiver of the intent
+ // and not its own handler?
+ mPhone.getContext().registerReceiver(mIntentReceiver, filter, null, mPhone);
+
+ // This preference tells us 1) initial condition for "dataEnabled",
+ // and 2) whether the RIL will setup the baseband to auto-PS attach.
+ SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mPhone.getContext());
+ boolean dataEnabledSetting = true;
+ try {
+ dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager.
+ getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled();
+ } catch (Exception e) {
+ // nothing to do - use the old behavior and leave data on
+ }
+ dataEnabled[APN_DEFAULT_ID] =
+ !sp.getBoolean(PhoneBase.DATA_DISABLED_ON_BOOT_KEY, false) &&
+ dataEnabledSetting;
+ if (dataEnabled[APN_DEFAULT_ID]) {
+ enabledCount++;
+ }
+ mAutoAttachOnCreation = dataEnabled[APN_DEFAULT_ID];
}
- public abstract void dispose();
+ public void dispose() {
+ mPhone.getContext().unregisterReceiver(this.mIntentReceiver);
+ }
public Activity getActivity() {
- return activity;
+ return mActivity;
}
public State getState() {
- return state;
+ return mState;
}
public String getStateInString() {
- switch (state) {
+ switch (mState) {
case IDLE: return "IDLE";
case INITING: return "INIT";
case CONNECTING: return "CING";
@@ -231,6 +338,14 @@
}
/**
+ * @return the data connections
+ */
+ public ArrayList<DataConnection> getAllDataConnections() {
+ /** TODO: change return type to Collection? */
+ return new ArrayList<DataConnection>(mDataConnections.values());
+ }
+
+ /**
* The data connection is expected to be setup while device
* 1. has Icc card
* 2. registered for data service
@@ -246,9 +361,9 @@
// the shared values. If it is not, then update it.
public void setDataOnRoamingEnabled(boolean enabled) {
if (getDataOnRoamingEnabled() != enabled) {
- Settings.Secure.putInt(phone.getContext().getContentResolver(),
+ Settings.Secure.putInt(mPhone.getContext().getContentResolver(),
Settings.Secure.DATA_ROAMING, enabled ? 1 : 0);
- if (phone.getServiceState().getRoaming()) {
+ if (mPhone.getServiceState().getRoaming()) {
if (enabled) {
mRetryMgr.resetRetryCount();
}
@@ -257,16 +372,19 @@
}
}
- //Retrieve the data roaming setting from the shared preferences.
+ // Retrieve the data roaming setting from the shared preferences.
public boolean getDataOnRoamingEnabled() {
try {
- return Settings.Secure.getInt(phone.getContext().getContentResolver(),
- Settings.Secure.DATA_ROAMING) > 0;
+ return Settings.Secure.getInt(
+ mPhone.getContext().getContentResolver(), Settings.Secure.DATA_ROAMING) > 0;
} catch (SettingNotFoundException snfe) {
return false;
}
}
+
+ protected abstract String getActionIntentReconnectAlarm();
+
// abstract handler methods
protected abstract boolean onTrySetupData(String reason);
protected abstract void onRoamingOff();
@@ -274,14 +392,14 @@
protected abstract void onRadioAvailable();
protected abstract void onRadioOffOrNotAvailable();
protected abstract void onDataSetupComplete(AsyncResult ar);
- protected abstract void onDisconnectDone(AsyncResult ar);
+ protected abstract void onDisconnectDone(int connId, AsyncResult ar);
protected abstract void onResetDone(AsyncResult ar);
protected abstract void onVoiceCallStarted();
protected abstract void onVoiceCallEnded();
protected abstract void onCleanUpConnection(boolean tearDown, String reason);
@Override
- public void handleMessage (Message msg) {
+ public void handleMessage(Message msg) {
switch (msg.what) {
case EVENT_ENABLE_NEW_APN:
@@ -291,7 +409,7 @@
case EVENT_TRY_SETUP_DATA:
String reason = null;
if (msg.obj instanceof String) {
- reason = (String)msg.obj;
+ reason = (String) msg.obj;
}
onTrySetupData(reason);
break;
@@ -316,12 +434,13 @@
break;
case EVENT_DATA_SETUP_COMPLETE:
- cidActive = msg.arg1;
+ mCidActive = msg.arg1;
onDataSetupComplete((AsyncResult) msg.obj);
break;
case EVENT_DISCONNECT_DONE:
- onDisconnectDone((AsyncResult) msg.obj);
+ log("DataConnectoinTracker.handleMessage: EVENT_DISCONNECT_DONE msg=" + msg);
+ onDisconnectDone(msg.arg1, (AsyncResult) msg.obj);
break;
case EVENT_VOICE_CALL_STARTED:
@@ -334,7 +453,7 @@
case EVENT_CLEAN_UP_CONNECTION:
boolean tearDown = (msg.arg1 == 0) ? false : true;
- onCleanUpConnection(tearDown, (String)msg.obj);
+ onCleanUpConnection(tearDown, (String) msg.obj);
break;
case EVENT_SET_MASTER_DATA_ENABLE:
@@ -354,8 +473,9 @@
/**
* Report the current state of data connectivity (enabled or disabled)
+ *
* @return {@code false} if data connectivity has been explicitly disabled,
- * {@code true} otherwise.
+ * {@code true} otherwise.
*/
public synchronized boolean getDataEnabled() {
return dataEnabled[APN_DEFAULT_ID];
@@ -363,8 +483,9 @@
/**
* Report on whether data connectivity is enabled
+ *
* @return {@code false} if data connectivity has been explicitly disabled,
- * {@code true} otherwise.
+ * {@code true} otherwise.
*/
public boolean getAnyDataEnabled() {
return (enabledCount != 0);
@@ -378,6 +499,8 @@
protected abstract void log(String s);
+ protected abstract void loge(String s);
+
protected int apnTypeToId(String type) {
if (TextUtils.equals(type, Phone.APN_TYPE_DEFAULT)) {
return APN_DEFAULT_ID;
@@ -407,7 +530,7 @@
case APN_HIPRI_ID:
return Phone.APN_TYPE_HIPRI;
default:
- Log.e(LOG_TAG, "Unknown id (" + id + ") in apnIdToType");
+ log("Unknown id (" + id + ") in apnIdToType");
return Phone.APN_TYPE_DEFAULT;
}
}
@@ -420,8 +543,6 @@
protected abstract String getActiveApnString();
- public abstract ArrayList<DataConnection> getAllDataConnections();
-
protected abstract void setState(State s);
protected LinkProperties getLinkProperties(String apnType) {
@@ -467,33 +588,34 @@
protected void notifyDataConnection(String reason) {
for (int id = 0; id < APN_NUM_TYPES; id++) {
if (dataEnabled[id]) {
- phone.notifyDataConnection(reason, apnIdToType(id));
+ mPhone.notifyDataConnection(reason, apnIdToType(id));
}
}
notifyDataAvailability(reason);
}
- // a new APN has gone active and needs to send events to catch up with the current condition
+ // a new APN has gone active and needs to send events to catch up with the
+ // current condition
private void notifyApnIdUpToCurrent(String reason, int apnId) {
- switch (state) {
+ switch (mState) {
case IDLE:
case INITING:
break;
case CONNECTING:
case SCANNING:
- phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
+ mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
break;
case CONNECTED:
case DISCONNECTING:
- phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
- phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTED);
+ mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTING);
+ mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.CONNECTED);
break;
}
}
// since we normally don't send info to a disconnected APN, we need to do this specially
private void notifyApnIdDisconnected(String reason, int apnId) {
- phone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.DISCONNECTED);
+ mPhone.notifyDataConnection(reason, apnIdToType(apnId), Phone.DataState.DISCONNECTED);
}
// disabled apn's still need avail/unavail notificiations - send them out
@@ -526,10 +648,10 @@
* @return {@code true} if data connectivity is possible, {@code false} otherwise.
*/
protected boolean isDataPossible() {
- boolean possible = (isDataAllowed() &&
- !(getDataEnabled() && (state == State.FAILED || state == State.IDLE)));
+ boolean possible = (isDataAllowed()
+ && !(getDataEnabled() && (mState == State.FAILED || mState == State.IDLE)));
if (!possible && DBG && isDataAllowed()) {
- log("Data not possible. No coverage: dataState = " + state);
+ log("Data not possible. No coverage: dataState = " + mState);
}
return possible;
}
@@ -549,13 +671,13 @@
/**
* Ensure that we are connected to an APN of the specified type.
- * @param type the APN type (currently the only valid values
- * are {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
- * @return the result of the operation. Success is indicated by
- * a return value of either {@code Phone.APN_ALREADY_ACTIVE} or
- * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a broadcast
- * will be sent by the ConnectivityManager when a connection to
- * the APN has been established.
+ *
+ * @param type the APN type (currently the only valid values are
+ * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL})
+ * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
+ * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
+ * broadcast will be sent by the ConnectivityManager when a
+ * connection to the APN has been established.
*/
public synchronized int enableApnType(String type) {
int id = apnTypeToId(type);
@@ -564,13 +686,12 @@
}
if (DBG) {
- Log.d(LOG_TAG, "enableApnType(" + type + "), isApnTypeActive = "
- + isApnTypeActive(type) + ", isApnIdEnabled =" + isApnIdEnabled(id) +
- " and state = " + state);
+ log("enableApnType(" + type + "), isApnTypeActive = " + isApnTypeActive(type)
+ + ", isApnIdEnabled =" + isApnIdEnabled(id) + " and state = " + mState);
}
if (!isApnTypeAvailable(type)) {
- if (DBG) Log.d(LOG_TAG, "type not available");
+ if (DBG) log("type not available");
return Phone.APN_TYPE_NOT_AVAILABLE;
}
@@ -583,15 +704,21 @@
}
/**
- * The APN of the specified type is no longer needed. Ensure that if
- * use of the default APN has not been explicitly disabled, we are connected
- * to the default APN.
+ * The APN of the specified type is no longer needed. Ensure that if use of
+ * the default APN has not been explicitly disabled, we are connected to the
+ * default APN.
+ *
* @param type the APN type. The only valid values are currently
- * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
- * @return
+ * {@link Phone#APN_TYPE_MMS} and {@link Phone#APN_TYPE_SUPL}.
+ * @return Success is indicated by {@code Phone.APN_ALREADY_ACTIVE} or
+ * {@code Phone.APN_REQUEST_STARTED}. In the latter case, a
+ * broadcast will be sent by the ConnectivityManager when a
+ * connection to the APN has been disconnected. A {@code
+ * Phone.APN_REQUEST_FAILED} is returned if the type parameter is
+ * invalid or if the apn wasn't enabled.
*/
public synchronized int disableApnType(String type) {
- if (DBG) Log.d(LOG_TAG, "disableApnType("+type+")");
+ if (DBG) log("disableApnType(" + type + ")");
int id = apnTypeToId(type);
if (id == APN_INVALID_ID) {
return Phone.APN_REQUEST_FAILED;
@@ -614,8 +741,8 @@
private void setEnabled(int id, boolean enable) {
if (DBG) {
- Log.d(LOG_TAG, "setEnabled(" + id + ", " + enable + ") with old state = "
- + dataEnabled[id] + " and enabledCount = " + enabledCount);
+ log("setEnabled(" + id + ", " + enable + ") with old state = " + dataEnabled[id]
+ + " and enabledCount = " + enabledCount);
}
Message msg = obtainMessage(EVENT_ENABLE_NEW_APN);
msg.arg1 = id;
@@ -625,9 +752,10 @@
protected synchronized void onEnableApn(int apnId, int enabled) {
if (DBG) {
- Log.d(LOG_TAG, "EVENT_APN_ENABLE_REQUEST " + apnId + ", " + enabled);
- Log.d(LOG_TAG, " dataEnabled = " + dataEnabled[apnId] + ", enabledCount = "
- + enabledCount + ", isApnTypeActive = " + isApnTypeActive(apnIdToType(apnId)));
+ log("EVENT_APN_ENABLE_REQUEST apnId=" + apnId + ", apnType=" + apnIdToType(apnId) +
+ ", enabled=" + enabled + ", dataEnabled = " + dataEnabled[apnId] +
+ ", enabledCount = " + enabledCount + ", isApnTypeActive = " +
+ isApnTypeActive(apnIdToType(apnId)));
}
if (enabled == ENABLED) {
if (!dataEnabled[apnId]) {
@@ -676,18 +804,22 @@
}
/**
- * Prevent mobile data connections from being established,
- * or once again allow mobile data connections. If the state
- * toggles, then either tear down or set up data, as
- * appropriate to match the new state.
- * <p>This operation only affects the default APN, and if the same APN is
- * currently being used for MMS traffic, the teardown will not happen
- * even when {@code enable} is {@code false}.</p>
- * @param enable indicates whether to enable ({@code true}) or disable ({@code false}) data
+ * Prevent mobile data connections from being established, or once again
+ * allow mobile data connections. If the state toggles, then either tear
+ * down or set up data, as appropriate to match the new state.
+ * <p>
+ * This operation only affects the default APN, and if the same APN is
+ * currently being used for MMS traffic, the teardown will not happen even
+ * when {@code enable} is {@code false}.
+ * </p>
+ *
+ * @param enable indicates whether to enable ({@code true}) or disable (
+ * {@code false}) data
* @return {@code true} if the operation succeeded
*/
public boolean setDataEnabled(boolean enable) {
- if (DBG) Log.d(LOG_TAG, "setDataEnabled(" + enable + ")");
+ if (DBG)
+ log("setDataEnabled(" + enable + ")");
Message msg = obtainMessage(EVENT_SET_MASTER_DATA_ENABLE);
msg.arg1 = (enable ? ENABLED : DISABLED);
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
index 95cb1c6..8072c44 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnection.java
@@ -23,6 +23,7 @@
import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.RetryManager;
/**
* {@hide}
@@ -39,23 +40,27 @@
// ***** Constructor
- private CdmaDataConnection(CDMAPhone phone, String name) {
- super(phone, name);
+ private CdmaDataConnection(CDMAPhone phone, String name, RetryManager rm) {
+ super(phone, name, rm);
}
/**
* Create the connection object
*
- * @param phone
+ * @param phone the Phone
+ * @param id the connection id
+ * @param rm the RetryManager
* @return CdmaDataConnection that was created.
*/
- static CdmaDataConnection makeDataConnection(CDMAPhone phone) {
+ static CdmaDataConnection makeDataConnection(CDMAPhone phone, int id, RetryManager rm) {
synchronized (mCountLock) {
mCount += 1;
}
- CdmaDataConnection cdmaDc = new CdmaDataConnection(phone, "CdmaDataConnection-" + mCount);
+ CdmaDataConnection cdmaDc = new CdmaDataConnection(phone,
+ "CdmaDataConnection-" + mCount, rm);
cdmaDc.start();
if (DBG) cdmaDc.log("Made " + cdmaDc.getName());
+ cdmaDc.mId = id;
return cdmaDc;
}
diff --git a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
index e499e95..7c652c5 100644
--- a/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/cdma/CdmaDataConnectionTracker.java
@@ -18,21 +18,13 @@
import android.app.AlarmManager;
import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
-import android.net.IConnectivityManager;
-import android.net.NetworkInfo;
import android.net.TrafficStats;
-import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Message;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.preference.PreferenceManager;
import android.telephony.ServiceState;
import android.telephony.TelephonyManager;
import android.telephony.cdma.CdmaCellLocation;
@@ -46,6 +38,7 @@
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.DataConnectionTracker;
import com.android.internal.telephony.EventLogTags;
+import com.android.internal.telephony.RetryManager;
import com.android.internal.telephony.gsm.ApnSetting;
import com.android.internal.telephony.Phone;
@@ -59,20 +52,11 @@
private CDMAPhone mCdmaPhone;
- // Indicates baseband will not auto-attach
- private boolean noAutoAttach = false;
- private boolean mIsScreenOn = true;
-
//useful for debugging
- boolean failNextConnect = false;
+ boolean mFailNextConnect = false;
- /**
- * dataConnectionList holds all the Data connection
- */
- private ArrayList<DataConnection> dataConnectionList;
-
- /** Currently active CdmaDataConnection */
- private CdmaDataConnection mActiveDataConnection;
+ /** The DataConnection being setup */
+ private CdmaDataConnection mPendingDataConnection;
private boolean mPendingRestartRadio = false;
private static final int TIME_DELAYED_TO_RESTART_RADIO =
@@ -83,10 +67,8 @@
*/
private static final int DATA_CONNECTION_POOL_SIZE = 1;
- private static final int POLL_CONNECTION_MILLIS = 5 * 1000;
private static final String INTENT_RECONNECT_ALARM =
- "com.android.internal.telephony.cdma-reconnect";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
+ "com.android.internal.telephony.cdma-reconnect";
/**
* Constants for the data connection activity:
@@ -110,49 +92,6 @@
// if we have no active Apn this is null
protected ApnSetting mActiveApn;
- // Possibly promote to base class, the only difference is
- // the INTENT_RECONNECT_ALARM action is a different string.
- // Do consider technology changes if it is promoted.
- BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_SCREEN_ON)) {
- mIsScreenOn = true;
- stopNetStatPoll();
- startNetStatPoll();
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- mIsScreenOn = false;
- stopNetStatPoll();
- startNetStatPoll();
- } else if (action.equals((INTENT_RECONNECT_ALARM))) {
- Log.d(LOG_TAG, "Data reconnect alarm. Previous state was " + state);
-
- String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
- if (state == State.FAILED) {
- cleanUpConnection(false, reason);
- }
- trySetupData(reason);
- } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- final android.net.NetworkInfo networkInfo = (NetworkInfo)
- intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
- } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
- WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
- if (!enabled) {
- // when wifi got disabeled, the NETWORK_STATE_CHANGED_ACTION
- // quit and wont report disconnected til next enalbing.
- mIsWifiConnected = false;
- }
- }
- }
- };
-
-
/* Constructor */
CdmaDataConnectionTracker(CDMAPhone p) {
@@ -172,79 +111,49 @@
p.mSST.registerForRoamingOff(this, EVENT_ROAMING_OFF, null);
p.mCM.registerForCdmaOtaProvision(this, EVENT_CDMA_OTA_PROVISION, null);
- IntentFilter filter = new IntentFilter();
- filter.addAction(INTENT_RECONNECT_ALARM);
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-
- // TODO: Why is this registering the phone as the receiver of the intent
- // and not its own handler?
- p.getContext().registerReceiver(mIntentReceiver, filter, null, p);
-
mDataConnectionTracker = this;
createAllDataConnectionList();
-
- // This preference tells us 1) initial condition for "dataEnabled",
- // and 2) whether the RIL will setup the baseband to auto-PS attach.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext());
-
- boolean dataEnabledSetting = true;
- try {
- dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager.
- getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled();
- } catch (Exception e) {
- // nothing to do - use the old behavior and leave data on
- }
- dataEnabled[APN_DEFAULT_ID] =
- !sp.getBoolean(CDMAPhone.DATA_DISABLED_ON_BOOT_KEY, false) &&
- dataEnabledSetting;
- if (dataEnabled[APN_DEFAULT_ID]) {
- enabledCount++;
- }
- noAutoAttach = !dataEnabled[APN_DEFAULT_ID];
-
- if (!mRetryMgr.configure(SystemProperties.get("ro.cdma.data_retry_config"))) {
- if (!mRetryMgr.configure(DEFAULT_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple linear sequence.
- Log.e(LOG_TAG, "Could not configure using DEFAULT_DATA_RETRY_CONFIG="
- + DEFAULT_DATA_RETRY_CONFIG);
- mRetryMgr.configure(20, 2000, 1000);
- }
- }
}
+ @Override
public void dispose() {
+ super.dispose();
+
// Unregister from all events
- phone.mCM.unregisterForAvailable(this);
- phone.mCM.unregisterForOffOrNotAvailable(this);
+ mPhone.mCM.unregisterForAvailable(this);
+ mPhone.mCM.unregisterForOffOrNotAvailable(this);
mCdmaPhone.mRuimRecords.unregisterForRecordsLoaded(this);
- phone.mCM.unregisterForNVReady(this);
- phone.mCM.unregisterForDataStateChanged(this);
+ mPhone.mCM.unregisterForNVReady(this);
+ mPhone.mCM.unregisterForDataStateChanged(this);
mCdmaPhone.mCT.unregisterForVoiceCallEnded(this);
mCdmaPhone.mCT.unregisterForVoiceCallStarted(this);
mCdmaPhone.mSST.unregisterForCdmaDataConnectionAttached(this);
mCdmaPhone.mSST.unregisterForCdmaDataConnectionDetached(this);
mCdmaPhone.mSST.unregisterForRoamingOn(this);
mCdmaPhone.mSST.unregisterForRoamingOff(this);
- phone.mCM.unregisterForCdmaOtaProvision(this);
+ mPhone.mCM.unregisterForCdmaOtaProvision(this);
- phone.getContext().unregisterReceiver(this.mIntentReceiver);
destroyAllDataConnectionList();
}
+ @Override
protected void finalize() {
- if(DBG) Log.d(LOG_TAG, "CdmaDataConnectionTracker finalized");
+ if(DBG) log("CdmaDataConnectionTracker finalized");
}
+ @Override
+ protected String getActionIntentReconnectAlarm() {
+ return INTENT_RECONNECT_ALARM;
+ }
+
+ @Override
protected void setState(State s) {
if (DBG) log ("setState: " + s);
- if (state != s) {
+ if (mState != s) {
EventLog.writeEvent(EventLogTags.CDMA_DATA_STATE_CHANGE,
- state.toString(), s.toString());
- state = s;
+ mState.toString(), s.toString());
+ mState = s;
}
}
@@ -263,6 +172,7 @@
return false;
}
+ @Override
protected String[] getActiveApnTypes() {
String[] result;
if (mActiveApn != null) {
@@ -274,6 +184,7 @@
return result;
}
+ @Override
protected String getActiveApnString() {
return null;
}
@@ -287,45 +198,51 @@
*
* @return false while no data connection if all above requirements are met.
*/
+ @Override
public boolean isDataConnectionAsDesired() {
- boolean roaming = phone.getServiceState().getRoaming();
+ boolean roaming = mPhone.getServiceState().getRoaming();
- if (((phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) ||
+ if (((mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY) ||
mCdmaPhone.mRuimRecords.getRecordsLoaded()) &&
(mCdmaPhone.mSST.getCurrentCdmaDataConnectionState() ==
ServiceState.STATE_IN_SERVICE) &&
(!roaming || getDataOnRoamingEnabled()) &&
!mIsWifiConnected ) {
- return (state == State.CONNECTED);
+ return (mState == State.CONNECTED);
}
return true;
}
+ @Override
protected boolean isDataAllowed() {
int psState = mCdmaPhone.mSST.getCurrentCdmaDataConnectionState();
- boolean roaming = (phone.getServiceState().getRoaming() && !getDataOnRoamingEnabled());
+ boolean roaming = (mPhone.getServiceState().getRoaming() && !getDataOnRoamingEnabled());
boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
- boolean allowed = (psState == ServiceState.STATE_IN_SERVICE &&
- (phone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY ||
- mCdmaPhone.mRuimRecords.getRecordsLoaded()) &&
- (mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
- phone.getState() == Phone.State.IDLE) &&
- !roaming &&
- mMasterDataEnabled &&
- desiredPowerState &&
- !mPendingRestartRadio &&
- !mCdmaPhone.needsOtaServiceProvisioning());
+ boolean allowed =
+ (psState == ServiceState.STATE_IN_SERVICE ||
+ mAutoAttachOnCreation) &&
+ (mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY ||
+ mCdmaPhone.mRuimRecords.getRecordsLoaded()) &&
+ (mCdmaPhone.mSST.isConcurrentVoiceAndData() ||
+ mPhone.getState() == Phone.State.IDLE) &&
+ !roaming &&
+ mMasterDataEnabled &&
+ desiredPowerState &&
+ !mPendingRestartRadio &&
+ !mCdmaPhone.needsOtaServiceProvisioning();
if (!allowed && DBG) {
String reason = "";
- if (psState != ServiceState.STATE_IN_SERVICE) reason += " - psState= " + psState;
- if (phone.mCM.getRadioState() != CommandsInterface.RadioState.NV_READY &&
- !mCdmaPhone.mRuimRecords.getRecordsLoaded()) {
- reason += " - radioState= " + phone.mCM.getRadioState() + " - RUIM not loaded";
+ if (!((psState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
+ reason += " - psState= " + psState;
}
- if (phone.getState() != Phone.State.IDLE &&
+ if (!(mPhone.mCM.getRadioState() == CommandsInterface.RadioState.NV_READY ||
+ mCdmaPhone.mRuimRecords.getRecordsLoaded())) {
+ reason += " - radioState= " + mPhone.mCM.getRadioState() + " - RUIM not loaded";
+ }
+ if (mPhone.getState() != Phone.State.IDLE &&
mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
- reason += " - concurrentVoiceAndData not allowed and state= " + phone.getState();
+ reason += " - concurrentVoiceAndData not allowed and state= " + mPhone.getState();
}
if (roaming) reason += " - Roaming";
if (!mMasterDataEnabled) reason += " - mMasterDataEnabled= false";
@@ -340,22 +257,22 @@
private boolean trySetupData(String reason) {
if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
setState(State.CONNECTED);
notifyDataConnection(reason);
notifyOffApnsOfAvailability(reason, true);
- Log.i(LOG_TAG, "(fix?) We're on the simulator; assuming data is connected");
+ log("(fix?) We're on the simulator; assuming data is connected");
return true;
}
int psState = mCdmaPhone.mSST.getCurrentCdmaDataConnectionState();
- boolean roaming = phone.getServiceState().getRoaming();
+ boolean roaming = mPhone.getServiceState().getRoaming();
boolean desiredPowerState = mCdmaPhone.mSST.getDesiredPowerState();
- if ((state == State.IDLE || state == State.SCANNING) &&
+ if ((mState == State.IDLE || mState == State.SCANNING) &&
isDataAllowed() && getAnyDataEnabled()) {
boolean retValue = setupData(reason);
notifyOffApnsOfAvailability(reason, retValue);
@@ -367,13 +284,12 @@
}
/**
- * If tearDown is true, this only tears down a CONNECTED session. Presently,
- * there is no mechanism for abandoning an INITING/CONNECTING session,
- * but would likely involve cancelling pending async requests or
- * setting a flag or new state to ignore them when they came in
- * @param tearDown true if the underlying DataConnection should be
- * disconnected.
- * @param reason reason for the clean up.
+ * Cleanup all connections.
+ *
+ * TODO: Cleanup only a specified connection passed as a parameter.
+ *
+ * @param tearDown true if the underlying DataConnection should be disconnected.
+ * @param reason for the clean up.
*/
private void cleanUpConnection(boolean tearDown, String reason) {
if (DBG) log("cleanUpConnection: reason: " + reason);
@@ -381,7 +297,7 @@
// Clear the reconnect alarm, if set.
if (mReconnectIntent != null) {
AlarmManager am =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
am.cancel(mReconnectIntent);
mReconnectIntent = null;
}
@@ -390,11 +306,12 @@
notifyDataAvailability(reason);
boolean notificationDeferred = false;
- for (DataConnection conn : dataConnectionList) {
+ for (DataConnection conn : mDataConnections.values()) {
if(conn != null) {
if (tearDown) {
if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
- conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE, reason));
+ conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE,
+ conn.getDataConnectionId(), 0, reason));
notificationDeferred = true;
} else {
if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
@@ -413,10 +330,9 @@
}
private CdmaDataConnection findFreeDataConnection() {
- for (DataConnection connBase : dataConnectionList) {
- CdmaDataConnection conn = (CdmaDataConnection) connBase;
- if (conn.isInactive()) {
- return conn;
+ for (DataConnection dc : mDataConnections.values()) {
+ if (dc.isInactive()) {
+ return (CdmaDataConnection) dc;
}
}
return null;
@@ -430,7 +346,8 @@
return false;
}
- mActiveDataConnection = conn;
+ /** TODO: We probably want the connection being setup to a parameter passed around */
+ mPendingDataConnection = conn;
String[] types;
if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) {
types = new String[1];
@@ -458,28 +375,31 @@
}
private void resetPollStats() {
- txPkts = -1;
- rxPkts = -1;
- sentSinceLastRecv = 0;
- netStatPollPeriod = POLL_NETSTAT_MILLIS;
+ mTxPkts = -1;
+ mRxPkts = -1;
+ mSentSinceLastRecv = 0;
+ mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
mNoRecvPollCount = 0;
}
+ @Override
protected void startNetStatPoll() {
- if (state == State.CONNECTED && netStatPollEnabled == false) {
- Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
+ if (mState == State.CONNECTED && mNetStatPollEnabled == false) {
+ log("[DataConnection] Start poll NetStat");
resetPollStats();
- netStatPollEnabled = true;
+ mNetStatPollEnabled = true;
mPollNetStat.run();
}
}
+ @Override
protected void stopNetStatPoll() {
- netStatPollEnabled = false;
+ mNetStatPollEnabled = false;
removeCallbacks(mPollNetStat);
- Log.d(LOG_TAG, "[DataConnection] Stop poll NetStat");
+ log("[DataConnection] Stop poll NetStat");
}
+ @Override
protected void restartRadio() {
if (DBG) log("Cleanup connection and wait " +
(TIME_DELAYED_TO_RESTART_RADIO / 1000) + "s to restart radio");
@@ -496,73 +416,73 @@
Activity newActivity;
- preTxPkts = txPkts;
- preRxPkts = rxPkts;
+ preTxPkts = mTxPkts;
+ preRxPkts = mRxPkts;
- txPkts = TrafficStats.getMobileTxPackets();
- rxPkts = TrafficStats.getMobileRxPackets();
+ mTxPkts = TrafficStats.getMobileTxPackets();
+ mRxPkts = TrafficStats.getMobileRxPackets();
- //Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
+ //log("rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
- if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
- sent = txPkts - preTxPkts;
- received = rxPkts - preRxPkts;
+ if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
+ sent = mTxPkts - preTxPkts;
+ received = mRxPkts - preRxPkts;
if ( sent > 0 && received > 0 ) {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.DATAINANDOUT;
} else if (sent > 0 && received == 0) {
- if (phone.getState() == Phone.State.IDLE) {
- sentSinceLastRecv += sent;
+ if (mPhone.getState() == Phone.State.IDLE) {
+ mSentSinceLastRecv += sent;
} else {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
}
newActivity = Activity.DATAOUT;
} else if (sent == 0 && received > 0) {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.DATAIN;
} else if (sent == 0 && received == 0) {
- newActivity = (activity == Activity.DORMANT) ? activity : Activity.NONE;
+ newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE;
} else {
- sentSinceLastRecv = 0;
- newActivity = (activity == Activity.DORMANT) ? activity : Activity.NONE;
+ mSentSinceLastRecv = 0;
+ newActivity = (mActivity == Activity.DORMANT) ? mActivity : Activity.NONE;
}
- if (activity != newActivity) {
- activity = newActivity;
- phone.notifyDataActivity();
+ if (mActivity != newActivity && mIsScreenOn) {
+ mActivity = newActivity;
+ mPhone.notifyDataActivity();
}
}
- if (sentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
+ if (mSentSinceLastRecv >= NUMBER_SENT_PACKETS_OF_HANG) {
// Packets sent without ack exceeded threshold.
if (mNoRecvPollCount == 0) {
EventLog.writeEvent(
EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED,
- sentSinceLastRecv);
+ mSentSinceLastRecv);
}
if (mNoRecvPollCount < NO_RECV_POLL_LIMIT) {
mNoRecvPollCount++;
// Slow down the poll interval to let things happen
- netStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS;
+ mNetStatPollPeriod = POLL_NETSTAT_SLOW_MILLIS;
} else {
- if (DBG) log("Sent " + String.valueOf(sentSinceLastRecv) +
+ if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) +
" pkts since last received");
// We've exceeded the threshold. Restart the radio.
- netStatPollEnabled = false;
+ mNetStatPollEnabled = false;
stopNetStatPoll();
restartRadio();
EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, NO_RECV_POLL_LIMIT);
}
} else {
mNoRecvPollCount = 0;
- netStatPollPeriod = POLL_NETSTAT_MILLIS;
+ mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
}
- if (netStatPollEnabled) {
- mDataConnectionTracker.postDelayed(this, netStatPollPeriod);
+ if (mNetStatPollEnabled) {
+ mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
}
}
};
@@ -594,7 +514,7 @@
}
private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
/**
* For now With CDMA we never try to reconnect on
* error and instead just continue to retry
@@ -602,15 +522,15 @@
* TODO: Make this configurable?
*/
int nextReconnectDelay = mRetryMgr.getRetryTimer();
- Log.d(LOG_TAG, "Data Connection activate failed. Scheduling next attempt for "
+ log("Data Connection activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
AlarmManager am =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(INTENT_RECONNECT_ALARM);
intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
mReconnectIntent = PendingIntent.getBroadcast(
- phone.getContext(), 0, intent, 0);
+ mPhone.getContext(), 0, intent, 0);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + nextReconnectDelay,
mReconnectIntent);
@@ -618,7 +538,7 @@
mRetryMgr.increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
- Log.d(LOG_TAG,"NOT Posting Data Connection Unavailable notification "
+ log("NOT Posting Data Connection Unavailable notification "
+ "-- likely transient error");
} else {
notifyNoData(lastFailCauseCode);
@@ -639,14 +559,14 @@
}
protected void onRecordsLoaded() {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, null);
}
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
}
protected void onNVReady() {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, null);
}
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
@@ -657,12 +577,13 @@
*/
@Override
protected void onEnableNewApn() {
- cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
+ cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
}
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected boolean onTrySetupData(String reason) {
return trySetupData(reason);
}
@@ -670,6 +591,7 @@
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onRoamingOff() {
trySetupData(Phone.REASON_ROAMING_OFF);
}
@@ -677,6 +599,7 @@
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onRoamingOn() {
if (getDataOnRoamingEnabled()) {
trySetupData(Phone.REASON_ROAMING_ON);
@@ -689,19 +612,20 @@
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onRadioAvailable() {
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
setState(State.CONNECTED);
notifyDataConnection(null);
- Log.i(LOG_TAG, "We're on the simulator; assuming data is connected");
+ log("We're on the simulator; assuming data is connected");
}
notifyDataAvailability(null);
- if (state != State.IDLE) {
+ if (mState != State.IDLE) {
cleanUpConnection(true, null);
}
}
@@ -709,13 +633,14 @@
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onRadioOffOrNotAvailable() {
mRetryMgr.resetRetryCount();
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
- Log.i(LOG_TAG, "We're on the simulator; assuming radio off is meaningless");
+ log("We're on the simulator; assuming radio off is meaningless");
} else {
if (DBG) log("Radio is off and clean up all connection");
cleanUpConnection(false, Phone.REASON_RADIO_TURNED_OFF);
@@ -725,6 +650,7 @@
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onDataSetupComplete(AsyncResult ar) {
String reason = null;
if (ar.userObj instanceof String) {
@@ -733,8 +659,8 @@
if (ar.exception == null) {
// TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
- mLinkProperties = getLinkProperties(mActiveDataConnection);
- mLinkCapabilities = getLinkCapabilities(mActiveDataConnection);
+ mLinkProperties = getLinkProperties(mPendingDataConnection);
+ mLinkCapabilities = getLinkCapabilities(mPendingDataConnection);
// everything is setup
notifyDefaultData(reason);
@@ -754,8 +680,9 @@
/**
* Called when EVENT_DISCONNECT_DONE is received.
*/
- protected void onDisconnectDone(AsyncResult ar) {
- if(DBG) log("EVENT_DISCONNECT_DONE");
+ @Override
+ protected void onDisconnectDone(int connId, AsyncResult ar) {
+ if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
String reason = null;
if (ar.userObj instanceof String) {
reason = (String) ar.userObj;
@@ -799,8 +726,9 @@
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onVoiceCallStarted() {
- if (state == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
+ if (mState == State.CONNECTED && !mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
stopNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
notifyDataAvailability(Phone.REASON_VOICE_CALL_STARTED);
@@ -810,8 +738,9 @@
/**
* @override com.android.internal.telephony.DataConnectionTracker
*/
+ @Override
protected void onVoiceCallEnded() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
if (!mCdmaPhone.mSST.isConcurrentVoiceAndData()) {
startNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
@@ -827,39 +756,49 @@
}
}
- /**
- * @override com.android.internal.telephony.DataConnectionTracker
- */
+ @Override
protected void onCleanUpConnection(boolean tearDown, String reason) {
cleanUpConnection(tearDown, reason);
}
private void createAllDataConnectionList() {
- dataConnectionList = new ArrayList<DataConnection>();
CdmaDataConnection dataConn;
- for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
- dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone);
- dataConnectionList.add(dataConn);
- }
+ /** TODO: Use one retry manager for all connections for now */
+ RetryManager rm = mRetryMgr;
+ if (!rm.configure(SystemProperties.get("ro.cdma.data_retry_config"))) {
+ if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
+ // Should never happen, log an error and default to a simple linear sequence.
+ log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
+ + DEFAULT_DATA_RETRY_CONFIG);
+ rm.configure(20, 2000, 1000);
+ }
+ }
+
+ for (int i = 0; i < DATA_CONNECTION_POOL_SIZE; i++) {
+ int id = mUniqueIdGenerator.getAndIncrement();
+
+ dataConn = CdmaDataConnection.makeDataConnection(mCdmaPhone, id, rm);
+ mDataConnections.put(id, dataConn);
+ }
}
private void destroyAllDataConnectionList() {
- if(dataConnectionList != null) {
- dataConnectionList.removeAll(dataConnectionList);
+ if(mDataConnections != null) {
+ mDataConnections.clear();
}
}
private void onCdmaDataDetached() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
startNetStatPoll();
notifyDataConnection(Phone.REASON_CDMA_DATA_DETACHED);
} else {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, Phone.REASON_CDMA_DATA_DETACHED);
mRetryMgr.resetRetryCount();
- CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
+ CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.CDMA_DATA_SETUP_FAILED,
loc != null ? loc.getBaseStationId() : -1,
TelephonyManager.getDefault().getNetworkType());
@@ -886,8 +825,8 @@
private void onRestartRadio() {
if (mPendingRestartRadio) {
- Log.d(LOG_TAG, "************TURN OFF RADIO**************");
- phone.mCM.setRadioPower(false, null);
+ log("************TURN OFF RADIO**************");
+ mPhone.mCM.setRadioPower(false, null);
/* Note: no need to call setRadioPower(true). Assuming the desired
* radio power state is still ON (as tracked by ServiceStateTracker),
* ServiceStateTracker will call setRadioPower when it receives the
@@ -900,7 +839,7 @@
}
private void writeEventLogCdmaDataDrop() {
- CdmaCellLocation loc = (CdmaCellLocation)(phone.getCellLocation());
+ CdmaCellLocation loc = (CdmaCellLocation)(mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.CDMA_DATA_DROP,
loc != null ? loc.getBaseStationId() : -1,
TelephonyManager.getDefault().getNetworkType());
@@ -916,7 +855,7 @@
return;
}
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
boolean isActiveOrDormantConnectionPresent = false;
int connectionState = DATA_CONNECTION_ACTIVE_PH_LINK_INACTIVE;
@@ -932,7 +871,7 @@
if (!isActiveOrDormantConnectionPresent) {
// No active or dormant connection
- Log.i(LOG_TAG, "onDataStateChanged: No active connection"
+ log("onDataStateChanged: No active connection"
+ "state is CONNECTED, disconnecting/cleanup");
writeEventLogCdmaDataDrop();
cleanUpConnection(true, null);
@@ -941,42 +880,39 @@
switch (connectionState) {
case DATA_CONNECTION_ACTIVE_PH_LINK_UP:
- Log.v(LOG_TAG, "onDataStateChanged: active=LINK_ACTIVE && CONNECTED, ignore");
- activity = Activity.NONE;
- phone.notifyDataActivity();
+ log("onDataStateChanged: active=LINK_ACTIVE && CONNECTED, ignore");
+ mActivity = Activity.NONE;
+ mPhone.notifyDataActivity();
startNetStatPoll();
break;
case DATA_CONNECTION_ACTIVE_PH_LINK_DOWN:
- Log.v(LOG_TAG, "onDataStateChanged active=LINK_DOWN && CONNECTED, dormant");
- activity = Activity.DORMANT;
- phone.notifyDataActivity();
+ log("onDataStateChanged active=LINK_DOWN && CONNECTED, dormant");
+ mActivity = Activity.DORMANT;
+ mPhone.notifyDataActivity();
stopNetStatPoll();
break;
default:
- Log.v(LOG_TAG, "onDataStateChanged: IGNORE unexpected DataCallState.active="
+ log("onDataStateChanged: IGNORE unexpected DataCallState.active="
+ connectionState);
}
} else {
// TODO: Do we need to do anything?
- Log.i(LOG_TAG, "onDataStateChanged: not connected, state=" + state + " ignoring");
+ log("onDataStateChanged: not connected, state=" + mState + " ignoring");
}
}
- public ArrayList<DataConnection> getAllDataConnections() {
- return dataConnectionList;
- }
-
private void startDelayedRetry(FailCause cause, String reason) {
notifyNoData(cause);
reconnectAfterFail(cause, reason);
}
+ @Override
public void handleMessage (Message msg) {
- if (!phone.mIsTheCurrentActivePhone) {
- Log.d(LOG_TAG, "Ignore CDMA msgs since CDMA phone is inactive");
+ if (!mPhone.mIsTheCurrentActivePhone) {
+ log("Ignore CDMA msgs since CDMA phone is inactive");
return;
}
@@ -1013,7 +949,13 @@
}
}
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[CdmaDataConnectionTracker] " + s);
}
+
+ @Override
+ protected void loge(String s) {
+ Log.e(LOG_TAG, "[CdmaDataConnectionTracker] " + s);
+ }
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
index 1572f09..d428099 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnection.java
@@ -23,6 +23,7 @@
import com.android.internal.telephony.DataConnection;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.RILConstants;
+import com.android.internal.telephony.RetryManager;
/**
* {@hide}
@@ -53,23 +54,27 @@
private ApnSetting apn;
//***** Constructor
- private GsmDataConnection(GSMPhone phone, String name) {
- super(phone, name);
+ private GsmDataConnection(GSMPhone phone, String name, RetryManager rm) {
+ super(phone, name, rm);
}
/**
* Create the connection object
*
- * @param phone
+ * @param phone the Phone
+ * @param id the connection id
+ * @param rm the RetryManager
* @return GsmDataConnection that was created.
*/
- static GsmDataConnection makeDataConnection(GSMPhone phone) {
+ static GsmDataConnection makeDataConnection(GSMPhone phone, int id, RetryManager rm) {
synchronized (mCountLock) {
mCount += 1;
}
- GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount);
+ GsmDataConnection gsmDc = new GsmDataConnection(phone, "GsmDataConnection-" + mCount, rm);
gsmDc.start();
if (DBG) gsmDc.log("Made " + gsmDc.getName());
+ gsmDc.mId = id;
+ gsmDc.mRetryMgr = rm;
return gsmDc;
}
diff --git a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
index 66da6e8..2aca9ad 100644
--- a/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
+++ b/telephony/java/com/android/internal/telephony/gsm/GsmDataConnectionTracker.java
@@ -18,27 +18,19 @@
import android.app.AlarmManager;
import android.app.PendingIntent;
-import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.SharedPreferences;
import android.database.ContentObserver;
import android.database.Cursor;
-import android.net.IConnectivityManager;
-import android.net.NetworkInfo;
import android.net.ProxyProperties;
import android.net.TrafficStats;
import android.net.Uri;
-import android.net.wifi.WifiManager;
import android.os.AsyncResult;
import android.os.Message;
-import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.SystemProperties;
-import android.preference.PreferenceManager;
import android.provider.Settings;
import android.provider.Telephony;
import android.telephony.ServiceState;
@@ -61,6 +53,7 @@
import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
+import java.util.HashMap;
/**
* {@hide}
@@ -85,9 +78,6 @@
//***** Instance Variables
- // Indicates baseband will not auto-attach
- private boolean noAutoAttach = false;
-
private boolean mReregisterOnReconnectFailure = false;
private ContentResolver mResolver;
@@ -95,13 +85,12 @@
// Count of PDP reset attempts; reset when we see incoming,
// call reRegisterNetwork, or pingTest succeeds.
private int mPdpResetCount = 0;
- private boolean mIsScreenOn = true;
/** Delay between APN attempts */
protected static final int APN_DELAY_MILLIS = 5000;
//useful for debugging
- boolean failNextConnect = false;
+ boolean mFailNextConnect = false;
/**
* allApns holds all apns for this sim spn, retrieved from
@@ -109,104 +98,49 @@
*
* Create once after simcard info is loaded
*/
- private ArrayList<ApnSetting> allApns = null;
+ private ArrayList<ApnSetting> mAllApns = null;
/**
* waitingApns holds all apns that are waiting to be connected
*
* It is a subset of allApns and has the same format
*/
- private ArrayList<ApnSetting> waitingApns = null;
+ private ArrayList<ApnSetting> mWaitingApns = null;
- private ApnSetting preferredApn = null;
+ private ApnSetting mPreferredApn = null;
/* Currently active APN */
protected ApnSetting mActiveApn;
- /**
- * pdpList holds all the PDP connection, i.e. IP Link in GPRS
- */
- private ArrayList<DataConnection> pdpList;
+ /** The DataConnection being setup */
+ private GsmDataConnection mPendingDataConnection;
- /** Currently active DataConnection */
- private GsmDataConnection mActivePdp;
+ /** Convert an ApnType string to Id (TODO: Use "enumeration" instead of String for ApnType) */
+ private HashMap<String, Integer> mApnToDataConnectionId =
+ new HashMap<String, Integer>();
/** Is packet service restricted by network */
private boolean mIsPsRestricted = false;
//***** Constants
- // TODO: Increase this to match the max number of simultaneous
- // PDP contexts we plan to support.
- /**
- * Pool size of DataConnection objects.
- */
- private static final int PDP_CONNECTION_POOL_SIZE = 1;
-
private static final int POLL_PDP_MILLIS = 5 * 1000;
private static final String INTENT_RECONNECT_ALARM = "com.android.internal.telephony.gprs-reconnect";
- private static final String INTENT_RECONNECT_ALARM_EXTRA_REASON = "reason";
static final Uri PREFERAPN_URI = Uri.parse("content://telephony/carriers/preferapn");
static final String APN_ID = "apn_id";
private boolean canSetPreferApn = false;
- // for tracking retries on the default APN
- private RetryManager mDefaultRetryManager;
- // for tracking retries on a secondary APN
- private RetryManager mSecondaryRetryManager;
-
- BroadcastReceiver mIntentReceiver = new BroadcastReceiver ()
- {
- @Override
- public void onReceive(Context context, Intent intent)
- {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_SCREEN_ON)) {
- mIsScreenOn = true;
- stopNetStatPoll();
- startNetStatPoll();
- } else if (action.equals(Intent.ACTION_SCREEN_OFF)) {
- mIsScreenOn = false;
- stopNetStatPoll();
- startNetStatPoll();
- } else if (action.equals((INTENT_RECONNECT_ALARM))) {
- Log.d(LOG_TAG, "GPRS reconnect alarm. Previous state was " + state);
-
- String reason = intent.getStringExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON);
- if (state == State.FAILED) {
- Message msg = obtainMessage(EVENT_CLEAN_UP_CONNECTION);
- msg.arg1 = 0; // tearDown is false
- msg.obj = (String) reason;
- sendMessage(msg);
- }
- sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA));
- } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) {
- final android.net.NetworkInfo networkInfo = (NetworkInfo)
- intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
- mIsWifiConnected = (networkInfo != null && networkInfo.isConnected());
- } else if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) {
- final boolean enabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
- WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED;
-
- if (!enabled) {
- // when wifi got disabled, the NETWORK_STATE_CHANGED_ACTION
- // quit and won't report disconnected til next enabling.
- mIsWifiConnected = false;
- }
- }
- }
- };
-
/** Watches for changes to the APN db. */
- private ApnChangeObserver apnObserver;
+ private ApnChangeObserver mApnObserver;
//***** Constructor
GsmDataConnectionTracker(GSMPhone p) {
super(p);
mGsmPhone = p;
+
p.mCM.registerForAvailable (this, EVENT_RADIO_AVAILABLE, null);
p.mCM.registerForOffOrNotAvailable(this, EVENT_RADIO_OFF_OR_NOT_AVAILABLE, null);
p.mSIMRecords.registerForRecordsLoaded(this, EVENT_RECORDS_LOADED, null);
@@ -220,73 +154,26 @@
p.mSST.registerForPsRestrictedEnabled(this, EVENT_PS_RESTRICT_ENABLED, null);
p.mSST.registerForPsRestrictedDisabled(this, EVENT_PS_RESTRICT_DISABLED, null);
- IntentFilter filter = new IntentFilter();
- filter.addAction(INTENT_RECONNECT_ALARM);
- filter.addAction(Intent.ACTION_SCREEN_ON);
- filter.addAction(Intent.ACTION_SCREEN_OFF);
- filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
- filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
-
- // TODO: Why is this registering the phone as the receiver of the intent
- // and not its own handler?
- p.getContext().registerReceiver(mIntentReceiver, filter, null, p);
-
-
mDataConnectionTracker = this;
- mResolver = phone.getContext().getContentResolver();
+ mResolver = mPhone.getContext().getContentResolver();
- apnObserver = new ApnChangeObserver();
+ mApnObserver = new ApnChangeObserver();
p.getContext().getContentResolver().registerContentObserver(
- Telephony.Carriers.CONTENT_URI, true, apnObserver);
+ Telephony.Carriers.CONTENT_URI, true, mApnObserver);
- createAllPdpList();
-
- // This preference tells us 1) initial condition for "dataEnabled",
- // and 2) whether the RIL will setup the baseband to auto-PS attach.
- SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(phone.getContext());
- boolean dataEnabledSetting = true;
- try {
- dataEnabledSetting = IConnectivityManager.Stub.asInterface(ServiceManager.
- getService(Context.CONNECTIVITY_SERVICE)).getMobileDataEnabled();
- } catch (Exception e) {
- // nothing to do - use the old behavior and leave data on
- }
- dataEnabled[APN_DEFAULT_ID] = !sp.getBoolean(GSMPhone.DATA_DISABLED_ON_BOOT_KEY, false) &&
- dataEnabledSetting;
- if (dataEnabled[APN_DEFAULT_ID]) {
- enabledCount++;
- }
- noAutoAttach = !dataEnabled[APN_DEFAULT_ID];
-
- if (!mRetryMgr.configure(SystemProperties.get("ro.gsm.data_retry_config"))) {
- if (!mRetryMgr.configure(DEFAULT_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple linear sequence.
- Log.e(LOG_TAG, "Could not configure using DEFAULT_DATA_RETRY_CONFIG="
- + DEFAULT_DATA_RETRY_CONFIG);
- mRetryMgr.configure(20, 2000, 1000);
- }
- }
-
- mDefaultRetryManager = mRetryMgr;
- mSecondaryRetryManager = new RetryManager();
-
- if (!mSecondaryRetryManager.configure(SystemProperties.get(
- "ro.gsm.2nd_data_retry_config"))) {
- if (!mSecondaryRetryManager.configure(SECONDARY_DATA_RETRY_CONFIG)) {
- // Should never happen, log an error and default to a simple sequence.
- Log.e(LOG_TAG, "Could note configure using SECONDARY_DATA_RETRY_CONFIG="
- + SECONDARY_DATA_RETRY_CONFIG);
- mSecondaryRetryManager.configure("max_retries=3, 333, 333, 333");
- }
- }
+ /** Create the default connection */
+ createDataConnection(Phone.APN_TYPE_DEFAULT);
}
+ @Override
public void dispose() {
+ super.dispose();
+
//Unregister for all events
- phone.mCM.unregisterForAvailable(this);
- phone.mCM.unregisterForOffOrNotAvailable(this);
+ mPhone.mCM.unregisterForAvailable(this);
+ mPhone.mCM.unregisterForOffOrNotAvailable(this);
mGsmPhone.mSIMRecords.unregisterForRecordsLoaded(this);
- phone.mCM.unregisterForDataStateChanged(this);
+ mPhone.mCM.unregisterForDataStateChanged(this);
mGsmPhone.mCT.unregisterForVoiceCallEnded(this);
mGsmPhone.mCT.unregisterForVoiceCallStarted(this);
mGsmPhone.mSST.unregisterForGprsAttached(this);
@@ -296,29 +183,36 @@
mGsmPhone.mSST.unregisterForPsRestrictedEnabled(this);
mGsmPhone.mSST.unregisterForPsRestrictedDisabled(this);
- phone.getContext().unregisterReceiver(this.mIntentReceiver);
- phone.getContext().getContentResolver().unregisterContentObserver(this.apnObserver);
+ mPhone.getContext().getContentResolver().unregisterContentObserver(this.mApnObserver);
- destroyAllPdpList();
+ destroyDataConnections();
}
+ @Override
protected void finalize() {
- if(DBG) Log.d(LOG_TAG, "GsmDataConnectionTracker finalized");
+ if(DBG) log("finalize");
}
+ @Override
+ protected String getActionIntentReconnectAlarm() {
+ return INTENT_RECONNECT_ALARM;
+ }
+
+ @Override
protected void setState(State s) {
if (DBG) log ("setState: " + s);
- if (state != s) {
- EventLog.writeEvent(EventLogTags.GSM_DATA_STATE_CHANGE, state.toString(), s.toString());
- state = s;
+ if (mState != s) {
+ EventLog.writeEvent(EventLogTags.GSM_DATA_STATE_CHANGE, mState.toString(), s.toString());
+ mState = s;
}
- if (state == State.FAILED) {
- if (waitingApns != null)
- waitingApns.clear(); // when teardown the connection and set to IDLE
+ if (mState == State.FAILED) {
+ if (mWaitingApns != null)
+ mWaitingApns.clear(); // when tear down the connection and set to IDLE
}
}
+ @Override
public String[] getActiveApnTypes() {
String[] result;
if (mActiveApn != null) {
@@ -330,6 +224,7 @@
return result;
}
+ @Override
protected String getActiveApnString() {
String result = null;
if (mActiveApn != null) {
@@ -347,15 +242,16 @@
*
* @return false while no data connection if all above requirements are met.
*/
+ @Override
public boolean isDataConnectionAsDesired() {
- boolean roaming = phone.getServiceState().getRoaming();
+ boolean roaming = mPhone.getServiceState().getRoaming();
if (mGsmPhone.mSIMRecords.getRecordsLoaded() &&
mGsmPhone.mSST.getCurrentGprsState() == ServiceState.STATE_IN_SERVICE &&
(!roaming || getDataOnRoamingEnabled()) &&
!mIsWifiConnected &&
!mIsPsRestricted ) {
- return (state == State.CONNECTED);
+ return (mState == State.CONNECTED);
}
return true;
}
@@ -372,8 +268,8 @@
return (fetchDunApn() != null);
}
- if (allApns != null) {
- for (ApnSetting apn : allApns) {
+ if (mAllApns != null) {
+ for (ApnSetting apn : mAllApns) {
if (apn.canHandleType(type)) {
return true;
}
@@ -382,14 +278,6 @@
return false;
}
- /**
- * Formerly this method was ArrayList<GsmDataConnection> getAllPdps()
- */
- public ArrayList<DataConnection> getAllDataConnections() {
- ArrayList<DataConnection> pdps = (ArrayList<DataConnection>)pdpList.clone();
- return pdps;
- }
-
//****** Called from ServiceStateTracker
/**
* Invoked when ServiceStateTracker observes a transition from GPRS
@@ -405,11 +293,11 @@
}
private void onGprsAttached() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
startNetStatPoll();
notifyDataConnection(Phone.REASON_GPRS_ATTACHED);
} else {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, Phone.REASON_GPRS_ATTACHED);
mRetryMgr.resetRetryCount();
}
@@ -417,26 +305,30 @@
}
}
+ @Override
protected boolean isDataAllowed() {
int gprsState = mGsmPhone.mSST.getCurrentGprsState();
boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
- boolean allowed = ((gprsState == ServiceState.STATE_IN_SERVICE || noAutoAttach) &&
- mGsmPhone.mSIMRecords.getRecordsLoaded() &&
- phone.getState() == Phone.State.IDLE &&
- mMasterDataEnabled &&
- (!phone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
- !mIsPsRestricted &&
- desiredPowerState);
+ boolean allowed =
+ (gprsState == ServiceState.STATE_IN_SERVICE || mAutoAttachOnCreation) &&
+ mGsmPhone.mSIMRecords.getRecordsLoaded() &&
+ mPhone.getState() == Phone.State.IDLE &&
+ mMasterDataEnabled &&
+ (!mPhone.getServiceState().getRoaming() || getDataOnRoamingEnabled()) &&
+ !mIsPsRestricted &&
+ desiredPowerState;
if (!allowed && DBG) {
String reason = "";
- if (gprsState != ServiceState.STATE_IN_SERVICE) reason += " - gprs= " + gprsState;
+ if (!((gprsState == ServiceState.STATE_IN_SERVICE) || mAutoAttachOnCreation)) {
+ reason += " - gprs= " + gprsState;
+ }
if (!mGsmPhone.mSIMRecords.getRecordsLoaded()) reason += " - SIM not loaded";
- if (phone.getState() != Phone.State.IDLE) {
- reason += " - PhoneState= " + phone.getState();
+ if (mPhone.getState() != Phone.State.IDLE) {
+ reason += " - PhoneState= " + mPhone.getState();
}
if (!mMasterDataEnabled) reason += " - mMasterDataEnabled= false";
- if (phone.getServiceState().getRoaming() && getDataOnRoamingEnabled()) {
+ if (mPhone.getServiceState().getRoaming() && getDataOnRoamingEnabled()) {
reason += " - Roaming";
}
if (mIsPsRestricted) reason += " - mIsPsRestricted= true";
@@ -449,38 +341,38 @@
private boolean trySetupData(String reason) {
if (DBG) log("***trySetupData due to " + (reason == null ? "(unspecified)" : reason));
- Log.d(LOG_TAG, "[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
+ log("[DSAC DEB] " + "trySetupData with mIsPsRestricted=" + mIsPsRestricted);
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
setState(State.CONNECTED);
notifyDataConnection(reason);
- Log.i(LOG_TAG, "(fix?) We're on the simulator; assuming data is connected");
+ log("(fix?) We're on the simulator; assuming data is connected");
return true;
}
int gprsState = mGsmPhone.mSST.getCurrentGprsState();
boolean desiredPowerState = mGsmPhone.mSST.getDesiredPowerState();
- if (((state == State.IDLE) || (state == State.SCANNING)) &&
+ if (((mState == State.IDLE) || (mState == State.SCANNING)) &&
isDataAllowed() && getAnyDataEnabled()) {
- if (state == State.IDLE) {
- waitingApns = buildWaitingApns();
- if (waitingApns.isEmpty()) {
+ if (mState == State.IDLE) {
+ mWaitingApns = buildWaitingApns(mRequestedApnType);
+ if (mWaitingApns.isEmpty()) {
if (DBG) log("No APN found");
notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
notifyOffApnsOfAvailability(reason, false);
return false;
} else {
- log ("Create from allApns : " + apnListToString(allApns));
+ log ("Create from allApns : " + apnListToString(mAllApns));
}
}
if (DBG) {
- log ("Setup waitngApns : " + apnListToString(waitingApns));
+ log ("Setup waitngApns : " + apnListToString(mWaitingApns));
}
boolean retValue = setupData(reason);
notifyOffApnsOfAvailability(reason, retValue);
@@ -492,13 +384,12 @@
}
/**
- * If tearDown is true, this only tears down a CONNECTED session. Presently,
- * there is no mechanism for abandoning an INITING/CONNECTING session,
- * but would likely involve cancelling pending async requests or
- * setting a flag or new state to ignore them when they came in
- * @param tearDown true if the underlying GsmDataConnection should be
- * disconnected.
- * @param reason reason for the clean up.
+ * Cleanup all connections.
+ *
+ * TODO: Cleanup only a specified connection passed as a parameter.
+ *
+ * @param tearDown true if the underlying DataConnection should be disconnected.
+ * @param reason for the clean up.
*/
private void cleanUpConnection(boolean tearDown, String reason) {
if (DBG) log("Clean up connection due to " + reason);
@@ -506,7 +397,7 @@
// Clear the reconnect alarm, if set.
if (mReconnectIntent != null) {
AlarmManager am =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
am.cancel(mReconnectIntent);
mReconnectIntent = null;
}
@@ -514,10 +405,11 @@
setState(State.DISCONNECTING);
boolean notificationDeferred = false;
- for (DataConnection conn : pdpList) {
+ for (DataConnection conn : mDataConnections.values()) {
if (tearDown) {
if (DBG) log("cleanUpConnection: teardown, call conn.disconnect");
- conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE, reason));
+ conn.disconnect(obtainMessage(EVENT_DISCONNECT_DONE,
+ conn.getDataConnectionId(), 0, reason));
notificationDeferred = true;
} else {
if (DBG) log("cleanUpConnection: !tearDown, call conn.resetSynchronously");
@@ -575,51 +467,49 @@
return result;
}
- private GsmDataConnection findFreePdp() {
- for (DataConnection conn : pdpList) {
- GsmDataConnection pdp = (GsmDataConnection) conn;
- if (pdp.isInactive()) {
- return pdp;
+ private GsmDataConnection findFreeDataConnection() {
+ for (DataConnection dc : mDataConnections.values()) {
+ if (dc.isInactive()) {
+ log("found free GsmDataConnection");
+ return (GsmDataConnection) dc;
}
}
+ log("NO free GsmDataConnection");
return null;
}
private boolean setupData(String reason) {
ApnSetting apn;
- GsmDataConnection pdp;
+ GsmDataConnection gdc;
apn = getNextApn();
if (apn == null) return false;
- pdp = findFreePdp();
- if (pdp == null) {
+ gdc = findFreeDataConnection();
+ if (gdc == null) {
if (DBG) log("setupData: No free GsmDataConnection found!");
return false;
}
mActiveApn = apn;
- mActivePdp = pdp;
+ mPendingDataConnection = gdc;
Message msg = obtainMessage();
msg.what = EVENT_DATA_SETUP_COMPLETE;
msg.obj = reason;
- pdp.connect(msg, apn);
+ gdc.connect(msg, apn);
setState(State.INITING);
notifyDataConnection(reason);
return true;
}
- private boolean
- pdpStatesHasCID (ArrayList<DataCallState> states, int cid) {
+ private boolean dataCallStatesHasCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if (states.get(i).cid == cid) return true;
}
-
return false;
}
- private boolean
- pdpStatesHasActiveCID (ArrayList<DataCallState> states, int cid) {
+ private boolean dataCallStatesHasActiveCID (ArrayList<DataCallState> states, int cid) {
for (int i = 0, s = states.size() ; i < s ; i++) {
if ((states.get(i).cid == cid) && (states.get(i).active != 0)) {
return true;
@@ -635,7 +525,7 @@
private void onApnChanged() {
boolean isConnected;
- isConnected = (state != State.IDLE && state != State.FAILED);
+ isConnected = (mState != State.IDLE && mState != State.FAILED);
// The "current" may no longer be valid. MMS depends on this to send properly.
mGsmPhone.updateCurrentCarrierInProvider();
@@ -643,7 +533,7 @@
// TODO: It'd be nice to only do this if the changed entrie(s)
// match the current operator.
createAllApnList();
- if (state != State.DISCONNECTING) {
+ if (mState != State.DISCONNECTING) {
cleanUpConnection(isConnected, Phone.REASON_APN_CHANGED);
if (!isConnected) {
// reset reconnect timer
@@ -660,10 +550,10 @@
* via an unsolicited response (which could have happened at any
* previous state
*/
- protected void onPdpStateChanged (AsyncResult ar, boolean explicitPoll) {
- ArrayList<DataCallState> pdpStates;
+ private void onDataStateChanged (AsyncResult ar, boolean explicitPoll) {
+ ArrayList<DataCallState> dataCallStates;
- pdpStates = (ArrayList<DataCallState>)(ar.result);
+ dataCallStates = (ArrayList<DataCallState>)(ar.result);
if (ar.exception != null) {
// This is probably "radio not available" or something
@@ -672,42 +562,42 @@
return;
}
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
// The way things are supposed to work, the PDP list
// should not contain the CID after it disconnects.
// However, the way things really work, sometimes the PDP
// context is still listed with active = false, which
// makes it hard to distinguish an activating context from
// an activated-and-then deactivated one.
- if (!pdpStatesHasCID(pdpStates, cidActive)) {
+ if (!dataCallStatesHasCID(dataCallStates, mCidActive)) {
// It looks like the PDP context has deactivated.
// Tear everything down and try to reconnect.
- Log.i(LOG_TAG, "PDP connection has dropped. Reconnecting");
+ log("PDP connection has dropped. Reconnecting");
// Add an event log when the network drops PDP
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
+ GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP,
loc != null ? loc.getCid() : -1,
TelephonyManager.getDefault().getNetworkType());
cleanUpConnection(true, null);
return;
- } else if (!pdpStatesHasActiveCID(pdpStates, cidActive)) {
+ } else if (!dataCallStatesHasActiveCID(dataCallStates, mCidActive)) {
// Here, we only consider this authoritative if we asked for the
// PDP list. If it was an unsolicited response, we poll again
// to make sure everyone agrees on the initial state.
if (!explicitPoll) {
// We think it disconnected but aren't sure...poll from our side
- phone.mCM.getPDPContextList(
+ mPhone.mCM.getPDPContextList(
this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
} else {
- Log.i(LOG_TAG, "PDP connection has dropped (active=false case). "
+ log("PDP connection has dropped (active=false case). "
+ " Reconnecting");
// Log the network drop on the event log.
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
+ GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.PDP_NETWORK_DROP,
loc != null ? loc.getCid() : -1,
TelephonyManager.getDefault().getNetworkType());
@@ -734,38 +624,26 @@
mActiveApn = null;
}
- /**
- * This is a kludge to deal with the fact that
- * the PDP state change notification doesn't always work
- * with certain RIL impl's/basebands
- *
- */
- private void startPeriodicPdpPoll() {
- removeMessages(EVENT_POLL_PDP);
-
- sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
- }
-
private void resetPollStats() {
- txPkts = -1;
- rxPkts = -1;
- sentSinceLastRecv = 0;
- netStatPollPeriod = POLL_NETSTAT_MILLIS;
+ mTxPkts = -1;
+ mRxPkts = -1;
+ mSentSinceLastRecv = 0;
+ mNetStatPollPeriod = POLL_NETSTAT_MILLIS;
mNoRecvPollCount = 0;
}
private void doRecovery() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
int maxPdpReset = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_MAX_PDP_RESET_FAIL_COUNT,
DEFAULT_MAX_PDP_RESET_FAIL);
if (mPdpResetCount < maxPdpReset) {
mPdpResetCount++;
- EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, sentSinceLastRecv);
+ EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET, mSentSinceLastRecv);
cleanUpConnection(true, Phone.REASON_PDP_RESET);
} else {
mPdpResetCount = 0;
- EventLog.writeEvent(EventLogTags.PDP_REREGISTER_NETWORK, sentSinceLastRecv);
+ EventLog.writeEvent(EventLogTags.PDP_REREGISTER_NETWORK, mSentSinceLastRecv);
mGsmPhone.mSST.reRegisterNetwork(null);
}
// TODO: Add increasingly drastic recovery steps, eg,
@@ -773,23 +651,26 @@
}
}
+ @Override
protected void startNetStatPoll() {
- if (state == State.CONNECTED && mPingTestActive == false && netStatPollEnabled == false) {
- Log.d(LOG_TAG, "[DataConnection] Start poll NetStat");
+ if (mState == State.CONNECTED && mPingTestActive == false && mNetStatPollEnabled == false) {
+ log("[DataConnection] Start poll NetStat");
resetPollStats();
- netStatPollEnabled = true;
+ mNetStatPollEnabled = true;
mPollNetStat.run();
}
}
+ @Override
protected void stopNetStatPoll() {
- netStatPollEnabled = false;
+ mNetStatPollEnabled = false;
removeCallbacks(mPollNetStat);
- Log.d(LOG_TAG, "[DataConnection] Stop poll NetStat");
+ log("[DataConnection] Stop poll NetStat");
}
+ @Override
protected void restartRadio() {
- Log.d(LOG_TAG, "************TURN OFF RADIO**************");
+ log("************TURN OFF RADIO**************");
cleanUpConnection(true, Phone.REASON_RADIO_TURNED_OFF);
mGsmPhone.mSST.powerOffRadioSafely();
/* Note: no need to call setRadioPower(true). Assuming the desired
@@ -813,43 +694,43 @@
Activity newActivity;
- preTxPkts = txPkts;
- preRxPkts = rxPkts;
+ preTxPkts = mTxPkts;
+ preRxPkts = mRxPkts;
- txPkts = TrafficStats.getMobileTxPackets();
- rxPkts = TrafficStats.getMobileRxPackets();
+ mTxPkts = TrafficStats.getMobileTxPackets();
+ mRxPkts = TrafficStats.getMobileRxPackets();
- //Log.d(LOG_TAG, "rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
+ //log("rx " + String.valueOf(rxPkts) + " tx " + String.valueOf(txPkts));
- if (netStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
- sent = txPkts - preTxPkts;
- received = rxPkts - preRxPkts;
+ if (mNetStatPollEnabled && (preTxPkts > 0 || preRxPkts > 0)) {
+ sent = mTxPkts - preTxPkts;
+ received = mRxPkts - preRxPkts;
if ( sent > 0 && received > 0 ) {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.DATAINANDOUT;
mPdpResetCount = 0;
} else if (sent > 0 && received == 0) {
- if (phone.getState() == Phone.State.IDLE) {
- sentSinceLastRecv += sent;
+ if (mPhone.getState() == Phone.State.IDLE) {
+ mSentSinceLastRecv += sent;
} else {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
}
newActivity = Activity.DATAOUT;
} else if (sent == 0 && received > 0) {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.DATAIN;
mPdpResetCount = 0;
} else if (sent == 0 && received == 0) {
newActivity = Activity.NONE;
} else {
- sentSinceLastRecv = 0;
+ mSentSinceLastRecv = 0;
newActivity = Activity.NONE;
}
- if (activity != newActivity && mIsScreenOn) {
- activity = newActivity;
- phone.notifyDataActivity();
+ if (mActivity != newActivity && mIsScreenOn) {
+ mActivity = newActivity;
+ mPhone.notifyDataActivity();
}
}
@@ -857,11 +738,11 @@
Settings.Secure.PDP_WATCHDOG_TRIGGER_PACKET_COUNT,
NUMBER_SENT_PACKETS_OF_HANG);
- if (sentSinceLastRecv >= watchdogTrigger) {
+ if (mSentSinceLastRecv >= watchdogTrigger) {
// we already have NUMBER_SENT_PACKETS sent without ack
if (mNoRecvPollCount == 0) {
EventLog.writeEvent(EventLogTags.PDP_RADIO_RESET_COUNTDOWN_TRIGGERED,
- sentSinceLastRecv);
+ mSentSinceLastRecv);
}
int noRecvPollLimit = Settings.Secure.getInt(mResolver,
@@ -871,21 +752,22 @@
// It's possible the PDP context went down and we weren't notified.
// Start polling the context list in an attempt to recover.
if (DBG) log("no DATAIN in a while; polling PDP");
- phone.mCM.getDataCallList(obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
+ mPhone.mCM.getDataCallList(obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
mNoRecvPollCount++;
// Slow down the poll interval to let things happen
- netStatPollPeriod = Settings.Secure.getInt(mResolver,
+ mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_ERROR_POLL_INTERVAL_MS,
POLL_NETSTAT_SLOW_MILLIS);
} else {
- if (DBG) log("Sent " + String.valueOf(sentSinceLastRecv) +
+ if (DBG) log("Sent " + String.valueOf(mSentSinceLastRecv) +
" pkts since last received");
// We've exceeded the threshold. Run ping test as a final check;
// it will proceed with recovery if ping fails.
stopNetStatPoll();
Thread pingTest = new Thread() {
+ @Override
public void run() {
runPingTest();
}
@@ -896,17 +778,17 @@
} else {
mNoRecvPollCount = 0;
if (mIsScreenOn) {
- netStatPollPeriod = Settings.Secure.getInt(mResolver,
+ mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_POLL_INTERVAL_MS, POLL_NETSTAT_MILLIS);
} else {
- netStatPollPeriod = Settings.Secure.getInt(mResolver,
+ mNetStatPollPeriod = Settings.Secure.getInt(mResolver,
Settings.Secure.PDP_WATCHDOG_LONG_POLL_INTERVAL_MS,
POLL_NETSTAT_SCREEN_OFF_MILLIS);
}
}
- if (netStatPollEnabled) {
- mDataConnectionTracker.postDelayed(this, netStatPollPeriod);
+ if (mNetStatPollEnabled) {
+ mDataConnectionTracker.postDelayed(this, mNetStatPollPeriod);
}
}
};
@@ -925,9 +807,9 @@
status = p.waitFor();
}
} catch (IOException e) {
- Log.w(LOG_TAG, "ping failed: IOException");
+ loge("ping failed: IOException");
} catch (Exception e) {
- Log.w(LOG_TAG, "exception trying to ping");
+ loge("exception trying to ping");
}
if (status == 0) {
@@ -968,7 +850,8 @@
}
private void reconnectAfterFail(FailCause lastFailCauseCode, String reason) {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
+ /** TODO: Retrieve retry manager from connection itself */
if (!mRetryMgr.isRetryNeeded()) {
if (!mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
// if no more retries on a secondary APN attempt, tell the world and revert.
@@ -977,11 +860,11 @@
return;
}
if (mReregisterOnReconnectFailure) {
- // We've re-registerd once now just retry forever.
+ // We've re-registered once now just retry forever.
mRetryMgr.retryForeverUsingLastTimeout();
} else {
// Try to re-register to the network.
- Log.d(LOG_TAG, "PDP activate failed, Reregistering to the network");
+ log("PDP activate failed, Reregistering to the network");
mReregisterOnReconnectFailure = true;
mGsmPhone.mSST.reRegisterNetwork(null);
mRetryMgr.resetRetryCount();
@@ -990,15 +873,15 @@
}
int nextReconnectDelay = mRetryMgr.getRetryTimer();
- Log.d(LOG_TAG, "PDP activate failed. Scheduling next attempt for "
+ log("PDP activate failed. Scheduling next attempt for "
+ (nextReconnectDelay / 1000) + "s");
AlarmManager am =
- (AlarmManager) phone.getContext().getSystemService(Context.ALARM_SERVICE);
+ (AlarmManager) mPhone.getContext().getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(INTENT_RECONNECT_ALARM);
intent.putExtra(INTENT_RECONNECT_ALARM_EXTRA_REASON, reason);
mReconnectIntent = PendingIntent.getBroadcast(
- phone.getContext(), 0, intent, 0);
+ mPhone.getContext(), 0, intent, 0);
am.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
SystemClock.elapsedRealtime() + nextReconnectDelay,
mReconnectIntent);
@@ -1006,7 +889,7 @@
mRetryMgr.increaseRetryCount();
if (!shouldPostNotification(lastFailCauseCode)) {
- Log.d(LOG_TAG,"NOT Posting GPRS Unavailable notification "
+ log("NOT Posting GPRS Unavailable notification "
+ "-- likely transient error");
} else {
notifyNoData(lastFailCauseCode);
@@ -1018,9 +901,9 @@
setState(State.FAILED);
}
- protected void onRecordsLoaded() {
+ private void onRecordsLoaded() {
createAllApnList();
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, null);
}
sendMessage(obtainMessage(EVENT_TRY_SETUP_DATA, Phone.REASON_SIM_LOADED));
@@ -1028,19 +911,29 @@
@Override
protected void onEnableNewApn() {
+ log("onEnableNewApn E");
// change our retry manager to use the appropriate numbers for the new APN
if (mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
- mRetryMgr = mDefaultRetryManager;
+ log("onEnableNewApn default type");
+ mRetryMgr = mPendingDataConnection.getRetryMgr();
+ mRetryMgr.resetRetryCount();
+ } else if (mApnToDataConnectionId.get(mRequestedApnType) == null) {
+ log("onEnableNewApn mRequestedApnType=" + mRequestedApnType +
+ " missing, make a new connection");
+ int id = createDataConnection(mRequestedApnType);
+ mRetryMgr = mDataConnections.get(id).getRetryMgr();
+ mRetryMgr.resetRetryCount();
} else {
- mRetryMgr = mSecondaryRetryManager;
+ log("oneEnableNewApn connection already exists, nothing to setup");
}
- mRetryMgr.resetRetryCount();
// TODO: To support simultaneous PDP contexts, this should really only call
// cleanUpConnection if it needs to free up a GsmDataConnection.
cleanUpConnection(true, Phone.REASON_APN_SWITCHED);
+ log("onEnableNewApn X");
}
+ @Override
protected boolean onTrySetupData(String reason) {
return trySetupData(reason);
}
@@ -1060,31 +953,33 @@
}
}
+ @Override
protected void onRadioAvailable() {
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
setState(State.CONNECTED);
notifyDataConnection(null);
- Log.i(LOG_TAG, "We're on the simulator; assuming data is connected");
+ log("We're on the simulator; assuming data is connected");
}
- if (state != State.IDLE) {
+ if (mState != State.IDLE) {
cleanUpConnection(true, null);
}
}
+ @Override
protected void onRadioOffOrNotAvailable() {
// Make sure our reconnect delay starts at the initial value
// next time the radio comes on
mRetryMgr.resetRetryCount();
mReregisterOnReconnectFailure = false;
- if (phone.getSimulatedRadioControl() != null) {
+ if (mPhone.getSimulatedRadioControl() != null) {
// Assume data is connected on the simulator
// FIXME this can be improved
- Log.i(LOG_TAG, "We're on the simulator; assuming radio off is meaningless");
+ log("We're on the simulator; assuming radio off is meaningless");
} else {
if (DBG) log("Radio is off and clean up all connection");
// TODO: Should we reset mRequestedApnType to "default"?
@@ -1092,7 +987,9 @@
}
}
+ @Override
protected void onDataSetupComplete(AsyncResult ar) {
+ /** TODO: Which connection is completing should be a parameter */
String reason = null;
if (ar.userObj instanceof String) {
reason = (String) ar.userObj;
@@ -1100,10 +997,10 @@
if (ar.exception == null) {
// TODO: We should clear LinkProperties/Capabilities when torn down or disconnected
- mLinkProperties = getLinkProperties(mActivePdp);
- mLinkCapabilities = getLinkCapabilities(mActivePdp);
+ mLinkProperties = getLinkProperties(mPendingDataConnection);
+ mLinkCapabilities = getLinkCapabilities(mPendingDataConnection);
- ApnSetting apn = mActivePdp.getApn();
+ ApnSetting apn = mPendingDataConnection.getApn();
if (apn.proxy != null && apn.proxy.length() != 0) {
try {
ProxyProperties proxy = new ProxyProperties();
@@ -1111,11 +1008,11 @@
Integer.parseInt(apn.port)));
mLinkProperties.setHttpProxy(proxy);
} catch (UnknownHostException e) {
- Log.e(LOG_TAG, "UnknownHostException making ProxyProperties: " + e);
+ loge("UnknownHostException making ProxyProperties: " + e);
} catch (SecurityException e) {
- Log.e(LOG_TAG, "SecurityException making ProxyProperties: " + e);
+ loge("SecurityException making ProxyProperties: " + e);
} catch (NumberFormatException e) {
- Log.e(LOG_TAG, "NumberFormatException making ProxyProperties (" + apn.port +
+ loge("NumberFormatException making ProxyProperties (" + apn.port +
"): " + e);
}
}
@@ -1123,10 +1020,10 @@
// everything is setup
if (isApnTypeActive(Phone.APN_TYPE_DEFAULT)) {
SystemProperties.set("gsm.defaultpdpcontext.active", "true");
- if (canSetPreferApn && preferredApn == null) {
- Log.d(LOG_TAG, "PREFERRED APN is null");
- preferredApn = mActiveApn;
- setPreferredApn(preferredApn.id);
+ if (canSetPreferApn && mPreferredApn == null) {
+ log("PREFERRED APN is null");
+ mPreferredApn = mActiveApn;
+ setPreferredApn(mPreferredApn.id);
}
} else {
SystemProperties.set("gsm.defaultpdpcontext.active", "false");
@@ -1143,13 +1040,14 @@
if(DBG) log("PDP setup failed " + cause);
// Log this failure to the Event Logs.
if (cause.isEventLoggable()) {
- GsmCellLocation loc = ((GsmCellLocation)phone.getCellLocation());
+ GsmCellLocation loc = ((GsmCellLocation)mPhone.getCellLocation());
EventLog.writeEvent(EventLogTags.PDP_SETUP_FAIL,
cause.ordinal(), loc != null ? loc.getCid() : -1,
TelephonyManager.getDefault().getNetworkType());
}
- // No try for permanent failure
+ // Do not retry on permanent failure
+ // TODO: We should not fail permanently if more Apns to try!
if (cause.isPermanentFail()) {
notifyNoData(cause);
notifyDataConnection(Phone.REASON_APN_FAILED);
@@ -1157,8 +1055,8 @@
return;
}
- waitingApns.remove(0);
- if (waitingApns.isEmpty()) {
+ mWaitingApns.remove(0);
+ if (mWaitingApns.isEmpty()) {
// No more to try, start delayed retry
startDelayedRetry(cause, reason);
} else {
@@ -1174,9 +1072,10 @@
/**
* Called when EVENT_DISCONNECT_DONE is received.
*/
- protected void onDisconnectDone(AsyncResult ar) {
+ @Override
+ protected void onDisconnectDone(int connId, AsyncResult ar) {
+ if(DBG) log("EVENT_DISCONNECT_DONE connId=" + connId);
String reason = null;
- if(DBG) log("EVENT_DISCONNECT_DONE");
if (ar.userObj instanceof String) {
reason = (String) ar.userObj;
}
@@ -1202,22 +1101,24 @@
}
protected void onPollPdp() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
// only poll when connected
- phone.mCM.getPDPContextList(this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
+ mPhone.mCM.getPDPContextList(this.obtainMessage(EVENT_GET_PDP_LIST_COMPLETE));
sendMessageDelayed(obtainMessage(EVENT_POLL_PDP), POLL_PDP_MILLIS);
}
}
+ @Override
protected void onVoiceCallStarted() {
- if (state == State.CONNECTED && ! mGsmPhone.mSST.isConcurrentVoiceAndData()) {
+ if (mState == State.CONNECTED && ! mGsmPhone.mSST.isConcurrentVoiceAndData()) {
stopNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_STARTED);
}
}
+ @Override
protected void onVoiceCallEnded() {
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
if (!mGsmPhone.mSST.isConcurrentVoiceAndData()) {
startNetStatPoll();
notifyDataConnection(Phone.REASON_VOICE_CALL_ENDED);
@@ -1234,74 +1135,92 @@
}
}
+ @Override
protected void onCleanUpConnection(boolean tearDown, String reason) {
cleanUpConnection(tearDown, reason);
}
/**
- * Based on the sim operator numeric, create a list for all possible pdps
- * with all apns associated with that pdp
- *
- *
+ * Based on the sim operator numeric, create a list for all possible
+ * Data Connections and setup the preferredApn.
*/
private void createAllApnList() {
- allApns = new ArrayList<ApnSetting>();
+ mAllApns = new ArrayList<ApnSetting>();
String operator = mGsmPhone.mSIMRecords.getSIMOperatorNumeric();
if (operator != null) {
String selection = "numeric = '" + operator + "'";
- Cursor cursor = phone.getContext().getContentResolver().query(
+ Cursor cursor = mPhone.getContext().getContentResolver().query(
Telephony.Carriers.CONTENT_URI, null, selection, null, null);
if (cursor != null) {
if (cursor.getCount() > 0) {
- allApns = createApnList(cursor);
- // TODO: Figure out where this fits in. This basically just
- // writes the pap-secrets file. No longer tied to GsmDataConnection
- // object. Not used on current platform (no ppp).
- //GsmDataConnection pdp = pdpList.get(pdp_name);
- //if (pdp != null && pdp.dataLink != null) {
- // pdp.dataLink.setPasswordInfo(cursor);
- //}
+ mAllApns = createApnList(cursor);
}
cursor.close();
}
}
- if (allApns.isEmpty()) {
+ if (mAllApns.isEmpty()) {
if (DBG) log("No APN found for carrier: " + operator);
- preferredApn = null;
+ mPreferredApn = null;
notifyNoData(GsmDataConnection.FailCause.MISSING_UNKNOWN_APN);
} else {
- preferredApn = getPreferredApn();
- Log.d(LOG_TAG, "Get PreferredAPN");
- if (preferredApn != null && !preferredApn.numeric.equals(operator)) {
- preferredApn = null;
+ mPreferredApn = getPreferredApn();
+ log("Get PreferredAPN");
+ if (mPreferredApn != null && !mPreferredApn.numeric.equals(operator)) {
+ mPreferredApn = null;
setPreferredApn(-1);
}
}
}
- private void createAllPdpList() {
- pdpList = new ArrayList<DataConnection>();
- DataConnection pdp;
+ /** Return the id for a new data connection */
+ private int createDataConnection(String apnType) {
+ log("createDataConnection(" + apnType + ") E");
+ RetryManager rm = new RetryManager();
- for (int i = 0; i < PDP_CONNECTION_POOL_SIZE; i++) {
- pdp = GsmDataConnection.makeDataConnection(mGsmPhone);
- pdpList.add(pdp);
- }
+ if (apnType.equals(Phone.APN_TYPE_DEFAULT)) {
+ if (!rm.configure(SystemProperties.get("ro.gsm.data_retry_config"))) {
+ if (!rm.configure(DEFAULT_DATA_RETRY_CONFIG)) {
+ // Should never happen, log an error and default to a simple linear sequence.
+ log("Could not configure using DEFAULT_DATA_RETRY_CONFIG="
+ + DEFAULT_DATA_RETRY_CONFIG);
+ rm.configure(20, 2000, 1000);
+ }
+ }
+ } else {
+ if (!rm.configure(SystemProperties.get("ro.gsm.2nd_data_retry_config"))) {
+ if (!rm.configure(SECONDARY_DATA_RETRY_CONFIG)) {
+ // Should never happen, log an error and default to a simple sequence.
+ log("Could note configure using SECONDARY_DATA_RETRY_CONFIG="
+ + SECONDARY_DATA_RETRY_CONFIG);
+ rm.configure("max_retries=3, 333, 333, 333");
+ }
+ }
+ }
+
+ int id = mUniqueIdGenerator.getAndIncrement();
+ DataConnection conn = GsmDataConnection.makeDataConnection(mGsmPhone, id, rm);
+ mDataConnections.put(id, conn);
+ mApnToDataConnectionId.put(apnType, id);
+
+ log("createDataConnection(" + apnType + ") X id=" + id);
+ return id;
}
- private void destroyAllPdpList() {
- if(pdpList != null) {
- GsmDataConnection pdp;
- pdpList.removeAll(pdpList);
+ private void destroyDataConnections() {
+ if(mDataConnections != null) {
+ log("destroyDataConnectionList clear mDataConnectionList");
+ mDataConnections.clear();
+ } else {
+ log("destroyDataConnectionList mDataConnecitonList is empty, ignore");
}
}
private ApnSetting fetchDunApn() {
- Context c = phone.getContext();
+ Context c = mPhone.getContext();
String apnData = Settings.Secure.getString(c.getContentResolver(),
Settings.Secure.TETHER_DUN_APN);
ApnSetting dunSetting = ApnSetting.fromString(apnData);
@@ -1312,14 +1231,16 @@
}
/**
+ * Build a list of APNs to be used to create PDP's.
*
+ * @param requestedApnType
* @return waitingApns list to be used to create PDP
* error when waitingApns.isEmpty()
*/
- private ArrayList<ApnSetting> buildWaitingApns() {
+ private ArrayList<ApnSetting> buildWaitingApns(String requestedApnType) {
ArrayList<ApnSetting> apnList = new ArrayList<ApnSetting>();
- if (mRequestedApnType.equals(Phone.APN_TYPE_DUN)) {
+ if (requestedApnType.equals(Phone.APN_TYPE_DUN)) {
ApnSetting dun = fetchDunApn();
if (dun != null) apnList.add(dun);
return apnList;
@@ -1327,24 +1248,24 @@
String operator = mGsmPhone.mSIMRecords.getSIMOperatorNumeric();
- if (mRequestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
- if (canSetPreferApn && preferredApn != null) {
- Log.i(LOG_TAG, "Preferred APN:" + operator + ":"
- + preferredApn.numeric + ":" + preferredApn);
- if (preferredApn.numeric.equals(operator)) {
- Log.i(LOG_TAG, "Waiting APN set to preferred APN");
- apnList.add(preferredApn);
+ if (requestedApnType.equals(Phone.APN_TYPE_DEFAULT)) {
+ if (canSetPreferApn && mPreferredApn != null) {
+ log("Preferred APN:" + operator + ":"
+ + mPreferredApn.numeric + ":" + mPreferredApn);
+ if (mPreferredApn.numeric.equals(operator)) {
+ log("Waiting APN set to preferred APN");
+ apnList.add(mPreferredApn);
return apnList;
} else {
setPreferredApn(-1);
- preferredApn = null;
+ mPreferredApn = null;
}
}
}
- if (allApns != null) {
- for (ApnSetting apn : allApns) {
- if (apn.canHandleType(mRequestedApnType)) {
+ if (mAllApns != null) {
+ for (ApnSetting apn : mAllApns) {
+ if (apn.canHandleType(requestedApnType)) {
apnList.add(apn);
}
}
@@ -1357,7 +1278,7 @@
* @return the first apn found in waitingApns, null if none
*/
private ApnSetting getNextApn() {
- ArrayList<ApnSetting> list = waitingApns;
+ ArrayList<ApnSetting> list = mWaitingApns;
ApnSetting apn = null;
if (list != null) {
@@ -1388,7 +1309,7 @@
return;
}
- ContentResolver resolver = phone.getContext().getContentResolver();
+ ContentResolver resolver = mPhone.getContext().getContentResolver();
resolver.delete(PREFERAPN_URI, null, null);
if (pos >= 0) {
@@ -1399,11 +1320,11 @@
}
private ApnSetting getPreferredApn() {
- if (allApns.isEmpty()) {
+ if (mAllApns.isEmpty()) {
return null;
}
- Cursor cursor = phone.getContext().getContentResolver().query(
+ Cursor cursor = mPhone.getContext().getContentResolver().query(
PREFERAPN_URI, new String[] { "_id", "name", "apn" },
null, null, Telephony.Carriers.DEFAULT_SORT_ORDER);
@@ -1417,7 +1338,7 @@
int pos;
cursor.moveToFirst();
pos = cursor.getInt(cursor.getColumnIndexOrThrow(Telephony.Carriers._ID));
- for(ApnSetting p:allApns) {
+ for(ApnSetting p:mAllApns) {
if (p.id == pos && p.canHandleType(mRequestedApnType)) {
cursor.close();
return p;
@@ -1432,11 +1353,12 @@
return null;
}
+ @Override
public void handleMessage (Message msg) {
- if (DBG) Log.d(LOG_TAG,"GSMDataConnTrack handleMessage "+msg);
+ if (DBG) log("GSMDataConnTrack handleMessage "+msg);
if (!mGsmPhone.mIsTheCurrentActivePhone) {
- Log.d(LOG_TAG, "Ignore GSM msgs since GSM phone is inactive");
+ log("Ignore GSM msgs since GSM phone is inactive");
return;
}
@@ -1454,11 +1376,11 @@
break;
case EVENT_DATA_STATE_CHANGED:
- onPdpStateChanged((AsyncResult) msg.obj, false);
+ onDataStateChanged((AsyncResult) msg.obj, false);
break;
case EVENT_GET_PDP_LIST_COMPLETE:
- onPdpStateChanged((AsyncResult) msg.obj, true);
+ onDataStateChanged((AsyncResult) msg.obj, true);
break;
case EVENT_POLL_PDP:
@@ -1486,7 +1408,7 @@
* PDP context and notify us with PDP_CONTEXT_CHANGED.
* But we should stop the network polling and prevent reset PDP.
*/
- Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
+ log("[DSAC DEB] " + "EVENT_PS_RESTRICT_ENABLED " + mIsPsRestricted);
stopNetStatPoll();
mIsPsRestricted = true;
break;
@@ -1496,12 +1418,12 @@
* When PS restrict is removed, we need setup PDP connection if
* PDP connection is down.
*/
- Log.d(LOG_TAG, "[DSAC DEB] " + "EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
+ log("[DSAC DEB] " + "EVENT_PS_RESTRICT_DISABLED " + mIsPsRestricted);
mIsPsRestricted = false;
- if (state == State.CONNECTED) {
+ if (mState == State.CONNECTED) {
startNetStatPoll();
} else {
- if (state == State.FAILED) {
+ if (mState == State.FAILED) {
cleanUpConnection(false, Phone.REASON_PS_RESTRICT_ENABLED);
mRetryMgr.resetRetryCount();
mReregisterOnReconnectFailure = false;
@@ -1517,7 +1439,13 @@
}
}
+ @Override
protected void log(String s) {
Log.d(LOG_TAG, "[GsmDataConnectionTracker] " + s);
}
+
+ @Override
+ protected void loge(String s) {
+ Log.e(LOG_TAG, "[GsmDataConnectionTracker] " + s);
+ }
}
diff --git a/tests/DpiTest/Android.mk b/tests/DpiTest/Android.mk
index 5463a17..f55ce6e 100644
--- a/tests/DpiTest/Android.mk
+++ b/tests/DpiTest/Android.mk
@@ -7,6 +7,6 @@
LOCAL_MODULE_TAGS := tests
-LOCAL_AAPT_FLAGS = -c 120dpi -c 240dpi -c 160dpi
+LOCAL_AAPT_FLAGS = -c 120dpi,240dpi,160dpi,nodpi
include $(BUILD_PACKAGE)
diff --git a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
index bfe5c86..80db8c3 100644
--- a/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
+++ b/tools/layoutlib/bridge/src/android/graphics/Canvas_Delegate.java
@@ -970,6 +970,8 @@
Graphics2D g = getGraphics2d();
g = (Graphics2D)g.create();
+ // configure it
+
if (paint.isAntiAliased()) {
g.setRenderingHint(
RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
@@ -977,54 +979,15 @@
RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
}
- // configure it
- g.setColor(new Color(paint.getColor()));
- int alpha = paint.getAlpha();
- float falpha = alpha / 255.f;
+ boolean useColorPaint = true;
- int style = paint.getStyle();
- if (style == Paint.Style.STROKE.nativeInt ||
- style == Paint.Style.FILL_AND_STROKE.nativeInt) {
- /* FIXME
- PathEffect e = paint.getPathEffect();
- if (e instanceof DashPathEffect) {
- DashPathEffect dpe = (DashPathEffect)e;
- g.setStroke(new BasicStroke(
- paint.getStrokeWidth(),
- paint.getStrokeCap().getJavaCap(),
- paint.getStrokeJoin().getJavaJoin(),
- paint.getStrokeMiter(),
- dpe.getIntervals(),
- dpe.getPhase()));
- } else {*/
- g.setStroke(new BasicStroke(
- paint.getStrokeWidth(),
- paint.getJavaCap(),
- paint.getJavaJoin(),
- paint.getStrokeMiter()));
- /* }*/
- }
-/*
- Xfermode xfermode = paint.getXfermode();
- if (xfermode instanceof PorterDuffXfermode) {
- PorterDuff.Mode mode = ((PorterDuffXfermode)xfermode).getMode();
-
- setModeInGraphics(mode, g, falpha);
- } else {
- if (mLogger != null && xfermode != null) {
- mLogger.warning(String.format(
- "Xfermode '%1$s' is not supported in the Layout Editor.",
- xfermode.getClass().getCanonicalName()));
- }
- g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
- }
-*/
- int nativeShader = paint.getShader();
- Shader_Delegate shaderDelegate = Shader_Delegate.getDelegate(nativeShader);
+ // get the shader first, as it'll replace the color if it can be used it.
+ Shader_Delegate shaderDelegate = Shader_Delegate.getDelegate(paint.getShader());
if (shaderDelegate != null) {
java.awt.Paint shaderPaint = shaderDelegate.getJavaPaint();
if (shaderPaint != null) {
g.setPaint(shaderPaint);
+ useColorPaint = false;
} else {
if (mLogger != null) {
mLogger.warning(String.format(
@@ -1034,6 +997,59 @@
}
}
+ // need to get the alpha to set it in the composite.
+ float falpha = 1.f;
+
+ if (useColorPaint) {
+ g.setColor(new Color(paint.getColor()));
+
+ // the alpha is taken from the alpha channel of the color
+ int alpha = paint.getAlpha();
+ falpha = alpha / 255.f;
+ }
+
+ int style = paint.getStyle();
+ if (style == Paint.Style.STROKE.nativeInt ||
+ style == Paint.Style.FILL_AND_STROKE.nativeInt) {
+
+ PathEffect_Delegate effectDelegate = PathEffect_Delegate.getDelegate(
+ paint.getPathEffect());
+
+ if (effectDelegate instanceof DashPathEffect_Delegate) {
+ DashPathEffect_Delegate dpe = (DashPathEffect_Delegate)effectDelegate;
+ g.setStroke(new BasicStroke(
+ paint.getStrokeWidth(),
+ paint.getJavaCap(),
+ paint.getJavaJoin(),
+ paint.getStrokeMiter(),
+ dpe.getIntervals(),
+ dpe.getPhase()));
+ } else {
+ g.setStroke(new BasicStroke(
+ paint.getStrokeWidth(),
+ paint.getJavaCap(),
+ paint.getJavaJoin(),
+ paint.getStrokeMiter()));
+ }
+ }
+
+ Xfermode_Delegate xfermodeDelegate = Xfermode_Delegate.getDelegate(paint.getXfermode());
+ if (xfermodeDelegate instanceof PorterDuffXfermode_Delegate) {
+ int mode = ((PorterDuffXfermode_Delegate)xfermodeDelegate).getMode();
+
+ setModeInGraphics(g, mode, falpha);
+ } else {
+ // default mode is src_over
+ g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, falpha));
+
+ // if xfermode wasn't null, then it's something we don't support. log it.
+ if (mLogger != null && xfermodeDelegate != null) {
+ mLogger.warning(String.format(
+ "Xfermode '%1$s' is not supported in the Layout Editor.",
+ xfermodeDelegate.getClass().getCanonicalName()));
+ }
+ }
+
return g;
}
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java
deleted file mode 100644
index 46d4c70..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Copyright (C) 2010 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.graphics;
-
-public class DashPathEffect extends PathEffect {
-
- private final float[] mIntervals;
- private final float mPhase;
-
- /**
- * The intervals array must contain an even number of entries (>=2), with
- * the even indices specifying the "on" intervals, and the odd indices
- * specifying the "off" intervals. phase is an offset into the intervals
- * array (mod the sum of all of the intervals). The intervals array
- * controls the length of the dashes. The paint's strokeWidth controls the
- * thickness of the dashes.
- * Note: this patheffect only affects drawing with the paint's style is set
- * to STROKE or STROKE_AND_FILL. It is ignored if the drawing is done with
- * style == FILL.
- * @param intervals array of ON and OFF distances
- * @param phase offset into the intervals array
- */
- public DashPathEffect(float intervals[], float phase) {
- if (intervals.length < 2) {
- throw new ArrayIndexOutOfBoundsException();
- }
-
- mIntervals = intervals;
- mPhase = phase;
- }
-
- public float[] getIntervals() {
- return mIntervals;
- }
-
- public float getPhase() {
- return mPhase;
- }
-}
-
diff --git a/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
new file mode 100644
index 0000000..59b6a91
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/DashPathEffect_Delegate.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2010 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.graphics;
+
+import com.android.layoutlib.bridge.DelegateManager;
+
+/**
+ * Delegate implementing the native methods of android.graphics.DashPathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of DashPathEffect have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original DashPathEffect class.
+ *
+ * Because this extends {@link PathEffect_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
+ * {@link PathEffect_Delegate}.
+ *
+ */
+public class DashPathEffect_Delegate extends PathEffect_Delegate {
+
+ // ---- delegate data ----
+
+ private final float[] mIntervals;
+ private final float mPhase;
+
+ // ---- Public Helper methods ----
+
+ public float[] getIntervals() {
+ return mIntervals;
+ }
+
+ public float getPhase() {
+ return mPhase;
+ }
+
+ // ---- native methods ----
+
+ /*package*/ static int nativeCreate(float intervals[], float phase) {
+ DashPathEffect_Delegate newDelegate = new DashPathEffect_Delegate(intervals, phase);
+ return sManager.addDelegate(newDelegate);
+ }
+
+ // ---- Private delegate/helper methods ----
+
+ private DashPathEffect_Delegate(float intervals[], float phase) {
+ mIntervals = new float[intervals.length];
+ System.arraycopy(intervals, 0, mIntervals, 0, intervals.length);
+ mPhase = phase;
+ }
+}
+
diff --git a/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
new file mode 100644
index 0000000..6827ae7
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PathEffect_Delegate.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 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.graphics;
+
+import com.android.layoutlib.bridge.DelegateManager;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PathEffect
+ *
+ * Through the layoutlib_create tool, the original native methods of PathEffect have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PathEffect class.
+ *
+ * This also serve as a base class for all PathEffect delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public class PathEffect_Delegate {
+
+ // ---- delegate manager ----
+ protected static final DelegateManager<PathEffect_Delegate> sManager =
+ new DelegateManager<PathEffect_Delegate>();
+
+ // ---- delegate helper data ----
+
+ // ---- delegate data ----
+
+ // ---- Public Helper methods ----
+
+ public static PathEffect_Delegate getDelegate(int nativeShader) {
+ return sManager.getDelegate(nativeShader);
+ }
+
+ // ---- native methods ----
+
+ /*package*/ static void nativeDestructor(int native_patheffect) {
+ sManager.removeDelegate(native_patheffect);
+ }
+
+ // ---- Private delegate/helper methods ----
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java
deleted file mode 100644
index 974ae49..0000000
--- a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode.java
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.graphics;
-
-import android.graphics.PorterDuff.Mode;
-
-public class PorterDuffXfermode extends Xfermode {
- private final Mode mMode;
-
- /**
- * Create an xfermode that uses the specified porter-duff mode.
- *
- * @param mode The porter-duff mode that is applied
- */
- public PorterDuffXfermode(PorterDuff.Mode mode) {
- mMode = mode;
- }
-
- //---------- Custom Methods
-
- public PorterDuff.Mode getMode() {
- return mMode;
- }
-
- //----------
-}
diff --git a/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
new file mode 100644
index 0000000..c242e80
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/PorterDuffXfermode_Delegate.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2010 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.graphics;
+
+import com.android.layoutlib.bridge.DelegateManager;
+
+/**
+ * Delegate implementing the native methods of android.graphics.PorterDuffXfermode
+ *
+ * Through the layoutlib_create tool, the original native methods of PorterDuffXfermode have been
+ * replaced by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original PorterDuffXfermode class.
+ *
+ * Because this extends {@link Xfermode_Delegate}, there's no need to use a
+ * {@link DelegateManager}, as all the PathEffect classes will be added to the manager owned by
+ * {@link Xfermode_Delegate}.
+ *
+ */
+public class PorterDuffXfermode_Delegate extends Xfermode_Delegate {
+
+ // ---- delegate data ----
+
+ private final int mMode;
+
+ // ---- Public Helper methods ----
+
+ public int getMode() {
+ return mMode;
+ }
+
+ // ---- native methods ----
+
+ /*package*/ static int nativeCreateXfermode(int mode) {
+ PorterDuffXfermode_Delegate newDelegate = new PorterDuffXfermode_Delegate(mode);
+ return sManager.addDelegate(newDelegate);
+ }
+
+ // ---- Private delegate/helper methods ----
+
+ private PorterDuffXfermode_Delegate(int mode) {
+ mMode = mode;
+ }
+
+}
diff --git a/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
new file mode 100644
index 0000000..d4408cf
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/graphics/Xfermode_Delegate.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2010 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.graphics;
+
+import com.android.layoutlib.bridge.DelegateManager;
+
+/**
+ * Delegate implementing the native methods of android.graphics.Xfermode
+ *
+ * Through the layoutlib_create tool, the original native methods of Xfermode have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * This class behaves like the original native implementation, but in Java, keeping previously
+ * native data into its own objects and mapping them to int that are sent back and forth between
+ * it and the original Xfermode class.
+ *
+ * This also serve as a base class for all Xfermode delegate classes.
+ *
+ * @see DelegateManager
+ *
+ */
+public class Xfermode_Delegate {
+
+ // ---- delegate manager ----
+ protected static final DelegateManager<Xfermode_Delegate> sManager =
+ new DelegateManager<Xfermode_Delegate>();
+
+ // ---- delegate helper data ----
+
+ // ---- delegate data ----
+
+ // ---- Public Helper methods ----
+
+ public static Xfermode_Delegate getDelegate(int native_instance) {
+ return sManager.getDelegate(native_instance);
+ }
+
+ // ---- native methods ----
+
+ /*package*/ static void finalizer(int native_instance) {
+ sManager.removeDelegate(native_instance);
+ }
+
+ // ---- Private delegate/helper methods ----
+
+}
diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath.java b/tools/layoutlib/bridge/src/android/util/FloatMath.java
deleted file mode 100644
index aae44f2..0000000
--- a/tools/layoutlib/bridge/src/android/util/FloatMath.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Copyright (C) 2007 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-/**
- * Reimplements _Original_FloatMath with the standard libraries.
- *
- * Math routines similar to those found in {@link java.lang.Math}. Performs
- * computations on {@code float} values directly without incurring the overhead
- * of conversions to and from {@code double}.
- *
- * <p>On one platform, {@code FloatMath.sqrt(100)} executes in one third of the
- * time required by {@code java.lang.Math.sqrt(100)}.</p>
- */
-public class FloatMath {
-
- /** Prevents instantiation. */
- private FloatMath() {}
-
- /**
- * Returns the float conversion of the most positive (i.e. closest to
- * positive infinity) integer value which is less than the argument.
- *
- * @param value to be converted
- * @return the floor of value
- */
- public static float floor(float value) {
- return (float)Math.floor(value);
- }
-
- /**
- * Returns the float conversion of the most negative (i.e. closest to
- * negative infinity) integer value which is greater than the argument.
- *
- * @param value to be converted
- * @return the ceiling of value
- */
- public static float ceil(float value) {
- return (float)Math.ceil(value);
- }
-
- /**
- * Returns the closest float approximation of the sine of the argument.
- *
- * @param angle to compute the cosine of, in radians
- * @return the sine of angle
- */
- public static float sin(float angle) {
- return (float)Math.sin(angle);
- }
-
- /**
- * Returns the closest float approximation of the cosine of the argument.
- *
- * @param angle to compute the cosine of, in radians
- * @return the cosine of angle
- */
- public static float cos(float angle) {
- return (float)Math.cos(angle);
- }
-
- /**
- * Returns the closest float approximation of the square root of the
- * argument.
- *
- * @param value to compute sqrt of
- * @return the square root of value
- */
- public static float sqrt(float value) {
- return (float)Math.sqrt(value);
- }
-}
diff --git a/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
new file mode 100644
index 0000000..ed24e16
--- /dev/null
+++ b/tools/layoutlib/bridge/src/android/util/FloatMath_Delegate.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (C) 2007 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.util;
+
+import com.android.layoutlib.bridge.DelegateManager;
+
+/**
+ * Delegate implementing the native methods of android.util.FloatMath
+ *
+ * Through the layoutlib_create tool, the original native methods of FloatMath have been replaced
+ * by calls to methods of the same name in this delegate class.
+ *
+ * Because it's a stateless class to start with, there's no need to keep a {@link DelegateManager}
+ * around to map int to instance of the delegate.
+ *
+ */
+/*package*/ final class FloatMath_Delegate {
+
+ /** Prevents instantiation. */
+ private FloatMath_Delegate() {}
+
+ /**
+ * Returns the float conversion of the most positive (i.e. closest to
+ * positive infinity) integer value which is less than the argument.
+ *
+ * @param value to be converted
+ * @return the floor of value
+ */
+ /*package*/ static float floor(float value) {
+ return (float)Math.floor(value);
+ }
+
+ /**
+ * Returns the float conversion of the most negative (i.e. closest to
+ * negative infinity) integer value which is greater than the argument.
+ *
+ * @param value to be converted
+ * @return the ceiling of value
+ */
+ /*package*/ static float ceil(float value) {
+ return (float)Math.ceil(value);
+ }
+
+ /**
+ * Returns the closest float approximation of the sine of the argument.
+ *
+ * @param angle to compute the cosine of, in radians
+ * @return the sine of angle
+ */
+ /*package*/ static float sin(float angle) {
+ return (float)Math.sin(angle);
+ }
+
+ /**
+ * Returns the closest float approximation of the cosine of the argument.
+ *
+ * @param angle to compute the cosine of, in radians
+ * @return the cosine of angle
+ */
+ /*package*/ static float cos(float angle) {
+ return (float)Math.cos(angle);
+ }
+
+ /**
+ * Returns the closest float approximation of the square root of the
+ * argument.
+ *
+ * @param value to compute sqrt of
+ * @return the square root of value
+ */
+ /*package*/ static float sqrt(float value) {
+ return (float)Math.sqrt(value);
+ }
+}
diff --git a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
index 2a6ef4d..8e05c31 100644
--- a/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
+++ b/tools/layoutlib/create/src/com/android/tools/layoutlib/create/CreateInfo.java
@@ -105,13 +105,18 @@
private final static String[] DELEGATE_CLASS_NATIVES = new String[] {
"android.graphics.Bitmap",
"android.graphics.Canvas",
+ "android.graphics.DashPathEffect",
"android.graphics.LinearGradient",
"android.graphics.Matrix",
"android.graphics.Paint",
+ "android.graphics.PathEffect",
+ "android.graphics.PorterDuffXfermode",
"android.graphics.RadialGradient",
"android.graphics.Shader",
"android.graphics.SweepGradient",
"android.graphics.Typeface",
+ "android.graphics.Xfermode",
+ "android.util.FloatMath",
};
/**
@@ -131,11 +136,8 @@
private final static String[] RENAMED_CLASSES =
new String[] {
"android.graphics.BitmapFactory", "android.graphics._Original_BitmapFactory",
- "android.graphics.DashPathEffect", "android.graphics._Original_DashPathEffect",
"android.graphics.Path", "android.graphics._Original_Path",
- "android.graphics.PorterDuffXfermode", "android.graphics._Original_PorterDuffXfermode",
"android.os.ServiceManager", "android.os._Original_ServiceManager",
- "android.util.FloatMath", "android.util._Original_FloatMath",
"android.view.SurfaceView", "android.view._Original_SurfaceView",
"android.view.accessibility.AccessibilityManager", "android.view.accessibility._Original_AccessibilityManager",
};