Merge "Change the default ssid from GoogleGuest to the opennet for the power test." into honeycomb
diff --git a/Android.mk b/Android.mk
index 5d989d1..7728b02 100644
--- a/Android.mk
+++ b/Android.mk
@@ -384,10 +384,10 @@
-hdf android.hasSamples 1 \
-samplecode $(sample_dir)/AccessibilityService \
resources/samples/AccessibilityService "Accessibility Service" \
- -samplecode $(sample_dir)/ApiDemos \
- resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/AccelerometerPlay \
resources/samples/AccelerometerPlay "Accelerometer Play" \
+ -samplecode $(sample_dir)/ApiDemos \
+ resources/samples/ApiDemos "API Demos" \
-samplecode $(sample_dir)/BackupRestore \
resources/samples/BackupRestore "Backup and Restore" \
-samplecode $(sample_dir)/BluetoothChat \
@@ -396,16 +396,20 @@
resources/samples/BusinessCard "Business Card" \
-samplecode $(sample_dir)/ContactManager \
resources/samples/ContactManager "Contact Manager" \
- -samplecode $(sample_dir)/CubeLiveWallpaper \
- resources/samples/CubeLiveWallpaper "Live Wallpaper" \
+ -samplecode $(sample_dir)/CubeLiveWallpaper \
+ resources/samples/CubeLiveWallpaper "Cube Live Wallpaper" \
-samplecode $(sample_dir)/Home \
resources/samples/Home "Home" \
+ -samplecode $(sample_dir)/Honeycomb-Gallery \
+ resources/samples/Honeycomb-Gallery "Honeycomb Gallery" \
-samplecode $(sample_dir)/JetBoy \
resources/samples/JetBoy "JetBoy" \
-samplecode $(sample_dir)/LunarLander \
resources/samples/LunarLander "Lunar Lander" \
-samplecode $(sample_dir)/MultiResolution \
resources/samples/MultiResolution "Multiple Resolutions" \
+ -samplecode $(sample_dir)/NFCDemo \
+ resources/samples/NFCDemo "NFC Demo" \
-samplecode $(sample_dir)/NotePad \
resources/samples/NotePad "Note Pad" \
-samplecode $(sample_dir)/SampleSyncAdapter \
diff --git a/CleanSpec.mk b/CleanSpec.mk
index 1acb620..337b30f 100644
--- a/CleanSpec.mk
+++ b/CleanSpec.mk
@@ -89,6 +89,7 @@
$(call add-clean-step, rm -rf $(OUT_DIR)/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/nfc/INdefTag.java)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_aacdec_intermediates)
$(call add-clean-step, rm -rf $(PRODUCT_OUT)/obj/STATIC_LIBRARIES/libstagefright_mp3dec_intermediates)
+$(call add-clean-step, rm -rf $(PRODUCT_OUT)/system/build.prop)
# ************************************************
# NEWER CLEAN STEPS MUST BE AT THE END OF THE LIST
diff --git a/api/11.xml b/api/11.xml
index 6c06a0a..52d48b6 100644
--- a/api/11.xml
+++ b/api/11.xml
@@ -2721,6 +2721,17 @@
visibility="public"
>
</field>
+<field name="calendarViewStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843613"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="candidatesTextStyleSpans"
type="int"
transient="false"
@@ -3282,6 +3293,17 @@
visibility="public"
>
</field>
+<field name="datePickerStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843612"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dateTextAppearance"
type="int"
transient="false"
@@ -8727,17 +8749,6 @@
visibility="public"
>
</field>
-<field name="solidColor"
- type="int"
- transient="false"
- volatile="false"
- value="16843594"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="soundEffectsEnabled"
type="int"
transient="false"
@@ -10905,6 +10916,17 @@
visibility="public"
>
</field>
+<field name="windowCloseOnTouchOutside"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843611"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="windowContentOverlay"
type="int"
transient="false"
@@ -13955,17 +13977,6 @@
visibility="public"
>
</field>
-<field name="up"
- type="int"
- transient="false"
- volatile="false"
- value="16908334"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="widget_frame"
type="int"
transient="false"
@@ -15982,7 +15993,7 @@
type="int"
transient="false"
volatile="false"
- value="16974069"
+ value="16974060"
static="true"
final="true"
deprecated="not deprecated"
@@ -16033,6 +16044,17 @@
visibility="public"
>
</field>
+<field name="Widget_DatePicker"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974063"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget_DropDownItem"
type="int"
transient="false"
@@ -16066,17 +16088,6 @@
visibility="public"
>
</field>
-<field name="Widget_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974061"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_ExpandableListView"
type="int"
transient="false"
@@ -16268,7 +16279,7 @@
type="int"
transient="false"
volatile="false"
- value="16974070"
+ value="16974061"
static="true"
final="true"
deprecated="not deprecated"
@@ -16308,6 +16319,17 @@
visibility="public"
>
</field>
+<field name="Widget_Holo_DatePicker"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974064"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget_Holo_DropDownItem"
type="int"
transient="false"
@@ -16341,17 +16363,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974064"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_ExpandableListView"
type="int"
transient="false"
@@ -16396,28 +16407,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974065"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974063"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light"
type="int"
transient="false"
@@ -16543,7 +16532,7 @@
type="int"
transient="false"
volatile="false"
- value="16974071"
+ value="16974062"
static="true"
final="true"
deprecated="not deprecated"
@@ -16616,17 +16605,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_Light_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974067"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light_ExpandableListView"
type="int"
transient="false"
@@ -16671,28 +16649,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974068"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974066"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light_ListPopupWindow"
type="int"
transient="false"
@@ -17221,28 +17177,6 @@
visibility="public"
>
</field>
-<field name="Widget_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974062"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974060"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_ImageWell"
type="int"
transient="false"
@@ -21657,17 +21591,6 @@
<parameter name="setSelected" type="boolean">
</parameter>
</method>
-<method name="getCustomNavigationView"
- return="android.view.View"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="getCustomView"
return="android.view.View"
abstract="true"
@@ -21734,17 +21657,6 @@
visibility="public"
>
</method>
-<method name="getSelectedNavigationItem"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="getSelectedTab"
return="android.app.ActionBar.Tab"
abstract="true"
@@ -21911,19 +21823,6 @@
<parameter name="d" type="android.graphics.drawable.Drawable">
</parameter>
</method>
-<method name="setCustomNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="view" type="android.view.View">
-</parameter>
-</method>
<method name="setCustomView"
return="void"
abstract="true"
@@ -22058,38 +21957,6 @@
<parameter name="useLogo" type="boolean">
</parameter>
</method>
-<method name="setDropdownNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.widget.SpinnerAdapter">
-</parameter>
-<parameter name="callback" type="android.app.ActionBar.OnNavigationListener">
-</parameter>
-</method>
-<method name="setDropdownNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.widget.SpinnerAdapter">
-</parameter>
-<parameter name="callback" type="android.app.ActionBar.OnNavigationListener">
-</parameter>
-<parameter name="defaultSelectedPosition" type="int">
-</parameter>
-</method>
<method name="setListNavigationCallbacks"
return="void"
abstract="true"
@@ -22131,17 +21998,6 @@
<parameter name="position" type="int">
</parameter>
</method>
-<method name="setStandardNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="setSubtitle"
return="void"
abstract="true"
@@ -22168,17 +22024,6 @@
<parameter name="resId" type="int">
</parameter>
</method>
-<method name="setTabNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="setTitle"
return="void"
abstract="true"
@@ -22216,17 +22061,6 @@
visibility="public"
>
</method>
-<field name="DISPLAY_HIDE_HOME"
- type="int"
- transient="false"
- volatile="false"
- value="4096"
- static="true"
- final="true"
- deprecated="deprecated"
- visibility="public"
->
-</field>
<field name="DISPLAY_HOME_AS_UP"
type="int"
transient="false"
@@ -22282,17 +22116,6 @@
visibility="public"
>
</field>
-<field name="NAVIGATION_MODE_DROPDOWN_LIST"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="deprecated"
- visibility="public"
->
-</field>
<field name="NAVIGATION_MODE_LIST"
type="int"
transient="false"
@@ -24311,6 +24134,19 @@
<parameter name="uri" type="android.net.Uri">
</parameter>
</method>
+<method name="setFinishOnTouchOutside"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="finish" type="boolean">
+</parameter>
+</method>
<method name="setIntent"
return="void"
abstract="false"
@@ -39754,6 +39590,16 @@
visibility="public"
>
</field>
+<field name="previewImage"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="provider"
type="android.content.ComponentName"
transient="false"
@@ -136099,6 +135945,17 @@
visibility="public"
>
</method>
+<method name="getPreserveEGLContextOnPause"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getRenderMode"
return="int"
abstract="false"
@@ -136270,6 +136127,19 @@
<parameter name="glWrapper" type="android.opengl.GLSurfaceView.GLWrapper">
</parameter>
</method>
+<method name="setPreserveEGLContextOnPause"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="preserveOnPause" type="boolean">
+</parameter>
+</method>
<method name="setRenderMode"
return="void"
abstract="false"
@@ -146702,6 +146572,16 @@
visibility="public"
>
</constructor>
+<constructor name="StrictMode.VmPolicy.Builder"
+ type="android.os.StrictMode.VmPolicy.Builder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="base" type="android.os.StrictMode.VmPolicy">
+</parameter>
+</constructor>
<method name="build"
return="android.os.StrictMode.VmPolicy"
abstract="false"
@@ -146713,6 +146593,17 @@
visibility="public"
>
</method>
+<method name="detectActivityLeaks"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="detectAll"
return="android.os.StrictMode.VmPolicy.Builder"
abstract="false"
@@ -146779,6 +146670,21 @@
visibility="public"
>
</method>
+<method name="setClassInstanceLimit"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="klass" type="java.lang.Class">
+</parameter>
+<parameter name="instanceLimit" type="int">
+</parameter>
+</method>
</class>
<class name="SystemClock"
extends="java.lang.Object"
@@ -160206,17 +160112,6 @@
visibility="public"
>
</field>
-<field name="ACTION_MTP_SESSION_END"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""android.provider.action.MTP_SESSION_END""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="ACTION_VIDEO_CAPTURE"
type="java.lang.String"
transient="false"
@@ -163328,22 +163223,22 @@
visibility="public"
>
</field>
-<field name="ACTION_INPUT_METHOD_AND_SUBTYPE_ENABLER"
+<field name="ACTION_INPUT_METHOD_SETTINGS"
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER""
+ value=""android.settings.INPUT_METHOD_SETTINGS""
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="ACTION_INPUT_METHOD_SETTINGS"
+<field name="ACTION_INPUT_METHOD_SUBTYPE_SETTINGS"
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.settings.INPUT_METHOD_SETTINGS""
+ value=""android.settings.INPUT_METHOD_SUBTYPE_SETTINGS""
static="true"
final="true"
deprecated="not deprecated"
@@ -163570,6 +163465,17 @@
visibility="public"
>
</field>
+<field name="EXTRA_INPUT_METHOD_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""input_method_id""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="Settings.NameValueTable"
extends="java.lang.Object"
@@ -166486,6 +166392,74 @@
<parameter name="d" type="float[]">
</parameter>
</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
<method name="copy2DRangeFrom"
return="void"
abstract="false"
@@ -166665,6 +166639,58 @@
<parameter name="b" type="android.graphics.Bitmap">
</parameter>
</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
<method name="copyTo"
return="void"
abstract="false"
@@ -168599,7 +168625,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="v" type="android.renderscript.Int2">
+<parameter name="v" type="android.renderscript.Long2">
</parameter>
</method>
<method name="addU32"
@@ -168612,7 +168638,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="v" type="android.renderscript.Int3">
+<parameter name="v" type="android.renderscript.Long3">
</parameter>
</method>
<method name="addU32"
@@ -168625,7 +168651,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="v" type="android.renderscript.Int4">
+<parameter name="v" type="android.renderscript.Long4">
</parameter>
</method>
<method name="addU64"
@@ -175634,6 +175660,17 @@
visibility="public"
>
</field>
+<field name="KEY_PARAM_PAN"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""pan""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="KEY_PARAM_STREAM"
type="java.lang.String"
transient="false"
@@ -175656,6 +175693,17 @@
visibility="public"
>
</field>
+<field name="KEY_PARAM_VOLUME"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""volume""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<interface name="TextToSpeech.OnInitListener"
abstract="true"
@@ -206247,25 +206295,6 @@
>
</field>
</class>
-<class name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- extends="android.util.AndroidRuntimeException"
- abstract="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- type="android.view.KeyCharacterMap.KeyCharacterMapUnavailableException"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="msg" type="java.lang.String">
-</parameter>
-</constructor>
-</class>
<class name="KeyCharacterMap.KeyData"
extends="java.lang.Object"
abstract="false"
@@ -206325,6 +206354,25 @@
>
</field>
</class>
+<class name="KeyCharacterMap.UnavailableException"
+ extends="android.util.AndroidRuntimeException"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="KeyCharacterMap.UnavailableException"
+ type="android.view.KeyCharacterMap.UnavailableException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="msg" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
<class name="KeyEvent"
extends="android.view.InputEvent"
abstract="false"
@@ -219396,6 +219444,14 @@
<parameter name="view" type="android.view.View">
</parameter>
</constructor>
+<constructor name="View.DragShadowBuilder"
+ type="android.view.View.DragShadowBuilder"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</constructor>
<method name="getView"
return="android.view.View"
abstract="false"
@@ -231248,8 +231304,21 @@
visibility="public"
>
</method>
-<method name="getSubtypes"
- return="java.util.ArrayList<android.view.inputmethod.InputMethodSubtype>"
+<method name="getSubtypeAt"
+ return="android.view.inputmethod.InputMethodSubtype"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
+<method name="getSubtypeCount"
+ return="int"
abstract="false"
native="false"
synchronized="false"
@@ -236046,6 +236115,48 @@
</parameter>
</method>
</class>
+<class name="WebStorage.Origin"
+ extends="java.lang.Object"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<method name="getOrigin"
+ return="java.lang.String"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getQuota"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+<method name="getUsage"
+ return="long"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
+</class>
<interface name="WebStorage.QuotaUpdater"
abstract="true"
static="true"
@@ -240442,6 +240553,17 @@
visibility="public"
>
</method>
+<method name="fyiWillBeAdvancedByHostKThx"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getAdapter"
return="android.widget.Adapter"
abstract="false"
@@ -240697,17 +240819,6 @@
visibility="public"
>
</method>
-<method name="willBeAdvancedByHost"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
</class>
<class name="AdapterViewFlipper"
extends="android.widget.AdapterViewAnimator"
@@ -249267,7 +249378,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="onValueChangedListener" type="android.widget.NumberPicker.OnValueChangedListener">
+<parameter name="onValueChangedListener" type="android.widget.NumberPicker.OnValueChangeListener">
</parameter>
</method>
<method name="setValue"
@@ -249374,7 +249485,7 @@
>
</field>
</interface>
-<interface name="NumberPicker.OnValueChangedListener"
+<interface name="NumberPicker.OnValueChangeListener"
abstract="true"
static="true"
final="false"
@@ -252338,21 +252449,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="viewId" type="int">
-</parameter>
-<parameter name="intent" type="android.content.Intent">
-</parameter>
-</method>
-<method name="setRemoteAdapter"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
<parameter name="appWidgetId" type="int">
</parameter>
<parameter name="viewId" type="int">
@@ -253574,19 +253670,6 @@
<parameter name="listener" type="android.widget.SearchView.OnCloseListener">
</parameter>
</method>
-<method name="setOnQueryChangeListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.widget.SearchView.OnQueryChangeListener">
-</parameter>
-</method>
<method name="setOnQueryTextFocusChangeListener"
return="void"
abstract="false"
@@ -253600,6 +253683,19 @@
<parameter name="listener" type="android.view.View.OnFocusChangeListener">
</parameter>
</method>
+<method name="setOnQueryTextListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.widget.SearchView.OnQueryTextListener">
+</parameter>
+</method>
<method name="setOnSearchClickListener"
return="void"
abstract="false"
@@ -253613,7 +253709,7 @@
<parameter name="listener" type="android.view.View.OnClickListener">
</parameter>
</method>
-<method name="setOnSuggestionSelectionListener"
+<method name="setOnSuggestionListener"
return="void"
abstract="false"
native="false"
@@ -253623,7 +253719,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="listener" type="android.widget.SearchView.OnSuggestionSelectionListener">
+<parameter name="listener" type="android.widget.SearchView.OnSuggestionListener">
</parameter>
</method>
<method name="setQuery"
@@ -253726,14 +253822,14 @@
>
</method>
</interface>
-<interface name="SearchView.OnQueryChangeListener"
+<interface name="SearchView.OnQueryTextListener"
abstract="true"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<method name="onQueryTextChanged"
+<method name="onQueryTextChange"
return="boolean"
abstract="true"
native="false"
@@ -253746,7 +253842,7 @@
<parameter name="newText" type="java.lang.String">
</parameter>
</method>
-<method name="onSubmitQuery"
+<method name="onQueryTextSubmit"
return="boolean"
abstract="true"
native="false"
@@ -253760,14 +253856,14 @@
</parameter>
</method>
</interface>
-<interface name="SearchView.OnSuggestionSelectionListener"
+<interface name="SearchView.OnSuggestionListener"
abstract="true"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<method name="onSuggestionClicked"
+<method name="onSuggestionClick"
return="boolean"
abstract="true"
native="false"
@@ -253780,7 +253876,7 @@
<parameter name="position" type="int">
</parameter>
</method>
-<method name="onSuggestionSelected"
+<method name="onSuggestionSelect"
return="boolean"
abstract="true"
native="false"
@@ -260153,7 +260249,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="arg0" type="T">
+<parameter name="t" type="T">
</parameter>
</method>
</interface>
diff --git a/api/current.xml b/api/current.xml
index 73581f1..8655ad3 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -2721,6 +2721,17 @@
visibility="public"
>
</field>
+<field name="calendarViewStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843613"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="candidatesTextStyleSpans"
type="int"
transient="false"
@@ -3282,6 +3293,17 @@
visibility="public"
>
</field>
+<field name="datePickerStyle"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843612"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="dateTextAppearance"
type="int"
transient="false"
@@ -8727,17 +8749,6 @@
visibility="public"
>
</field>
-<field name="solidColor"
- type="int"
- transient="false"
- volatile="false"
- value="16843594"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="soundEffectsEnabled"
type="int"
transient="false"
@@ -9915,6 +9926,28 @@
visibility="public"
>
</field>
+<field name="textEditSideNoPasteWindowLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843615"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
+<field name="textEditSidePasteWindowLayout"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16843614"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="textFilterEnabled"
type="int"
transient="false"
@@ -13966,17 +13999,6 @@
visibility="public"
>
</field>
-<field name="up"
- type="int"
- transient="false"
- volatile="false"
- value="16908334"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="widget_frame"
type="int"
transient="false"
@@ -15993,7 +16015,7 @@
type="int"
transient="false"
volatile="false"
- value="16974069"
+ value="16974060"
static="true"
final="true"
deprecated="not deprecated"
@@ -16044,6 +16066,17 @@
visibility="public"
>
</field>
+<field name="Widget_DatePicker"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974063"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget_DropDownItem"
type="int"
transient="false"
@@ -16077,17 +16110,6 @@
visibility="public"
>
</field>
-<field name="Widget_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974061"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_ExpandableListView"
type="int"
transient="false"
@@ -16279,7 +16301,7 @@
type="int"
transient="false"
volatile="false"
- value="16974070"
+ value="16974061"
static="true"
final="true"
deprecated="not deprecated"
@@ -16319,6 +16341,17 @@
visibility="public"
>
</field>
+<field name="Widget_Holo_DatePicker"
+ type="int"
+ transient="false"
+ volatile="false"
+ value="16974064"
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="Widget_Holo_DropDownItem"
type="int"
transient="false"
@@ -16352,17 +16385,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974064"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_ExpandableListView"
type="int"
transient="false"
@@ -16407,28 +16429,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974065"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974063"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light"
type="int"
transient="false"
@@ -16554,7 +16554,7 @@
type="int"
transient="false"
volatile="false"
- value="16974071"
+ value="16974062"
static="true"
final="true"
deprecated="not deprecated"
@@ -16627,17 +16627,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_Light_EditText_NumberPickerInputText"
- type="int"
- transient="false"
- volatile="false"
- value="16974067"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light_ExpandableListView"
type="int"
transient="false"
@@ -16682,28 +16671,6 @@
visibility="public"
>
</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974068"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_Holo_Light_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974066"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_Holo_Light_ListPopupWindow"
type="int"
transient="false"
@@ -17232,28 +17199,6 @@
visibility="public"
>
</field>
-<field name="Widget_ImageButton_NumberPickerDownButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974062"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
-<field name="Widget_ImageButton_NumberPickerUpButton"
- type="int"
- transient="false"
- volatile="false"
- value="16974060"
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="Widget_ImageWell"
type="int"
transient="false"
@@ -21668,17 +21613,6 @@
<parameter name="setSelected" type="boolean">
</parameter>
</method>
-<method name="getCustomNavigationView"
- return="android.view.View"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="getCustomView"
return="android.view.View"
abstract="true"
@@ -21745,17 +21679,6 @@
visibility="public"
>
</method>
-<method name="getSelectedNavigationItem"
- return="int"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="getSelectedTab"
return="android.app.ActionBar.Tab"
abstract="true"
@@ -21922,19 +21845,6 @@
<parameter name="d" type="android.graphics.drawable.Drawable">
</parameter>
</method>
-<method name="setCustomNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="view" type="android.view.View">
-</parameter>
-</method>
<method name="setCustomView"
return="void"
abstract="true"
@@ -22069,38 +21979,6 @@
<parameter name="useLogo" type="boolean">
</parameter>
</method>
-<method name="setDropdownNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.widget.SpinnerAdapter">
-</parameter>
-<parameter name="callback" type="android.app.ActionBar.OnNavigationListener">
-</parameter>
-</method>
-<method name="setDropdownNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-<parameter name="adapter" type="android.widget.SpinnerAdapter">
-</parameter>
-<parameter name="callback" type="android.app.ActionBar.OnNavigationListener">
-</parameter>
-<parameter name="defaultSelectedPosition" type="int">
-</parameter>
-</method>
<method name="setListNavigationCallbacks"
return="void"
abstract="true"
@@ -22142,17 +22020,6 @@
<parameter name="position" type="int">
</parameter>
</method>
-<method name="setStandardNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="setSubtitle"
return="void"
abstract="true"
@@ -22179,17 +22046,6 @@
<parameter name="resId" type="int">
</parameter>
</method>
-<method name="setTabNavigationMode"
- return="void"
- abstract="true"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="deprecated"
- visibility="public"
->
-</method>
<method name="setTitle"
return="void"
abstract="true"
@@ -22227,17 +22083,6 @@
visibility="public"
>
</method>
-<field name="DISPLAY_HIDE_HOME"
- type="int"
- transient="false"
- volatile="false"
- value="4096"
- static="true"
- final="true"
- deprecated="deprecated"
- visibility="public"
->
-</field>
<field name="DISPLAY_HOME_AS_UP"
type="int"
transient="false"
@@ -22293,17 +22138,6 @@
visibility="public"
>
</field>
-<field name="NAVIGATION_MODE_DROPDOWN_LIST"
- type="int"
- transient="false"
- volatile="false"
- value="1"
- static="true"
- final="true"
- deprecated="deprecated"
- visibility="public"
->
-</field>
<field name="NAVIGATION_MODE_LIST"
type="int"
transient="false"
@@ -39778,6 +39612,16 @@
visibility="public"
>
</field>
+<field name="previewImage"
+ type="int"
+ transient="false"
+ volatile="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
<field name="provider"
type="android.content.ComponentName"
transient="false"
@@ -146771,6 +146615,17 @@
visibility="public"
>
</method>
+<method name="detectActivityLeaks"
+ return="android.os.StrictMode.VmPolicy.Builder"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="detectAll"
return="android.os.StrictMode.VmPolicy.Builder"
abstract="false"
@@ -160279,17 +160134,6 @@
visibility="public"
>
</field>
-<field name="ACTION_MTP_SESSION_END"
- type="java.lang.String"
- transient="false"
- volatile="false"
- value=""android.provider.action.MTP_SESSION_END""
- static="true"
- final="true"
- deprecated="not deprecated"
- visibility="public"
->
-</field>
<field name="ACTION_VIDEO_CAPTURE"
type="java.lang.String"
transient="false"
@@ -163401,22 +163245,22 @@
visibility="public"
>
</field>
-<field name="ACTION_INPUT_METHOD_AND_SUBTYPE_ENABLER"
+<field name="ACTION_INPUT_METHOD_SETTINGS"
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER""
+ value=""android.settings.INPUT_METHOD_SETTINGS""
static="true"
final="true"
deprecated="not deprecated"
visibility="public"
>
</field>
-<field name="ACTION_INPUT_METHOD_SETTINGS"
+<field name="ACTION_INPUT_METHOD_SUBTYPE_SETTINGS"
type="java.lang.String"
transient="false"
volatile="false"
- value=""android.settings.INPUT_METHOD_SETTINGS""
+ value=""android.settings.INPUT_METHOD_SUBTYPE_SETTINGS""
static="true"
final="true"
deprecated="not deprecated"
@@ -163643,6 +163487,17 @@
visibility="public"
>
</field>
+<field name="EXTRA_INPUT_METHOD_ID"
+ type="java.lang.String"
+ transient="false"
+ volatile="false"
+ value=""input_method_id""
+ static="true"
+ final="true"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</field>
</class>
<class name="Settings.NameValueTable"
extends="java.lang.Object"
@@ -166559,6 +166414,74 @@
<parameter name="d" type="float[]">
</parameter>
</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copy1DRangeFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="off" type="int">
+</parameter>
+<parameter name="count" type="int">
+</parameter>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
<method name="copy2DRangeFrom"
return="void"
abstract="false"
@@ -166738,6 +166661,58 @@
<parameter name="b" type="android.graphics.Bitmap">
</parameter>
</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="int[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="short[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="byte[]">
+</parameter>
+</method>
+<method name="copyFromUnchecked"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="d" type="float[]">
+</parameter>
+</method>
<method name="copyTo"
return="void"
abstract="false"
@@ -168672,7 +168647,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="v" type="android.renderscript.Int2">
+<parameter name="v" type="android.renderscript.Long2">
</parameter>
</method>
<method name="addU32"
@@ -168685,7 +168660,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="v" type="android.renderscript.Int3">
+<parameter name="v" type="android.renderscript.Long3">
</parameter>
</method>
<method name="addU32"
@@ -168698,7 +168673,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="v" type="android.renderscript.Int4">
+<parameter name="v" type="android.renderscript.Long4">
</parameter>
</method>
<method name="addU64"
@@ -206342,25 +206317,6 @@
>
</field>
</class>
-<class name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- extends="android.util.AndroidRuntimeException"
- abstract="false"
- static="true"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<constructor name="KeyCharacterMap.KeyCharacterMapUnavailableException"
- type="android.view.KeyCharacterMap.KeyCharacterMapUnavailableException"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="msg" type="java.lang.String">
-</parameter>
-</constructor>
-</class>
<class name="KeyCharacterMap.KeyData"
extends="java.lang.Object"
abstract="false"
@@ -206420,6 +206376,25 @@
>
</field>
</class>
+<class name="KeyCharacterMap.UnavailableException"
+ extends="android.util.AndroidRuntimeException"
+ abstract="false"
+ static="true"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<constructor name="KeyCharacterMap.UnavailableException"
+ type="android.view.KeyCharacterMap.UnavailableException"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="msg" type="java.lang.String">
+</parameter>
+</constructor>
+</class>
<class name="KeyEvent"
extends="android.view.InputEvent"
abstract="false"
@@ -231351,8 +231326,21 @@
visibility="public"
>
</method>
-<method name="getSubtypes"
- return="java.util.ArrayList<android.view.inputmethod.InputMethodSubtype>"
+<method name="getSubtypeAt"
+ return="android.view.inputmethod.InputMethodSubtype"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
+<method name="getSubtypeCount"
+ return="int"
abstract="false"
native="false"
synchronized="false"
@@ -240587,6 +240575,17 @@
visibility="public"
>
</method>
+<method name="fyiWillBeAdvancedByHostKThx"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+</method>
<method name="getAdapter"
return="android.widget.Adapter"
abstract="false"
@@ -240842,17 +240841,6 @@
visibility="public"
>
</method>
-<method name="willBeAdvancedByHost"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-</method>
</class>
<class name="AdapterViewFlipper"
extends="android.widget.AdapterViewAnimator"
@@ -249412,7 +249400,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="onValueChangedListener" type="android.widget.NumberPicker.OnValueChangedListener">
+<parameter name="onValueChangedListener" type="android.widget.NumberPicker.OnValueChangeListener">
</parameter>
</method>
<method name="setValue"
@@ -249519,7 +249507,7 @@
>
</field>
</interface>
-<interface name="NumberPicker.OnValueChangedListener"
+<interface name="NumberPicker.OnValueChangeListener"
abstract="true"
static="true"
final="false"
@@ -252483,21 +252471,6 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="viewId" type="int">
-</parameter>
-<parameter name="intent" type="android.content.Intent">
-</parameter>
-</method>
-<method name="setRemoteAdapter"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
<parameter name="appWidgetId" type="int">
</parameter>
<parameter name="viewId" type="int">
@@ -253719,19 +253692,6 @@
<parameter name="listener" type="android.widget.SearchView.OnCloseListener">
</parameter>
</method>
-<method name="setOnQueryChangeListener"
- return="void"
- abstract="false"
- native="false"
- synchronized="false"
- static="false"
- final="false"
- deprecated="not deprecated"
- visibility="public"
->
-<parameter name="listener" type="android.widget.SearchView.OnQueryChangeListener">
-</parameter>
-</method>
<method name="setOnQueryTextFocusChangeListener"
return="void"
abstract="false"
@@ -253745,6 +253705,19 @@
<parameter name="listener" type="android.view.View.OnFocusChangeListener">
</parameter>
</method>
+<method name="setOnQueryTextListener"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="listener" type="android.widget.SearchView.OnQueryTextListener">
+</parameter>
+</method>
<method name="setOnSearchClickListener"
return="void"
abstract="false"
@@ -253758,7 +253731,7 @@
<parameter name="listener" type="android.view.View.OnClickListener">
</parameter>
</method>
-<method name="setOnSuggestionSelectionListener"
+<method name="setOnSuggestionListener"
return="void"
abstract="false"
native="false"
@@ -253768,7 +253741,7 @@
deprecated="not deprecated"
visibility="public"
>
-<parameter name="listener" type="android.widget.SearchView.OnSuggestionSelectionListener">
+<parameter name="listener" type="android.widget.SearchView.OnSuggestionListener">
</parameter>
</method>
<method name="setQuery"
@@ -253871,14 +253844,14 @@
>
</method>
</interface>
-<interface name="SearchView.OnQueryChangeListener"
+<interface name="SearchView.OnQueryTextListener"
abstract="true"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<method name="onQueryTextChanged"
+<method name="onQueryTextChange"
return="boolean"
abstract="true"
native="false"
@@ -253891,7 +253864,7 @@
<parameter name="newText" type="java.lang.String">
</parameter>
</method>
-<method name="onSubmitQuery"
+<method name="onQueryTextSubmit"
return="boolean"
abstract="true"
native="false"
@@ -253905,14 +253878,14 @@
</parameter>
</method>
</interface>
-<interface name="SearchView.OnSuggestionSelectionListener"
+<interface name="SearchView.OnSuggestionListener"
abstract="true"
static="true"
final="false"
deprecated="not deprecated"
visibility="public"
>
-<method name="onSuggestionClicked"
+<method name="onSuggestionClick"
return="boolean"
abstract="true"
native="false"
@@ -253925,7 +253898,7 @@
<parameter name="position" type="int">
</parameter>
</method>
-<method name="onSuggestionSelected"
+<method name="onSuggestionSelect"
return="boolean"
abstract="true"
native="false"
diff --git a/build/phone-hdpi-512-dalvik-heap.mk b/build/phone-hdpi-512-dalvik-heap.mk
index afc45ee..630cf03 100644
--- a/build/phone-hdpi-512-dalvik-heap.mk
+++ b/build/phone-hdpi-512-dalvik-heap.mk
@@ -19,5 +19,5 @@
PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapstartsize=5m \
- dalvik.vm.smallheapsize=32m \
- dalvik.vm.heapsize=32m
+ dalvik.vm.growthlimit=32m \
+ dalvik.vm.heapsize=128m
diff --git a/build/phone-hdpi-dalvik-heap.mk b/build/phone-hdpi-dalvik-heap.mk
index ee30b92..ab33b96 100644
--- a/build/phone-hdpi-dalvik-heap.mk
+++ b/build/phone-hdpi-dalvik-heap.mk
@@ -18,5 +18,4 @@
PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapstartsize=5m \
- dalvik.vm.smallheapsize=32m \
dalvik.vm.heapsize=32m
diff --git a/build/tablet-dalvik-heap.mk b/build/tablet-dalvik-heap.mk
index 9cb2f6b..37c3ec5 100644
--- a/build/tablet-dalvik-heap.mk
+++ b/build/tablet-dalvik-heap.mk
@@ -18,5 +18,5 @@
PRODUCT_PROPERTY_OVERRIDES += \
dalvik.vm.heapstartsize=5m \
- dalvik.vm.smallheapsize=48m \
- dalvik.vm.heapsize=48m
+ dalvik.vm.growthlimit=48m \
+ dalvik.vm.heapsize=256m
diff --git a/core/java/android/accounts/AccountManagerService.java b/core/java/android/accounts/AccountManagerService.java
index e6eaf71..2c99f14 100644
--- a/core/java/android/accounts/AccountManagerService.java
+++ b/core/java/android/accounts/AccountManagerService.java
@@ -722,6 +722,9 @@
final String[] argsAccountId = {String.valueOf(accountId)};
db.update(TABLE_ACCOUNTS, values, ACCOUNTS_ID + "=?", argsAccountId);
db.delete(TABLE_AUTHTOKENS, AUTHTOKENS_ACCOUNTS_ID + "=?", argsAccountId);
+ synchronized (mCacheLock) {
+ mAuthTokenCache.remove(account);
+ }
db.setTransactionSuccessful();
}
} finally {
@@ -1812,6 +1815,11 @@
try {
db.execSQL("DELETE from " + TABLE_AUTHTOKENS);
db.execSQL("UPDATE " + TABLE_ACCOUNTS + " SET " + ACCOUNTS_PASSWORD + " = ''");
+
+ synchronized (mCacheLock) {
+ mAuthTokenCache = new HashMap<Account, HashMap<String, String>>();
+ }
+
db.setTransactionSuccessful();
} finally {
db.endTransaction();
diff --git a/core/java/android/animation/package.html b/core/java/android/animation/package.html
index b66669b..ff43260 100644
--- a/core/java/android/animation/package.html
+++ b/core/java/android/animation/package.html
@@ -1,6 +1,21 @@
<html>
<body>
-Provides classes for animating values over time, and setting those values on target
-objects.
+<p>
+These classes provide functionality for the property animation system, which allows you
+to animate object properties of any type. <code>int</code>, <code>float</code>, and hexadecimal
+color values are supported by default. You can animate any other type by telling the system how
+to calculate the values for that given type with a custom {@link android.animation.TypeEvaluator}.
+</p>
+
+<p>
+You can set many different types of interpolators (contained in {@link android.view.animation}),
+specify {@link android.animation.Keyframe keyframes}, or group animations to play sequentially
+or simultaneously (with {@link android.animation.AnimatorSet}) to further control your animation
+behaviors.</p>
+
+<p>
+For a guide on how to use the property animation system, see the
+<a href="{@docRoot}guide/topics/media/index.html">Animation</a> developer guide.
+</p>
</body>
</html>
diff --git a/core/java/android/app/ActionBar.java b/core/java/android/app/ActionBar.java
index 8d5a6da..fc5fac6 100644
--- a/core/java/android/app/ActionBar.java
+++ b/core/java/android/app/ActionBar.java
@@ -49,12 +49,6 @@
* e.g. this might be presented to the user as a dropdown list.
*/
public static final int NAVIGATION_MODE_LIST = 1;
-
- /**
- * @deprecated use NAVIGATION_MODE_LIST
- */
- @Deprecated
- public static final int NAVIGATION_MODE_DROPDOWN_LIST = 1;
/**
* Tab navigation mode. Instead of static title text this mode
@@ -81,13 +75,6 @@
public static final int DISPLAY_SHOW_HOME = 0x2;
/**
- * @deprecated Display flags are now positive for consistency - 'show' instead of 'hide'.
- * Use DISPLAY_SHOW_HOME.
- */
- @Deprecated
- public static final int DISPLAY_HIDE_HOME = 0x1000;
-
- /**
* Display the 'home' element such that it appears as an 'up' affordance.
* e.g. show an arrow to the left indicating the action that will be taken.
*
@@ -173,28 +160,6 @@
public abstract void setCustomView(int resId);
/**
- * @param view
- * @deprecated Use {@link #setCustomView(View)} and {@link #setDisplayOptions(int)} instead.
- */
- @Deprecated
- public abstract void setCustomNavigationMode(View view);
-
- /**
- * Set the action bar into dropdown navigation mode and supply an adapter
- * that will provide views for navigation choices.
- *
- * @param adapter An adapter that will provide views both to display
- * the current navigation selection and populate views
- * within the dropdown navigation menu.
- * @param callback A OnNavigationListener that will receive events when the user
- * selects a navigation item.
- * @deprecated See setListNavigationCallbacks.
- */
- @Deprecated
- public abstract void setDropdownNavigationMode(SpinnerAdapter adapter,
- OnNavigationListener callback);
-
- /**
* Set the adapter and navigation callback for list navigation mode.
*
* The supplied adapter will provide views for the expanded list as well as
@@ -213,23 +178,6 @@
OnNavigationListener callback);
/**
- * Set the action bar into dropdown navigation mode and supply an adapter that will
- * provide views for navigation choices.
- *
- * @param adapter An adapter that will provide views both to display the current
- * navigation selection and populate views within the dropdown
- * navigation menu.
- * @param callback A OnNavigationListener that will receive events when the user
- * selects a navigation item.
- * @param defaultSelectedPosition Position within the provided adapter that should be
- * selected from the outset.
- * @deprecated See setListNavigationCallbacks and setSelectedNavigationItem.
- */
- @Deprecated
- public abstract void setDropdownNavigationMode(SpinnerAdapter adapter,
- OnNavigationListener callback, int defaultSelectedPosition);
-
- /**
* Set the selected navigation item in list or tabbed navigation modes.
*
* @param position Position of the item to select.
@@ -240,15 +188,6 @@
* Get the position of the selected navigation item in list or tabbed navigation modes.
*
* @return Position of the selected item.
- * @deprecated Use {@link #getSelectedNavigationIndex()} instead.
- */
- @Deprecated
- public abstract int getSelectedNavigationItem();
-
- /**
- * Get the position of the selected navigation item in list or tabbed navigation modes.
- *
- * @return Position of the selected item.
*/
public abstract int getSelectedNavigationIndex();
@@ -260,17 +199,6 @@
public abstract int getNavigationItemCount();
/**
- * Set the action bar into standard navigation mode, using the currently set title
- * and/or subtitle.
- *
- * Standard navigation mode is default. The title is automatically set to the name of
- * your Activity on startup if an action bar is present.
- * @deprecated See setNavigationMode
- */
- @Deprecated
- public abstract void setStandardNavigationMode();
-
- /**
* Set the action bar's title. This will only be displayed if
* {@link #DISPLAY_SHOW_TITLE} is set.
*
@@ -410,13 +338,6 @@
* @param d Background drawable
*/
public abstract void setBackgroundDrawable(Drawable d);
-
- /**
- * @return The current custom navigation view.
- * @deprecated Method has been renamed. Use {@link #getCustomView()}.
- */
- @Deprecated
- public abstract View getCustomNavigationView();
/**
* @return The current custom view.
@@ -476,18 +397,6 @@
public abstract int getDisplayOptions();
/**
- * Set the action bar into tabbed navigation mode.
- *
- * @see #addTab(Tab)
- * @see #insertTab(Tab, int)
- * @see #removeTab(Tab)
- * @see #removeTabAt(int)
- *
- * @deprecated See {@link #setNavigationMode(int)}
- */
- public abstract void setTabNavigationMode();
-
- /**
* Create and return a new {@link Tab}.
* This tab will not be included in the action bar until it is added.
*
diff --git a/core/java/android/app/Activity.java b/core/java/android/app/Activity.java
index 0a64070..22971a2 100644
--- a/core/java/android/app/Activity.java
+++ b/core/java/android/app/Activity.java
@@ -859,7 +859,6 @@
mFragments.restoreAllState(p, mLastNonConfigurationInstances != null
? mLastNonConfigurationInstances.fragments : null);
}
- StrictMode.noteActivityClass(this.getClass());
mFragments.dispatchCreate();
mCalled = true;
}
@@ -1762,8 +1761,11 @@
/**
* Set the activity content from a layout resource. The resource will be
* inflated, adding all top-level views to the activity.
- *
+ *
* @param layoutResID Resource ID to be inflated.
+ *
+ * @see #setContentView(android.view.View)
+ * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
*/
public void setContentView(int layoutResID) {
getWindow().setContentView(layoutResID);
@@ -1773,9 +1775,17 @@
/**
* Set the activity content to an explicit view. This view is placed
* directly into the activity's view hierarchy. It can itself be a complex
- * view hierarhcy.
+ * view hierarchy. When calling this method, the layout parameters of the
+ * specified view are ignored. Both the width and the height of the view are
+ * set by default to {@link ViewGroup.LayoutParams#MATCH_PARENT}. To use
+ * your own layout parameters, invoke
+ * {@link #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)}
+ * instead.
*
* @param view The desired content to display.
+ *
+ * @see #setContentView(int)
+ * @see #setContentView(android.view.View, android.view.ViewGroup.LayoutParams)
*/
public void setContentView(View view) {
getWindow().setContentView(view);
@@ -1785,10 +1795,13 @@
/**
* Set the activity content to an explicit view. This view is placed
* directly into the activity's view hierarchy. It can itself be a complex
- * view hierarhcy.
+ * view hierarchy.
*
* @param view The desired content to display.
* @param params Layout parameters for the view.
+ *
+ * @see #setContentView(android.view.View)
+ * @see #setContentView(int)
*/
public void setContentView(View view, ViewGroup.LayoutParams params) {
getWindow().setContentView(view, params);
@@ -4433,6 +4446,9 @@
mStopped = true;
}
mResumed = false;
+
+ // Check for Activity leaks, if enabled.
+ StrictMode.conditionallyCheckInstanceCounts();
}
final void performDestroy() {
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index d5aa961..133a7d0 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -64,8 +64,11 @@
static public int staticGetMemoryClass() {
// Really brain dead right now -- just take this from the configured
// vm heap size, and assume it is in megabytes and thus ends with "m".
- String vmHeapSize = SystemProperties.get("dalvik.vm.smallheapsize", "16m");
- return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+ String vmHeapSize = SystemProperties.get("dalvik.vm.growthlimit", "");
+ if (vmHeapSize != null && !"".equals(vmHeapSize)) {
+ return Integer.parseInt(vmHeapSize.substring(0, vmHeapSize.length()-1));
+ }
+ return staticGetLargeMemoryClass();
}
/**
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index db046ef..2389f01 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -1616,6 +1616,7 @@
java.lang.ClassLoader cl = r.packageInfo.getClassLoader();
activity = mInstrumentation.newActivity(
cl, component.getClassName(), r.intent);
+ StrictMode.incrementExpectedActivityCount(activity.getClass());
r.intent.setExtrasClassLoader(cl);
if (r.state != null) {
r.state.setClassLoader(cl);
@@ -2686,8 +2687,10 @@
private final ActivityClientRecord performDestroyActivity(IBinder token, boolean finishing,
int configChanges, boolean getNonConfigInstance) {
ActivityClientRecord r = mActivities.get(token);
+ Class activityClass = null;
if (localLOGV) Slog.v(TAG, "Performing finish of " + r);
if (r != null) {
+ activityClass = r.activity.getClass();
r.activity.mConfigChangeFlags |= configChanges;
if (finishing) {
r.activity.mFinished = true;
@@ -2765,7 +2768,7 @@
}
}
mActivities.remove(token);
-
+ StrictMode.decrementExpectedActivityCount(activityClass);
return r;
}
@@ -3463,7 +3466,7 @@
}
if ((data.appInfo.flags&ApplicationInfo.FLAG_LARGE_HEAP) != 0) {
- // XXX bump up Dalvik's heap.
+ dalvik.system.VMRuntime.getRuntime().clearGrowthLimit();
}
// If the app is being launched for full backup or restore, bring it up in
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 079d4cf..50e56c7 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -570,6 +570,9 @@
} catch (NameNotFoundException e) {
Log.w("PackageManager", "Failure retrieving resources for"
+ appInfo.packageName);
+ } catch (Resources.NotFoundException e) {
+ Log.w("PackageManager", "Failure retrieving resources for"
+ + appInfo.packageName + ": " + e.getMessage());
} catch (RuntimeException e) {
// If an exception was thrown, fall through to return
// default icon.
diff --git a/core/java/android/app/FragmentBreadCrumbs.java b/core/java/android/app/FragmentBreadCrumbs.java
index 72a8e9a..3f045ac 100644
--- a/core/java/android/app/FragmentBreadCrumbs.java
+++ b/core/java/android/app/FragmentBreadCrumbs.java
@@ -29,9 +29,9 @@
/**
* Helper class for showing "bread crumbs" representing the fragment
* stack in an activity. This is intended to be used with
- * {@link ActionBar#setCustomNavigationMode(View)
- * ActionBar.setCustomNavigationMode(View)} to place the bread crumbs in
- * the navigation area of the action bar.
+ * {@link ActionBar#setCustomView(View)
+ * ActionBar.setCustomView(View)} to place the bread crumbs in
+ * the action bar.
*
* <p>The default style for this view is
* {@link android.R.style#Widget_FragmentBreadCrumbs}.
diff --git a/core/java/android/app/LoaderManager.java b/core/java/android/app/LoaderManager.java
index ffe2a5d..fc5f5fc 100644
--- a/core/java/android/app/LoaderManager.java
+++ b/core/java/android/app/LoaderManager.java
@@ -203,20 +203,25 @@
boolean mStarted;
boolean mRetaining;
boolean mRetainingStarted;
+
+ boolean mCreatingLoader;
final class LoaderInfo implements Loader.OnLoadCompleteListener<Object> {
final int mId;
final Bundle mArgs;
LoaderManager.LoaderCallbacks<Object> mCallbacks;
Loader<Object> mLoader;
+ boolean mHaveData;
+ boolean mDeliveredData;
Object mData;
- Object mDeliveredData;
boolean mStarted;
boolean mRetaining;
boolean mRetainingStarted;
boolean mDestroyed;
boolean mListenerRegistered;
+ LoaderInfo mPendingLoader;
+
public LoaderInfo(int id, Bundle args, LoaderManager.LoaderCallbacks<Object> callbacks) {
mId = id;
mArgs = args;
@@ -280,7 +285,7 @@
}
}
- if (mStarted && mData != null) {
+ if (mStarted && mHaveData) {
// This loader has retained its data, either completely across
// a configuration change or just whatever the last data set
// was after being restarted from a stop, and now at the point of
@@ -307,9 +312,9 @@
void destroy() {
if (DEBUG) Log.v(TAG, " Destroying: " + this);
mDestroyed = true;
- boolean needReset = mDeliveredData != null;
- mDeliveredData = null;
- if (mCallbacks != null && mLoader != null && mData != null && needReset) {
+ boolean needReset = mDeliveredData;
+ mDeliveredData = false;
+ if (mCallbacks != null && mLoader != null && mHaveData && needReset) {
if (DEBUG) Log.v(TAG, " Reseting: " + this);
String lastBecause = null;
if (mActivity != null) {
@@ -326,6 +331,7 @@
}
mCallbacks = null;
mData = null;
+ mHaveData = false;
if (mLoader != null) {
if (mListenerRegistered) {
mListenerRegistered = false;
@@ -333,20 +339,44 @@
}
mLoader.reset();
}
+ if (mPendingLoader != null) {
+ mPendingLoader.destroy();
+ }
}
@Override public void onLoadComplete(Loader<Object> loader, Object data) {
if (DEBUG) Log.v(TAG, "onLoadComplete: " + this);
-
+
if (mDestroyed) {
if (DEBUG) Log.v(TAG, " Ignoring load complete -- destroyed");
return;
}
+
+ if (mLoaders.get(mId) != this) {
+ // This data is not coming from the current active loader.
+ // We don't care about it.
+ if (DEBUG) Log.v(TAG, " Ignoring load complete -- not active");
+ return;
+ }
+
+ LoaderInfo pending = mPendingLoader;
+ if (pending != null) {
+ // There is a new request pending and we were just
+ // waiting for the old one to complete before starting
+ // it. So now it is time, switch over to the new loader.
+ if (DEBUG) Log.v(TAG, " Switching to pending loader: " + pending);
+ mPendingLoader = null;
+ mLoaders.put(mId, null);
+ destroy();
+ installLoader(pending);
+ return;
+ }
// Notify of the new data so the app can switch out the old data before
// we try to destroy it.
- if (data == null || mData != data) {
+ if (mData != data || !mHaveData) {
mData = data;
+ mHaveData = true;
if (mStarted) {
callOnLoadFinished(loader, data);
}
@@ -360,7 +390,7 @@
// clean it up.
LoaderInfo info = mInactiveLoaders.get(mId);
if (info != null && info != this) {
- info.mDeliveredData = null;
+ info.mDeliveredData = false;
info.destroy();
mInactiveLoaders.remove(mId);
}
@@ -382,7 +412,7 @@
mActivity.mFragments.mNoTransactionsBecause = lastBecause;
}
}
- mDeliveredData = data;
+ mDeliveredData = true;
}
}
@@ -407,13 +437,21 @@
if (mLoader != null) {
mLoader.dump(prefix + " ", fd, writer, args);
}
- writer.print(prefix); writer.print("mData="); writer.println(mData);
- writer.print(prefix); writer.print("mDeliveredData="); writer.println(mDeliveredData);
+ if (mHaveData || mDeliveredData) {
+ writer.print(prefix); writer.print("mHaveData="); writer.print(mHaveData);
+ writer.print(" mDeliveredData="); writer.println(mDeliveredData);
+ writer.print(prefix); writer.print("mData="); writer.println(mData);
+ }
writer.print(prefix); writer.print("mStarted="); writer.print(mStarted);
writer.print(" mRetaining="); writer.print(mRetaining);
writer.print(" mDestroyed="); writer.println(mDestroyed);
writer.print(prefix); writer.print("mListenerRegistered=");
writer.println(mListenerRegistered);
+ if (mPendingLoader != null) {
+ writer.print(prefix); writer.println("Pending Loader ");
+ writer.print(mPendingLoader); writer.println(":");
+ mPendingLoader.dump(prefix + " ", fd, writer, args);
+ }
}
}
@@ -429,34 +467,77 @@
private LoaderInfo createLoader(int id, Bundle args,
LoaderManager.LoaderCallbacks<Object> callback) {
LoaderInfo info = new LoaderInfo(id, args, (LoaderManager.LoaderCallbacks<Object>)callback);
- mLoaders.put(id, info);
Loader<Object> loader = callback.onCreateLoader(id, args);
info.mLoader = (Loader<Object>)loader;
+ return info;
+ }
+
+ private LoaderInfo createAndInstallLoader(int id, Bundle args,
+ LoaderManager.LoaderCallbacks<Object> callback) {
+ try {
+ mCreatingLoader = true;
+ LoaderInfo info = createLoader(id, args, callback);
+ installLoader(info);
+ return info;
+ } finally {
+ mCreatingLoader = false;
+ }
+ }
+
+ void installLoader(LoaderInfo info) {
+ mLoaders.put(info.mId, info);
if (mStarted) {
// The activity will start all existing loaders in it's onStart(),
// so only start them here if we're past that point of the activitiy's
// life cycle
info.start();
}
- return info;
}
+ /**
+ * Call to initialize a particular ID with a Loader. If this ID already
+ * has a Loader associated with it, it is left unchanged and any previous
+ * callbacks replaced with the newly provided ones. If there is not currently
+ * a Loader for the ID, a new one is created and started.
+ *
+ * <p>This function should generally be used when a component is initializing,
+ * to ensure that a Loader it relies on is created. This allows it to re-use
+ * an existing Loader's data if there already is one, so that for example
+ * when an {@link Activity} is re-created after a configuration change it
+ * does not need to re-create its loaders.
+ *
+ * <p>Note that in the case where an existing Loader is re-used, the
+ * <var>args</var> given here <em>will be ignored</em> because you will
+ * continue using the previous Loader.
+ *
+ * @param id A unique (to this LoaderManager instance) identifier under
+ * which to manage the new Loader.
+ * @param args Optional arguments that will be propagated to
+ * {@link LoaderCallbacks#onCreateLoader(int, Bundle) LoaderCallbacks.onCreateLoader()}.
+ * @param callback Interface implementing management of this Loader. Required.
+ * Its onCreateLoader() method will be called while inside of the function to
+ * instantiate the Loader object.
+ */
@SuppressWarnings("unchecked")
public <D> Loader<D> initLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback) {
+ if (mCreatingLoader) {
+ throw new IllegalStateException("Called while creating a loader");
+ }
+
LoaderInfo info = mLoaders.get(id);
if (DEBUG) Log.v(TAG, "initLoader in " + this + ": args=" + args);
if (info == null) {
// Loader doesn't already exist; create.
- info = createLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback);
+ info = createAndInstallLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback);
if (DEBUG) Log.v(TAG, " Created new loader " + info);
} else {
if (DEBUG) Log.v(TAG, " Re-using existing loader " + info);
info.mCallbacks = (LoaderManager.LoaderCallbacks<Object>)callback;
}
- if (info.mData != null && mStarted) {
+ if (info.mHaveData && mStarted) {
// If the loader has already generated its data, report it now.
info.callOnLoadFinished(info.mLoader, info.mData);
}
@@ -464,29 +545,73 @@
return (Loader<D>)info.mLoader;
}
+ /**
+ * Call to re-create the Loader associated with a particular ID. If there
+ * is currently a Loader associated with this ID, it will be
+ * canceled/stopped/destroyed as appropriate. A new Loader with the given
+ * arguments will be created and its data delivered to you once available.
+ *
+ * <p>This function does some throttling of Loaders. If too many Loaders
+ * have been created for the given ID but not yet generated their data,
+ * new calls to this function will create and return a new Loader but not
+ * actually start it until some previous loaders have completed.
+ *
+ * <p>After calling this function, any previous Loaders associated with
+ * this ID will be considered invalid, and you will receive no further
+ * data updates from them.
+ *
+ * @param id A unique (to this LoaderManager instance) identifier under
+ * which to manage the new Loader.
+ * @param args Optional arguments that will be propagated to
+ * {@link LoaderCallbacks#onCreateLoader(int, Bundle) LoaderCallbacks.onCreateLoader()}.
+ * @param callback Interface implementing management of this Loader. Required.
+ * Its onCreateLoader() method will be called while inside of the function to
+ * instantiate the Loader object.
+ */
@SuppressWarnings("unchecked")
public <D> Loader<D> restartLoader(int id, Bundle args, LoaderManager.LoaderCallbacks<D> callback) {
+ if (mCreatingLoader) {
+ throw new IllegalStateException("Called while creating a loader");
+ }
+
LoaderInfo info = mLoaders.get(id);
if (DEBUG) Log.v(TAG, "restartLoader in " + this + ": args=" + args);
if (info != null) {
LoaderInfo inactive = mInactiveLoaders.get(id);
if (inactive != null) {
- if (info.mData != null) {
+ if (info.mHaveData) {
// This loader now has data... we are probably being
// called from within onLoadComplete, where we haven't
// yet destroyed the last inactive loader. So just do
// that now.
if (DEBUG) Log.v(TAG, " Removing last inactive loader: " + info);
- inactive.mDeliveredData = null;
+ inactive.mDeliveredData = false;
inactive.destroy();
mInactiveLoaders.put(id, info);
} else {
// We already have an inactive loader for this ID that we are
- // waiting for! Now we have three active loaders... let's just
- // drop the one in the middle, since we are still waiting for
- // its result but that result is already out of date.
- if (DEBUG) Log.v(TAG, " Removing intermediate loader: " + info);
- info.destroy();
+ // waiting for! What to do, what to do...
+ if (!info.mStarted) {
+ // The current Loader has not been started... we thus
+ // have no reason to keep it around, so bam, slam,
+ // thank-you-ma'am.
+ if (DEBUG) Log.v(TAG, " Current loader is stopped; replacing");
+ mLoaders.put(id, null);
+ info.destroy();
+ } else {
+ // Now we have three active loaders... we'll queue
+ // up this request to be processed once one of the other loaders
+ // finishes.
+ if (info.mPendingLoader != null) {
+ if (DEBUG) Log.v(TAG, " Removing pending loader: " + info.mPendingLoader);
+ info.mPendingLoader.destroy();
+ info.mPendingLoader = null;
+ }
+ if (DEBUG) Log.v(TAG, " Enqueuing as new pending loader");
+ info.mPendingLoader = createLoader(id, args,
+ (LoaderManager.LoaderCallbacks<Object>)callback);
+ return (Loader<D>)info.mPendingLoader.mLoader;
+ }
}
} else {
// Keep track of the previous instance of this loader so we can destroy
@@ -496,11 +621,22 @@
}
}
- info = createLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback);
+ info = createAndInstallLoader(id, args, (LoaderManager.LoaderCallbacks<Object>)callback);
return (Loader<D>)info.mLoader;
}
+ /**
+ * Rip down, tear apart, shred to pieces a current Loader ID. After returning
+ * from this function, any Loader objects associated with this ID are
+ * destroyed. Any data associated with them is destroyed. You better not
+ * be using it when you do this.
+ * @param id Identifier of the Loader to be destroyed.
+ */
public void destroyLoader(int id) {
+ if (mCreatingLoader) {
+ throw new IllegalStateException("Called while creating a loader");
+ }
+
if (DEBUG) Log.v(TAG, "destroyLoader in " + this + " of " + id);
int idx = mLoaders.indexOfKey(id);
if (idx >= 0) {
@@ -516,11 +652,22 @@
}
}
+ /**
+ * Return the most recent Loader object associated with the
+ * given ID.
+ */
@SuppressWarnings("unchecked")
public <D> Loader<D> getLoader(int id) {
+ if (mCreatingLoader) {
+ throw new IllegalStateException("Called while creating a loader");
+ }
+
LoaderInfo loaderInfo = mLoaders.get(id);
if (loaderInfo != null) {
- return (Loader<D>)mLoaders.get(id).mLoader;
+ if (loaderInfo.mPendingLoader != null) {
+ return (Loader<D>)loaderInfo.mPendingLoader.mLoader;
+ }
+ return (Loader<D>)loaderInfo.mLoader;
}
return null;
}
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index 0243b02..de84c56 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -34,6 +34,9 @@
* A class that represents how a persistent notification is to be presented to
* the user using the {@link android.app.NotificationManager}.
*
+ * <p>The {@link Notification.Builder Notification.Builder} has been added to make it
+ * easier to construct Notifications.</p>
+ *
* <p>For a guide to creating notifications, see the
* <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Creating Status
* Bar Notifications</a> document in the Dev Guide.</p>
@@ -119,15 +122,8 @@
/**
* An intent to launch instead of posting the notification to the status bar.
- * Only for use with extremely high-priority notifications demanding the user's
- * <strong>immediate</strong> attention, such as an incoming phone call or
- * alarm clock that the user has explicitly set to a particular time.
- * If this facility is used for something else, please give the user an option
- * to turn it off and use a normal notification, as this can be extremely
- * disruptive.
- *
- * <p>Use with {@link #FLAG_HIGH_PRIORITY} to ensure that this notification
- * will reach the user even when other notifications are suppressed.
+ *
+ * @see Notification.Builder#setFullScreenIntent
*/
public PendingIntent fullScreenIntent;
@@ -278,7 +274,7 @@
/**
* Bit to be bitwise-ored into the {@link #flags} field that should be
* set if the notification should be canceled when it is clicked by the
- * user.
+ * user. On tablets, the
*/
public static final int FLAG_AUTO_CANCEL = 0x00000010;
@@ -618,6 +614,10 @@
return sb.toString();
}
+ /**
+ * Builder class for {@link Notification} objects. Allows easier control over
+ * all the flags, as well as help constructing the typical notification layouts.
+ */
public static class Builder {
private Context mContext;
@@ -644,6 +644,16 @@
private int mDefaults;
private int mFlags;
+ /**
+ * Constructor.
+ *
+ * Automatically sets the when field to {@link System#currentTimeMillis()
+ * System.currentTimeMllis()} and the audio stream to the {@link #STREAM_DEFAULT}.
+ *
+ * @param context A {@link Context} that will be used to construct the
+ * RemoteViews. The Context will not be held past the lifetime of this
+ * Builder object.
+ */
public Builder(Context context) {
mContext = context;
@@ -652,96 +662,192 @@
mAudioStreamType = STREAM_DEFAULT;
}
+ /**
+ * Set the time that the event occurred. Notifications in the panel are
+ * sorted by this time.
+ */
public Builder setWhen(long when) {
mWhen = when;
return this;
}
+ /**
+ * Set the small icon to use in the notification layouts. Different classes of devices
+ * may return different sizes. See the UX guidelines for more information on how to
+ * design these icons.
+ *
+ * @param icon A resource ID in the application's package of the drawble to use.
+ */
public Builder setSmallIcon(int icon) {
mSmallIcon = icon;
return this;
}
+ /**
+ * A variant of {@link #setSmallIcon(int) setSmallIcon(int)} that takes an additional
+ * level parameter for when the icon is a {@link android.graphics.drawable.LevelListDrawable
+ * LevelListDrawable}.
+ *
+ * @param icon A resource ID in the application's package of the drawble to use.
+ * @param level The level to use for the icon.
+ *
+ * @see android.graphics.drawable.LevelListDrawable
+ */
public Builder setSmallIcon(int icon, int level) {
mSmallIcon = icon;
mSmallIconLevel = level;
return this;
}
+ /**
+ * Set the title (first row) of the notification, in a standard notification.
+ */
public Builder setContentTitle(CharSequence title) {
mContentTitle = title;
return this;
}
+ /**
+ * Set the text (second row) of the notification, in a standard notification.
+ */
public Builder setContentText(CharSequence text) {
mContentText = text;
return this;
}
+ /**
+ * Set the large number at the right-hand side of the notification. This is
+ * equivalent to setContentInfo, although it might show the number in a different
+ * font size for readability.
+ */
public Builder setNumber(int number) {
mNumber = number;
return this;
}
+ /**
+ * Set the large text at the right-hand side of the notification.
+ */
public Builder setContentInfo(CharSequence info) {
mContentInfo = info;
return this;
}
+ /**
+ * Supply a custom RemoteViews to use instead of the standard one.
+ */
public Builder setContent(RemoteViews views) {
mContentView = views;
return this;
}
+ /**
+ * Supply a {@link PendingIntent} to send when the notification is clicked.
+ * If you do not supply an intent, you can now add PendingIntents to individual
+ * views to be launched when clicked by calling {@link RemoteViews#setOnClickPendingIntent
+ * RemoteViews.setOnClickPendingIntent(int,PendingIntent)}.
+ */
public Builder setContentIntent(PendingIntent intent) {
mContentIntent = intent;
return this;
}
+ /**
+ * Supply a {@link PendingIntent} to send when the notification is cleared by the user
+ * directly from the notification panel. For example, this intent is sent when the user
+ * clicks the "Clear all" button, or the individual "X" buttons on notifications. This
+ * intent is not sent when the application calls {@link NotificationManager#cancel
+ * NotificationManager.cancel(int)}.
+ */
public Builder setDeleteIntent(PendingIntent intent) {
mDeleteIntent = intent;
return this;
}
+ /**
+ * An intent to launch instead of posting the notification to the status bar.
+ * Only for use with extremely high-priority notifications demanding the user's
+ * <strong>immediate</strong> attention, such as an incoming phone call or
+ * alarm clock that the user has explicitly set to a particular time.
+ * If this facility is used for something else, please give the user an option
+ * to turn it off and use a normal notification, as this can be extremely
+ * disruptive.
+ *
+ * @param intent The pending intent to launch.
+ * @param highPriority Passing true will cause this notification to be sent
+ * even if other notifications are suppressed.
+ */
public Builder setFullScreenIntent(PendingIntent intent, boolean highPriority) {
mFullScreenIntent = intent;
setFlag(FLAG_HIGH_PRIORITY, highPriority);
return this;
}
+ /**
+ * Set the text that is displayed in the status bar when the notification first
+ * arrives.
+ */
public Builder setTicker(CharSequence tickerText) {
mTickerText = tickerText;
return this;
}
+ /**
+ * Set the text that is displayed in the status bar when the notification first
+ * arrives, and also a RemoteViews object that may be displayed instead on some
+ * devices.
+ */
public Builder setTicker(CharSequence tickerText, RemoteViews views) {
mTickerText = tickerText;
mTickerView = views;
return this;
}
+ /**
+ * Set the large icon that is shown in the ticker and notification.
+ */
public Builder setLargeIcon(Bitmap icon) {
mLargeIcon = icon;
return this;
}
+ /**
+ * Set the sound to play. It will play on the default stream.
+ */
public Builder setSound(Uri sound) {
mSound = sound;
mAudioStreamType = STREAM_DEFAULT;
return this;
}
+ /**
+ * Set the sound to play. It will play on the stream you supply.
+ *
+ * @see #STREAM_DEFAULT
+ * @see AudioManager for the <code>STREAM_</code> constants.
+ */
public Builder setSound(Uri sound, int streamType) {
mSound = sound;
mAudioStreamType = streamType;
return this;
}
+ /**
+ * Set the vibration pattern to use.
+ *
+ * @see android.os.Vibrator for a discussion of the <code>pattern</code>
+ * parameter.
+ */
public Builder setVibrate(long[] pattern) {
mVibrate = pattern;
return this;
}
+ /**
+ * Set the argb value that you would like the LED on the device to blnk, as well as the
+ * rate. The rate is specified in terms of the number of milliseconds to be on
+ * and then the number of milliseconds to be off.
+ */
public Builder setLights(int argb, int onMs, int offMs) {
mLedArgb = argb;
mLedOnMs = onMs;
@@ -749,21 +855,51 @@
return this;
}
+ /**
+ * Set whether this is an ongoing notification.
+ *
+ * <p>Ongoing notifications differ from regular notifications in the following ways:
+ * <ul>
+ * <li>Ongoing notifications are sorted above the regular notifications in the
+ * notification panel.</li>
+ * <li>Ongoing notifications do not have an 'X' close button, and are not affected
+ * by the "Clear all" button.
+ * </ul>
+ */
public Builder setOngoing(boolean ongoing) {
setFlag(FLAG_ONGOING_EVENT, ongoing);
return this;
}
+ /**
+ * Set this flag if you would only like the sound, vibrate
+ * and ticker to be played if the notification is not already showing.
+ */
public Builder setOnlyAlertOnce(boolean onlyAlertOnce) {
setFlag(FLAG_ONLY_ALERT_ONCE, onlyAlertOnce);
return this;
}
+ /**
+ * Setting this flag will make it so the notification is automatically
+ * canceled when the user clicks it in the panel. The PendingIntent
+ * set with {@link #setDeleteIntent} will be broadcast when the notification
+ * is canceled.
+ */
public Builder setAutoCancel(boolean autoCancel) {
setFlag(FLAG_AUTO_CANCEL, autoCancel);
return this;
}
+ /**
+ * Set the default notification options that will be used.
+ * <p>
+ * The value should be one or more of the following fields combined with
+ * bitwise-or:
+ * {@link #DEFAULT_SOUND}, {@link #DEFAULT_VIBRATE}, {@link #DEFAULT_LIGHTS}.
+ * <p>
+ * For all default values, use {@link #DEFAULT_ALL}.
+ */
public Builder setDefaults(int defaults) {
mDefaults = defaults;
return this;
@@ -834,6 +970,10 @@
}
}
+ /**
+ * Combine all of the options that have been set and return a new {@link Notification}
+ * object.
+ */
public Notification getNotification() {
Notification n = new Notification();
n.when = mWhen;
diff --git a/core/java/android/app/SearchDialog.java b/core/java/android/app/SearchDialog.java
index 4d19b62..e95a23d 100644
--- a/core/java/android/app/SearchDialog.java
+++ b/core/java/android/app/SearchDialog.java
@@ -164,8 +164,8 @@
mSearchView = (SearchView) findViewById(com.android.internal.R.id.search_view);
mSearchView.setSubmitButtonEnabled(true);
mSearchView.setOnCloseListener(mOnCloseListener);
- mSearchView.setOnQueryChangeListener(mOnQueryChangeListener);
- mSearchView.setOnSuggestionSelectionListener(mOnSuggestionSelectionListener);
+ mSearchView.setOnQueryTextListener(mOnQueryChangeListener);
+ mSearchView.setOnSuggestionListener(mOnSuggestionSelectionListener);
// TODO: Move the badge logic to SearchView or move the badge to search_bar.xml
mBadgeLabel = (TextView) mSearchView.findViewById(com.android.internal.R.id.search_badge);
@@ -678,27 +678,27 @@
}
};
- private final SearchView.OnQueryChangeListener mOnQueryChangeListener =
- new SearchView.OnQueryChangeListener() {
+ private final SearchView.OnQueryTextListener mOnQueryChangeListener =
+ new SearchView.OnQueryTextListener() {
- public boolean onSubmitQuery(String query) {
+ public boolean onQueryTextSubmit(String query) {
dismiss();
return false;
}
- public boolean onQueryTextChanged(String newText) {
+ public boolean onQueryTextChange(String newText) {
return false;
}
};
- private final SearchView.OnSuggestionSelectionListener mOnSuggestionSelectionListener =
- new SearchView.OnSuggestionSelectionListener() {
+ private final SearchView.OnSuggestionListener mOnSuggestionSelectionListener =
+ new SearchView.OnSuggestionListener() {
- public boolean onSuggestionSelected(int position) {
+ public boolean onSuggestionSelect(int position) {
return false;
}
- public boolean onSuggestionClicked(int position) {
+ public boolean onSuggestionClick(int position) {
dismiss();
return false;
}
diff --git a/core/java/android/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java
index a3db01d..fe33782 100644
--- a/core/java/android/appwidget/AppWidgetProviderInfo.java
+++ b/core/java/android/appwidget/AppWidgetProviderInfo.java
@@ -121,8 +121,6 @@
*
* <p>This field corresponds to the <code>android:previewImage</code> attribute in
* the <code><receiver></code> element in the AndroidManifest.xml file.
- *
- * @hide Pending API approval
*/
public int previewImage;
diff --git a/core/java/android/bluetooth/BluetoothAdapter.java b/core/java/android/bluetooth/BluetoothAdapter.java
index b2185ad..fb3744d 100644
--- a/core/java/android/bluetooth/BluetoothAdapter.java
+++ b/core/java/android/bluetooth/BluetoothAdapter.java
@@ -1025,17 +1025,18 @@
return null;
}
- /*
+ /**
* Get the profile proxy object associated with the profile.
*
- * <p>Profile can be one of {@link BluetoothProfile.HEADSET} or
- * {@link BluetoothProfile.A2DP}. Clients must implements
+ * <p>Profile can be one of {@link BluetoothProfile#HEADSET} or
+ * {@link BluetoothProfile#A2DP}. Clients must implements
* {@link BluetoothProfile.ServiceListener} to get notified of
* the connection status and to get the proxy object.
*
* @param context Context of the application
* @param listener The service Listener for connection callbacks.
- * @param profile
+ * @param profile The Bluetooth profile; either {@link BluetoothProfile#HEADSET}
+ * or {@link BluetoothProfile#A2DP}.
* @return true on success, false on error
*/
public boolean getProfileProxy(Context context, BluetoothProfile.ServiceListener listener,
diff --git a/core/java/android/bluetooth/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java
index bc8a836..a70de59 100644
--- a/core/java/android/bluetooth/BluetoothInputDevice.java
+++ b/core/java/android/bluetooth/BluetoothInputDevice.java
@@ -85,6 +85,19 @@
*/
public static final int PRIORITY_UNDEFINED = -1;
+ /**
+ * Return codes for the connect and disconnect Bluez / Dbus calls.
+ */
+ public static final int INPUT_DISCONNECT_FAILED_NOT_CONNECTED = 5000;
+
+ public static final int INPUT_CONNECT_FAILED_ALREADY_CONNECTED = 5001;
+
+ public static final int INPUT_CONNECT_FAILED_ATTEMPT_FAILED = 5002;
+
+ public static final int INPUT_OPERATION_GENERIC_FAILURE = 5003;
+
+ public static final int INPUT_OPERATION_SUCCESS = 5004;
+
private final IBluetooth mService;
private final Context mContext;
diff --git a/core/java/android/bluetooth/BluetoothPan.java b/core/java/android/bluetooth/BluetoothPan.java
index 7dee25e..1f07349 100644
--- a/core/java/android/bluetooth/BluetoothPan.java
+++ b/core/java/android/bluetooth/BluetoothPan.java
@@ -70,6 +70,19 @@
public static final int STATE_CONNECTED = 2;
public static final int STATE_DISCONNECTING = 3;
+ /**
+ * Return codes for the connect and disconnect Bluez / Dbus calls.
+ */
+ public static final int PAN_DISCONNECT_FAILED_NOT_CONNECTED = 1000;
+
+ public static final int PAN_CONNECT_FAILED_ALREADY_CONNECTED = 1001;
+
+ public static final int PAN_CONNECT_FAILED_ATTEMPT_FAILED = 1002;
+
+ public static final int PAN_OPERATION_GENERIC_FAILURE = 1003;
+
+ public static final int PAN_OPERATION_SUCCESS = 1004;
+
private final IBluetooth mService;
private final Context mContext;
diff --git a/core/java/android/inputmethodservice/InputMethodService.java b/core/java/android/inputmethodservice/InputMethodService.java
index 4d25bac..f35a438 100644
--- a/core/java/android/inputmethodservice/InputMethodService.java
+++ b/core/java/android/inputmethodservice/InputMethodService.java
@@ -393,6 +393,10 @@
if (onShowInputRequested(flags, false)) {
showWindow(true);
}
+ // If user uses hard keyboard, IME button should always be shown.
+ if (!onEvaluateInputViewShown()) {
+ mImm.setIMEButtonVisible(mToken, true);
+ }
if (resultReceiver != null) {
resultReceiver.send(wasVis != isInputViewShown()
? InputMethodManager.RESULT_SHOWN
@@ -557,7 +561,7 @@
*/
public int touchableInsets;
}
-
+
/**
* You can call this to customize the theme used by your IME's window.
* This theme should typically be one that derives from
@@ -573,7 +577,7 @@
}
mTheme = theme;
}
-
+
@Override public void onCreate() {
mTheme = Resources.selectSystemTheme(mTheme,
getApplicationInfo().targetSdkVersion,
@@ -699,6 +703,10 @@
// Otherwise hide the window.
hideWindow();
}
+ // If user uses hard keyboard, IME button should always be shown.
+ if (!onEvaluateInputViewShown()) {
+ mImm.setIMEButtonVisible(mToken, true);
+ }
}
}
@@ -1386,10 +1394,10 @@
}
mInputViewStarted = false;
mCandidatesViewStarted = false;
+ mImm.setIMEButtonVisible(mToken, false);
if (mWindowVisible) {
mWindow.hide();
mWindowVisible = false;
- mImm.setIMEButtonVisible(mToken, false);
onWindowHidden();
mWindowWasVisible = false;
}
diff --git a/core/java/android/inputmethodservice/Keyboard.java b/core/java/android/inputmethodservice/Keyboard.java
index 75c945b..10386f8 100644
--- a/core/java/android/inputmethodservice/Keyboard.java
+++ b/core/java/android/inputmethodservice/Keyboard.java
@@ -97,11 +97,11 @@
private boolean mShifted;
/** Key instance for the shift key, if present */
- private Key mShiftKey;
-
+ private Key[] mShiftKeys = { null, null };
+
/** Key index for the shift key, if present */
- private int mShiftKeyIndex = -1;
-
+ private int[] mShiftKeyIndices = {-1, -1};
+
/** Current key width, while loading the keyboard */
private int mKeyWidth;
@@ -656,8 +656,10 @@
}
public boolean setShifted(boolean shiftState) {
- if (mShiftKey != null) {
- mShiftKey.on = shiftState;
+ for (Key shiftKey : mShiftKeys) {
+ if (shiftKey != null) {
+ shiftKey.on = shiftState;
+ }
}
if (mShifted != shiftState) {
mShifted = shiftState;
@@ -670,8 +672,15 @@
return mShifted;
}
+ /**
+ * @hide
+ */
+ public int[] getShiftKeyIndices() {
+ return mShiftKeyIndices;
+ }
+
public int getShiftKeyIndex() {
- return mShiftKeyIndex;
+ return mShiftKeyIndices[0];
}
private void computeNearestNeighbors() {
@@ -760,8 +769,14 @@
key = createKeyFromXml(res, currentRow, x, y, parser);
mKeys.add(key);
if (key.codes[0] == KEYCODE_SHIFT) {
- mShiftKey = key;
- mShiftKeyIndex = mKeys.size()-1;
+ // Find available shift key slot and put this shift key in it
+ for (int i = 0; i < mShiftKeys.length; i++) {
+ if (mShiftKeys[i] == null) {
+ mShiftKeys[i] = key;
+ mShiftKeyIndices[i] = mKeys.size()-1;
+ break;
+ }
+ }
mModifierKeys.add(key);
} else if (key.codes[0] == KEYCODE_ALT) {
mModifierKeys.add(key);
diff --git a/core/java/android/os/StrictMode.java b/core/java/android/os/StrictMode.java
index 997ea53..1375a29 100644
--- a/core/java/android/os/StrictMode.java
+++ b/core/java/android/os/StrictMode.java
@@ -30,12 +30,14 @@
import dalvik.system.BlockGuard;
import dalvik.system.CloseGuard;
+import dalvik.system.VMDebug;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;
/**
@@ -184,6 +186,15 @@
/**
* @hide
*/
+ private static final int DETECT_VM_INSTANCE_LEAKS = 0x1000; // for VmPolicy
+
+ private static final int ALL_VM_DETECT_BITS =
+ DETECT_VM_CURSOR_LEAKS | DETECT_VM_CLOSABLE_LEAKS |
+ DETECT_VM_ACTIVITY_LEAKS | DETECT_VM_INSTANCE_LEAKS;
+
+ /**
+ * @hide
+ */
public static final int PENALTY_LOG = 0x10; // normal android.util.Log
// Used for both process and thread policy:
@@ -233,13 +244,20 @@
public static final int PENALTY_GATHER = 0x100;
/**
- * Mask of all the penalty bits.
+ * Mask of all the penalty bits valid for thread policies.
*/
- private static final int PENALTY_MASK =
+ private static final int THREAD_PENALTY_MASK =
PENALTY_LOG | PENALTY_DIALOG | PENALTY_DEATH | PENALTY_DROPBOX | PENALTY_GATHER |
PENALTY_DEATH_ON_NETWORK | PENALTY_FLASH;
+ /**
+ * Mask of all the penalty bits valid for VM policies.
+ */
+ private static final int VM_PENALTY_MASK =
+ PENALTY_LOG | PENALTY_DEATH | PENALTY_DROPBOX;
+
+
// TODO: wrap in some ImmutableHashMap thing.
// Note: must be before static initialization of sVmPolicy.
private static final HashMap<Class, Integer> EMPTY_CLASS_LIMIT_MAP = new HashMap<Class, Integer>();
@@ -573,11 +591,15 @@
} else if (mClassInstanceLimit == null) {
mClassInstanceLimit = new HashMap<Class, Integer>();
}
+ mMask |= DETECT_VM_INSTANCE_LEAKS;
mClassInstanceLimit.put(klass, instanceLimit);
return this;
}
- private Builder detectActivityLeaks() {
+ /**
+ * Detect leaks of {@link android.app.Activity} subclasses.
+ */
+ public Builder detectActivityLeaks() {
return enable(DETECT_VM_ACTIVITY_LEAKS);
}
@@ -585,8 +607,8 @@
* Detect everything that's potentially suspect.
*
* <p>In the Honeycomb release this includes leaks of
- * SQLite cursors and other closable objects but will
- * likely expand in future releases.
+ * SQLite cursors, Activities, and other closable objects
+ * but will likely expand in future releases.
*/
public Builder detectAll() {
return enable(DETECT_VM_ACTIVITY_LEAKS |
@@ -1102,7 +1124,7 @@
// TODO: if in gather mode, ignore Looper.myLooper() and always
// go into this immediate mode?
if (looper == null ||
- (info.policy & PENALTY_MASK) == PENALTY_DEATH) {
+ (info.policy & THREAD_PENALTY_MASK) == PENALTY_DEATH) {
info.durationMillis = -1; // unknown (redundant, already set)
handleViolation(info);
return;
@@ -1239,7 +1261,7 @@
violationMaskSubset |= violationBit;
final int savedPolicyMask = getThreadPolicyMask();
- final boolean justDropBox = (info.policy & PENALTY_MASK) == PENALTY_DROPBOX;
+ final boolean justDropBox = (info.policy & THREAD_PENALTY_MASK) == PENALTY_DROPBOX;
if (justDropBox) {
// If all we're going to ask the activity manager
// to do is dropbox it (the common case during
@@ -1347,6 +1369,42 @@
}
/**
+ * @hide
+ */
+ public static void conditionallyCheckInstanceCounts() {
+ VmPolicy policy = getVmPolicy();
+ if (policy.classInstanceLimit.size() == 0) {
+ return;
+ }
+ Runtime.getRuntime().gc();
+ // Note: classInstanceLimit is immutable, so this is lock-free
+ for (Map.Entry<Class, Integer> entry : policy.classInstanceLimit.entrySet()) {
+ Class klass = entry.getKey();
+ int limit = entry.getValue();
+ long instances = VMDebug.countInstancesOfClass(klass, false);
+ if (instances <= limit) {
+ continue;
+ }
+ Throwable tr = new InstanceCountViolation(klass, instances, limit);
+ onVmPolicyViolation(tr.getMessage(), tr);
+ }
+ }
+
+ private static long sLastInstanceCountCheckMillis = 0;
+ private static boolean sIsIdlerRegistered = false; // guarded by StrictMode.class
+ private static final MessageQueue.IdleHandler sProcessIdleHandler =
+ new MessageQueue.IdleHandler() {
+ public boolean queueIdle() {
+ long now = SystemClock.uptimeMillis();
+ if (now - sLastInstanceCountCheckMillis > 30 * 1000) {
+ sLastInstanceCountCheckMillis = now;
+ conditionallyCheckInstanceCounts();
+ }
+ return true;
+ }
+ };
+
+ /**
* Sets the policy for what actions in the VM process (on any
* thread) should be detected, as well as the penalty if such
* actions occur.
@@ -1354,16 +1412,33 @@
* @param policy the policy to put into place
*/
public static void setVmPolicy(final VmPolicy policy) {
- sVmPolicy = policy;
- sVmPolicyMask = policy.mask;
- setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
+ synchronized (StrictMode.class) {
+ sVmPolicy = policy;
+ sVmPolicyMask = policy.mask;
+ setCloseGuardEnabled(vmClosableObjectLeaksEnabled());
+
+ Looper looper = Looper.getMainLooper();
+ if (looper != null) {
+ MessageQueue mq = looper.mQueue;
+ if (policy.classInstanceLimit.size() == 0 ||
+ (sVmPolicyMask & VM_PENALTY_MASK) == 0) {
+ mq.removeIdleHandler(sProcessIdleHandler);
+ sIsIdlerRegistered = false;
+ } else if (!sIsIdlerRegistered) {
+ mq.addIdleHandler(sProcessIdleHandler);
+ sIsIdlerRegistered = true;
+ }
+ }
+ }
}
/**
* Gets the current VM policy.
*/
public static VmPolicy getVmPolicy() {
- return sVmPolicy;
+ synchronized (StrictMode.class) {
+ return sVmPolicy;
+ }
}
/**
@@ -1406,19 +1481,42 @@
onVmPolicyViolation(message, originStack);
}
+ // Map from VM violation fingerprint to uptime millis.
+ private static final HashMap<Integer, Long> sLastVmViolationTime = new HashMap<Integer, Long>();
+
/**
* @hide
*/
public static void onVmPolicyViolation(String message, Throwable originStack) {
- if ((sVmPolicyMask & PENALTY_LOG) != 0) {
+ final boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
+ final boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
+ final boolean penaltyLog = (sVmPolicyMask & PENALTY_LOG) != 0;
+ final ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+
+ // Erase stuff not relevant for process-wide violations
+ info.numAnimationsRunning = 0;
+ info.tags = null;
+ info.broadcastIntentAction = null;
+
+ final Integer fingerprint = info.hashCode();
+ final long now = SystemClock.uptimeMillis();
+ long lastViolationTime = 0;
+ long timeSinceLastViolationMillis = Long.MAX_VALUE;
+ synchronized (sLastVmViolationTime) {
+ if (sLastVmViolationTime.containsKey(fingerprint)) {
+ lastViolationTime = sLastVmViolationTime.get(fingerprint);
+ timeSinceLastViolationMillis = now - lastViolationTime;
+ }
+ if (timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
+ sLastVmViolationTime.put(fingerprint, now);
+ }
+ }
+
+ if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) {
Log.e(TAG, message, originStack);
}
- boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0;
- boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0;
-
- int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS;
- ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask);
+ int violationMaskSubset = PENALTY_DROPBOX | (ALL_VM_DETECT_BITS & sVmPolicyMask);
if (penaltyDropbox && !penaltyDeath) {
// Common case for userdebug/eng builds. If no death and
@@ -1428,7 +1526,7 @@
return;
}
- if (penaltyDropbox) {
+ if (penaltyDropbox && lastViolationTime == 0) {
// The violationMask, passed to ActivityManager, is a
// subset of the original StrictMode policy bitmask, with
// only the bit violated and penalty bits to be executed
@@ -1717,18 +1815,57 @@
((AndroidBlockGuardPolicy) policy).onWriteToDisk();
}
+ // Guarded by StrictMode.class
+ private static final HashMap<Class, Integer> sExpectedActivityInstanceCount =
+ new HashMap<Class, Integer>();
+
/**
* @hide
*/
- public static void noteActivityClass(Class klass) {
- if ((sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) {
+ public static void incrementExpectedActivityCount(Class klass) {
+ if (klass == null || (sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) {
return;
}
- if (sVmPolicy.classInstanceLimit.containsKey(klass)) {
+ synchronized (StrictMode.class) {
+ Integer expected = sExpectedActivityInstanceCount.get(klass);
+ Integer newExpected = expected == null ? 1 : expected + 1;
+ sExpectedActivityInstanceCount.put(klass, newExpected);
+ // Note: adding 1 here to give some breathing room during
+ // orientation changes. (shouldn't be necessary, though?)
+ setExpectedClassInstanceCount(klass, newExpected + 1);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static void decrementExpectedActivityCount(Class klass) {
+ if (klass == null || (sVmPolicy.mask & DETECT_VM_ACTIVITY_LEAKS) == 0) {
return;
}
- // Note: capping at 2, not 1, to give some breathing room.
- setVmPolicy(new VmPolicy.Builder(sVmPolicy).setClassInstanceLimit(klass, 2).build());
+ synchronized (StrictMode.class) {
+ Integer expected = sExpectedActivityInstanceCount.get(klass);
+ Integer newExpected = (expected == null || expected == 0) ? 0 : expected - 1;
+ if (newExpected == 0) {
+ sExpectedActivityInstanceCount.remove(klass);
+ } else {
+ sExpectedActivityInstanceCount.put(klass, newExpected);
+ }
+ // Note: adding 1 here to give some breathing room during
+ // orientation changes. (shouldn't be necessary, though?)
+ setExpectedClassInstanceCount(klass, newExpected + 1);
+ }
+ }
+
+ /**
+ * @hide
+ */
+ public static void setExpectedClassInstanceCount(Class klass, int count) {
+ synchronized (StrictMode.class) {
+ setVmPolicy(new VmPolicy.Builder(sVmPolicy)
+ .setClassInstanceLimit(klass, count)
+ .build());
+ }
}
/**
@@ -1786,6 +1923,12 @@
public String broadcastIntentAction;
/**
+ * If this is a instance count violation, the number of instances in memory,
+ * else -1.
+ */
+ public long numInstances = -1;
+
+ /**
* Create an uninitialized instance of ViolationInfo
*/
public ViolationInfo() {
@@ -1806,6 +1949,9 @@
broadcastIntentAction = broadcastIntent.getAction();
}
ThreadSpanState state = sThisThreadSpanState.get();
+ if (tr instanceof InstanceCountViolation) {
+ this.numInstances = ((InstanceCountViolation) tr).mInstances;
+ }
synchronized (state) {
int spanActiveCount = state.mActiveSize;
if (spanActiveCount > MAX_SPAN_TAGS) {
@@ -1867,6 +2013,7 @@
violationNumThisLoop = in.readInt();
numAnimationsRunning = in.readInt();
violationUptimeMillis = in.readLong();
+ numInstances = in.readLong();
broadcastIntentAction = in.readString();
tags = in.readStringArray();
}
@@ -1881,6 +2028,7 @@
dest.writeInt(violationNumThisLoop);
dest.writeInt(numAnimationsRunning);
dest.writeLong(violationUptimeMillis);
+ dest.writeLong(numInstances);
dest.writeString(broadcastIntentAction);
dest.writeStringArray(tags);
}
@@ -1895,6 +2043,9 @@
if (durationMillis != -1) {
pw.println(prefix + "durationMillis: " + durationMillis);
}
+ if (numInstances != -1) {
+ pw.println(prefix + "numInstances: " + numInstances);
+ }
if (violationNumThisLoop != 0) {
pw.println(prefix + "violationNumThisLoop: " + violationNumThisLoop);
}
@@ -1914,4 +2065,27 @@
}
}
+
+ // Dummy throwable, for now, since we don't know when or where the
+ // leaked instances came from. We might in the future, but for
+ // now we suppress the stack trace because it's useless and/or
+ // misleading.
+ private static class InstanceCountViolation extends Throwable {
+ final Class mClass;
+ final long mInstances;
+ final int mLimit;
+
+ private static final StackTraceElement[] FAKE_STACK = {
+ new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit",
+ "StrictMode.java", 1)
+ };
+
+ public InstanceCountViolation(Class klass, long instances, int limit) {
+ super(klass.toString() + "; instances=" + instances + "; limit=" + limit);
+ setStackTrace(FAKE_STACK);
+ mClass = klass;
+ mInstances = instances;
+ mLimit = limit;
+ }
+ }
}
diff --git a/core/java/android/preference/PreferenceActivity.java b/core/java/android/preference/PreferenceActivity.java
index 3883451..2b609ea 100644
--- a/core/java/android/preference/PreferenceActivity.java
+++ b/core/java/android/preference/PreferenceActivity.java
@@ -998,7 +998,9 @@
mFragmentBreadCrumbs = new FragmentBreadCrumbs(this);
ActionBar actionBar = getActionBar();
if (actionBar != null) {
- actionBar.setCustomNavigationMode(mFragmentBreadCrumbs);
+ actionBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM,
+ ActionBar.DISPLAY_SHOW_TITLE | ActionBar.DISPLAY_SHOW_CUSTOM);
+ actionBar.setCustomView(mFragmentBreadCrumbs);
}
}
mFragmentBreadCrumbs.setMaxVisible(2);
diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java
index 9f0ea32..82fe7de 100644
--- a/core/java/android/provider/MediaStore.java
+++ b/core/java/android/provider/MediaStore.java
@@ -57,6 +57,8 @@
* Broadcast Action: A broadcast to indicate the end of an MTP session with the host.
* This broadcast is only sent if MTP activity has modified the media database during the
* most recent MTP session.
+ *
+ * @hide
*/
public static final String ACTION_MTP_SESSION_END = "android.provider.action.MTP_SESSION_END";
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index cec99e9..6f23215 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -280,18 +280,25 @@
"android.settings.INPUT_METHOD_SETTINGS";
/**
- * Activity Action: Show enabler activity to enable/disable input methods and subtypes.
+ * Activity Action: Show settings to enable/disable input method subtypes.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
* safeguard against this.
* <p>
+ * To tell which input method's subtypes are displayed in the settings, add
+ * {@link #EXTRA_INPUT_METHOD_ID} extra to this Intent with the input method id.
+ * If there is no extra in this Intent, subtypes from all installed input methods
+ * will be displayed in the settings.
+ *
+ * @see android.view.inputmethod.InputMethodInfo#getId
+ * <p>
* Input: Nothing.
* <p>
* Output: Nothing.
*/
@SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
- public static final String ACTION_INPUT_METHOD_AND_SUBTYPE_ENABLER =
- "android.settings.INPUT_METHOD_AND_SUBTYPE_ENABLER";
+ public static final String ACTION_INPUT_METHOD_SUBTYPE_SETTINGS =
+ "android.settings.INPUT_METHOD_SUBTYPE_SETTINGS";
/**
* Activity Action: Show settings to manage the user input dictionary.
@@ -555,6 +562,8 @@
public static final String EXTRA_AUTHORITIES =
"authorities";
+ public static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
+
private static final String JID_RESOURCE_PREFIX = "android";
public static final String AUTHORITY = "settings";
diff --git a/core/java/android/server/BluetoothEventLoop.java b/core/java/android/server/BluetoothEventLoop.java
index 539a696..cd3bc3e 100644
--- a/core/java/android/server/BluetoothEventLoop.java
+++ b/core/java/android/server/BluetoothEventLoop.java
@@ -748,9 +748,9 @@
}
}
- private void onInputDeviceConnectionResult(String path, boolean result) {
+ private void onInputDeviceConnectionResult(String path, int result) {
// Success case gets handled by Property Change signal
- if (!result) {
+ if (result != BluetoothInputDevice.INPUT_OPERATION_SUCCESS) {
String address = mBluetoothService.getAddressFromObjectPath(path);
if (address == null) return;
@@ -758,9 +758,18 @@
BluetoothDevice device = mAdapter.getRemoteDevice(address);
int state = mBluetoothService.getInputDeviceState(device);
if (state == BluetoothInputDevice.STATE_CONNECTING) {
- connected = false;
+ if (result == BluetoothInputDevice.INPUT_CONNECT_FAILED_ALREADY_CONNECTED) {
+ connected = true;
+ } else {
+ connected = false;
+ }
} else if (state == BluetoothInputDevice.STATE_DISCONNECTING) {
- connected = true;
+ if (result == BluetoothInputDevice.INPUT_DISCONNECT_FAILED_NOT_CONNECTED) {
+ connected = false;
+ } else {
+ // There is no better way to handle this, this shouldn't happen
+ connected = true;
+ }
} else {
Log.e(TAG, "Error onInputDeviceConnectionResult. State is:" + state);
}
@@ -768,10 +777,10 @@
}
}
- private void onPanDeviceConnectionResult(String path, boolean result) {
+ private void onPanDeviceConnectionResult(String path, int result) {
log ("onPanDeviceConnectionResult " + path + " " + result);
// Success case gets handled by Property Change signal
- if (!result) {
+ if (result != BluetoothPan.PAN_OPERATION_SUCCESS) {
String address = mBluetoothService.getAddressFromObjectPath(path);
if (address == null) return;
@@ -779,9 +788,18 @@
BluetoothDevice device = mAdapter.getRemoteDevice(address);
int state = mBluetoothService.getPanDeviceState(device);
if (state == BluetoothPan.STATE_CONNECTING) {
- connected = false;
+ if (result == BluetoothPan.PAN_CONNECT_FAILED_ALREADY_CONNECTED) {
+ connected = true;
+ } else {
+ connected = false;
+ }
} else if (state == BluetoothPan.STATE_DISCONNECTING) {
- connected = true;
+ if (result == BluetoothPan.PAN_DISCONNECT_FAILED_NOT_CONNECTED) {
+ connected = false;
+ } else {
+ // There is no better way to handle this, this shouldn't happen
+ connected = true;
+ }
} else {
Log.e(TAG, "Error onPanDeviceConnectionResult. State is: "
+ state + " result: "+ result);
diff --git a/core/java/android/text/method/Touch.java b/core/java/android/text/method/Touch.java
index 78cbdcf..a528044 100644
--- a/core/java/android/text/method/Touch.java
+++ b/core/java/android/text/method/Touch.java
@@ -77,24 +77,6 @@
}
/**
- * @hide
- * Returns the maximum scroll value in x.
- */
- public static int getMaxScrollX(TextView widget, Layout layout, int y) {
- int top = layout.getLineForVertical(y);
- int bottom = layout.getLineForVertical(y + widget.getHeight()
- - widget.getTotalPaddingTop() -widget.getTotalPaddingBottom());
- int left = Integer.MAX_VALUE;
- int right = 0;
- for (int i = top; i <= bottom; i++) {
- left = (int) Math.min(left, layout.getLineLeft(i));
- right = (int) Math.max(right, layout.getLineRight(i));
- }
- return right - left - widget.getWidth() - widget.getTotalPaddingLeft()
- - widget.getTotalPaddingRight();
- }
-
- /**
* Handles touch events for dragging. You may want to do other actions
* like moving the cursor on touch as well.
*/
diff --git a/core/java/android/view/DragEvent.java b/core/java/android/view/DragEvent.java
index 6634f00..4d83891 100644
--- a/core/java/android/view/DragEvent.java
+++ b/core/java/android/view/DragEvent.java
@@ -130,12 +130,13 @@
}
private void init(int action, float x, float y, ClipDescription description, ClipData data,
- boolean result) {
+ Object localState, boolean result) {
mAction = action;
mX = x;
mY = y;
mClipDescription = description;
mClipData = data;
+ mLocalState = localState;
mDragResult = result;
}
@@ -150,7 +151,7 @@
synchronized (gRecyclerLock) {
if (gRecyclerTop == null) {
ev = new DragEvent();
- ev.init(action, x, y, description, data, result);
+ ev.init(action, x, y, description, data, localState, result);
return ev;
}
ev = gRecyclerTop;
@@ -161,7 +162,7 @@
ev.mRecycled = false;
ev.mNext = null;
- ev.init(action, x, y, description, data, result);
+ ev.init(action, x, y, description, data, localState, result);
return ev;
}
@@ -274,7 +275,7 @@
public String toString() {
return "DragEvent{" + Integer.toHexString(System.identityHashCode(this))
+ " action=" + mAction + " @ (" + mX + ", " + mY + ") desc=" + mClipDescription
- + " data=" + mClipData + " result=" + mDragResult
+ + " data=" + mClipData + " local=" + mLocalState + " result=" + mDragResult
+ "}";
}
diff --git a/core/java/android/view/GLES20Canvas.java b/core/java/android/view/GLES20Canvas.java
index 99b686e..e47dc93 100644
--- a/core/java/android/view/GLES20Canvas.java
+++ b/core/java/android/view/GLES20Canvas.java
@@ -452,11 +452,14 @@
@Override
public int saveLayer(float left, float top, float right, float bottom, Paint paint,
int saveFlags) {
- boolean hasColorFilter = paint != null && setupColorFilter(paint);
- final int nativePaint = paint == null ? 0 : paint.mNativePaint;
- int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
- if (hasColorFilter) nResetModifiers(mRenderer);
- return count;
+ if (left < right && top < bottom) {
+ boolean hasColorFilter = paint != null && setupColorFilter(paint);
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ int count = nSaveLayer(mRenderer, left, top, right, bottom, nativePaint, saveFlags);
+ if (hasColorFilter) nResetModifiers(mRenderer);
+ return count;
+ }
+ return save(saveFlags);
}
private native int nSaveLayer(int renderer, float left, float top, float right, float bottom,
@@ -471,7 +474,10 @@
@Override
public int saveLayerAlpha(float left, float top, float right, float bottom, int alpha,
int saveFlags) {
- return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
+ if (left < right && top < bottom) {
+ return nSaveLayerAlpha(mRenderer, left, top, right, bottom, alpha, saveFlags);
+ }
+ return save(saveFlags);
}
private native int nSaveLayerAlpha(int renderer, float left, float top, float right,
@@ -624,14 +630,41 @@
@Override
public void drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts,
int vertOffset, int[] colors, int colorOffset, Paint paint) {
- // TODO: Implement
+ if (meshWidth < 0 || meshHeight < 0 || vertOffset < 0 || colorOffset < 0) {
+ throw new ArrayIndexOutOfBoundsException();
+ }
+
+ if (meshWidth == 0 || meshHeight == 0) {
+ return;
+ }
+
+ final int count = (meshWidth + 1) * (meshHeight + 1);
+ checkRange(verts.length, vertOffset, count * 2);
+
+ // TODO: Colors are ignored for now
+ colors = null;
+ colorOffset = 0;
+
+ boolean hasColorFilter = paint != null && setupColorFilter(paint);
+ final int nativePaint = paint == null ? 0 : paint.mNativePaint;
+ nDrawBitmapMesh(mRenderer, bitmap.mNativeBitmap, bitmap.mBuffer, meshWidth, meshHeight,
+ verts, vertOffset, colors, colorOffset, nativePaint);
+ if (hasColorFilter) nResetModifiers(mRenderer);
}
+ private native void nDrawBitmapMesh(int renderer, int bitmap, byte[] buffer,
+ int meshWidth, int meshHeight, float[] verts, int vertOffset,
+ int[] colors, int colorOffset, int paint);
+
@Override
public void drawCircle(float cx, float cy, float radius, Paint paint) {
- throw new UnsupportedOperationException();
+ boolean hasModifier = setupModifiers(paint);
+ nDrawCircle(mRenderer, cx, cy, radius, paint.mNativePaint);
+ if (hasModifier) nResetModifiers(mRenderer);
}
+ private native void nDrawCircle(int renderer, float cx, float cy, float radius, int paint);
+
@Override
public void drawColor(int color) {
drawColor(color, PorterDuff.Mode.SRC_OVER);
@@ -767,9 +800,15 @@
@Override
public void drawRoundRect(RectF rect, float rx, float ry, Paint paint) {
- // TODO: Implement
+ boolean hasModifier = setupModifiers(paint);
+ nDrawRoundRect(mRenderer, rect.left, rect.top, rect.right, rect.bottom,
+ rx, ry, paint.mNativePaint);
+ if (hasModifier) nResetModifiers(mRenderer);
}
+ private native void nDrawRoundRect(int renderer, float left, float top,
+ float right, float bottom, float rx, float y, int paint);
+
@Override
public void drawText(char[] text, int index, int count, float x, float y, Paint paint) {
if ((index | count | (index + count) | (text.length - index - count)) < 0) {
diff --git a/core/java/android/view/KeyCharacterMap.java b/core/java/android/view/KeyCharacterMap.java
index 7ca5a19..3ff7fcd 100644
--- a/core/java/android/view/KeyCharacterMap.java
+++ b/core/java/android/view/KeyCharacterMap.java
@@ -170,7 +170,7 @@
*
* @param deviceId The device id of the keyboard.
* @return The associated key character map.
- * @throws {@link KeyCharacterMapUnavailableException} if the key character map
+ * @throws {@link UnavailableException} if the key character map
* could not be loaded because it was malformed or the default key character map
* is missing from the system.
*/
@@ -692,8 +692,8 @@
/**
* Thrown by {@link KeyCharacterMap#load} when a key character map could not be loaded.
*/
- public static class KeyCharacterMapUnavailableException extends AndroidRuntimeException {
- public KeyCharacterMapUnavailableException(String msg) {
+ public static class UnavailableException extends AndroidRuntimeException {
+ public UnavailableException(String msg) {
super(msg);
}
}
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index ecf1aef..941331a 100755
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -2163,7 +2163,7 @@
* Gets the {@link KeyCharacterMap} associated with the keyboard device.
*
* @return The associated key character map.
- * @throws {@link KeyCharacterMapUnavailableException} if the key character map
+ * @throws {@link UnavailableException} if the key character map
* could not be loaded because it was malformed or the default key character map
* is missing from the system.
*
diff --git a/core/java/android/view/View.java b/core/java/android/view/View.java
index 270ea76..811a633 100644
--- a/core/java/android/view/View.java
+++ b/core/java/android/view/View.java
@@ -58,7 +58,6 @@
import android.util.Pools;
import android.util.SparseArray;
import android.view.ContextMenu.ContextMenuInfo;
-import android.view.View.MeasureSpec;
import android.view.accessibility.AccessibilityEvent;
import android.view.accessibility.AccessibilityEventSource;
import android.view.accessibility.AccessibilityManager;
@@ -5028,6 +5027,15 @@
focusTaken = requestFocus();
}
+ if (prepressed) {
+ // The button is being released before we actually
+ // showed it as pressed. Make it show the pressed
+ // state now (before scheduling the click) to ensure
+ // the user sees it.
+ mPrivateFlags |= PRESSED;
+ refreshDrawableState();
+ }
+
if (!mHasPerformedLongPress) {
// This is a tap, so remove the longpress check
removeLongPressCallback();
@@ -5051,8 +5059,6 @@
}
if (prepressed) {
- mPrivateFlags |= PRESSED;
- refreshDrawableState();
postDelayed(mUnsetPressedState,
ViewConfiguration.getPressedStateDuration());
} else if (!post(mUnsetPressedState)) {
diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java
index d1781cc..115431e 100644
--- a/core/java/android/view/ViewGroup.java
+++ b/core/java/android/view/ViewGroup.java
@@ -935,15 +935,17 @@
} break;
case DragEvent.ACTION_DRAG_ENDED: {
- // If a child was notified about an ongoing drag, it's told that it's over
- for (View child : mDragNotifiedChildren) {
- child.dispatchDragEvent(event);
- }
-
// Release the bookkeeping now that the drag lifecycle has ended
- mDragNotifiedChildren.clear();
- mCurrentDrag.recycle();
- mCurrentDrag = null;
+ if (mDragNotifiedChildren != null) {
+ for (View child : mDragNotifiedChildren) {
+ // If a child was notified about an ongoing drag, it's told that it's over
+ child.dispatchDragEvent(event);
+ }
+
+ mDragNotifiedChildren.clear();
+ mCurrentDrag.recycle();
+ mCurrentDrag = null;
+ }
// We consider drag-ended to have been handled if one of our children
// had offered to handle the drag.
diff --git a/core/java/android/view/ViewRoot.java b/core/java/android/view/ViewRoot.java
index 961b633..2c6ec71 100644
--- a/core/java/android/view/ViewRoot.java
+++ b/core/java/android/view/ViewRoot.java
@@ -228,7 +228,7 @@
/* Drag/drop */
ClipDescription mDragDescription;
View mCurrentDragView;
- Object mLocalDragState;
+ volatile Object mLocalDragState;
final PointF mDragPoint = new PointF();
final PointF mLastTouchPoint = new PointF();
@@ -489,17 +489,17 @@
// Try to enable hardware acceleration if requested
if (attrs != null &&
(attrs.flags & WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED) != 0) {
- // Don't enable hardware acceleration when we're not on the main thread
- if (Looper.getMainLooper() != Looper.myLooper()) {
- Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware acceleration "
- + "outside of the main thread, aborting");
- return;
- }
-
// Only enable hardware acceleration if we are not in the system process
// The window manager creates ViewRoots to display animated preview windows
// of launching apps and we don't want those to be hardware accelerated
if (!HardwareRenderer.sRendererDisabled) {
+ // Don't enable hardware acceleration when we're not on the main thread
+ if (Looper.getMainLooper() != Looper.myLooper()) {
+ Log.w(HardwareRenderer.LOG_TAG, "Attempting to initialize hardware "
+ + "acceleration outside of the main thread, aborting");
+ return;
+ }
+
final boolean translucent = attrs.format != PixelFormat.OPAQUE;
if (mAttachInfo.mHardwareRenderer != null) {
mAttachInfo.mHardwareRenderer.destroy(true);
@@ -2051,7 +2051,9 @@
} break;
case DISPATCH_DRAG_EVENT:
case DISPATCH_DRAG_LOCATION_EVENT: {
- handleDragEvent((DragEvent)msg.obj);
+ DragEvent event = (DragEvent)msg.obj;
+ event.mLocalState = mLocalDragState; // only present when this app called startDrag()
+ handleDragEvent(event);
} break;
}
}
@@ -2803,6 +2805,7 @@
// Report the drop result when we're done
if (what == DragEvent.ACTION_DROP) {
+ mDragDescription = null;
try {
Log.i(TAG, "Reporting drop result: " + result);
sWindowSession.reportDropResult(mWindow, result);
@@ -3132,7 +3135,6 @@
} else {
what = DISPATCH_DRAG_EVENT;
}
- event.mLocalState = mLocalDragState; // only present when this app called startDrag()
Message msg = obtainMessage(what, event);
sendMessage(msg);
}
diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java
index e21824e..e447dbb 100644
--- a/core/java/android/view/VolumePanel.java
+++ b/core/java/android/view/VolumePanel.java
@@ -284,10 +284,11 @@
synchronized (this) {
ToneGenerator toneGen = getOrCreateToneGenerator(streamType);
- toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
+ if (toneGen != null) {
+ toneGen.startTone(ToneGenerator.TONE_PROP_BEEP);
+ sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
+ }
}
-
- sendMessageDelayed(obtainMessage(MSG_STOP_SOUNDS), BEEP_DURATION);
}
protected void onStopSounds() {
@@ -319,10 +320,16 @@
private ToneGenerator getOrCreateToneGenerator(int streamType) {
synchronized (this) {
if (mToneGenerators[streamType] == null) {
- return mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
- } else {
- return mToneGenerators[streamType];
+ try {
+ mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
+ } catch (RuntimeException e) {
+ if (LOGD) {
+ Log.d(TAG, "ToneGenerator constructor failed with "
+ + "RuntimeException: " + e);
+ }
+ }
}
+ return mToneGenerators[streamType];
}
}
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index c54a3cf..8eb4269 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -817,7 +817,7 @@
public static final int SOFT_INPUT_IS_FORWARD_NAVIGATION = 0x100;
/**
- * Desired operating mode for any soft input area. May any combination
+ * Desired operating mode for any soft input area. May be any combination
* of:
*
* <ul>
diff --git a/core/java/android/view/inputmethod/InputMethodInfo.java b/core/java/android/view/inputmethod/InputMethodInfo.java
index defd104..32eec9f 100644
--- a/core/java/android/view/inputmethod/InputMethodInfo.java
+++ b/core/java/android/view/inputmethod/InputMethodInfo.java
@@ -265,10 +265,19 @@
}
/**
- * Return the subtypes of Input Method.
+ * Return the count of the subtypes of Input Method.
*/
- public ArrayList<InputMethodSubtype> getSubtypes() {
- return mSubtypes;
+ public int getSubtypeCount() {
+ return mSubtypes.size();
+ }
+
+ /**
+ * Return the Input Method's subtype at the specified index.
+ *
+ * @param index the index of the subtype to return.
+ */
+ public InputMethodSubtype getSubtypeAt(int index) {
+ return mSubtypes.get(index);
}
/**
diff --git a/core/java/android/view/inputmethod/InputMethodSubtype.java b/core/java/android/view/inputmethod/InputMethodSubtype.java
index 39a0c19..ba425a6 100644
--- a/core/java/android/view/inputmethod/InputMethodSubtype.java
+++ b/core/java/android/view/inputmethod/InputMethodSubtype.java
@@ -22,13 +22,10 @@
import java.util.Arrays;
/**
- * Information given to an {@link InputMethod} about a client connecting
- * to it.
- */
-/**
- * InputMethodSubtype is a subtype contained in the input method. Subtype can describe
- * locales (e.g. en_US, fr_FR...) and modes (e.g. voice, keyboard...), and is used for
- * IME switch. The subtype allows the system to call the specified subtype of IME directly.
+ * This class is used to specify meta information of a subtype contained in an input method.
+ * Subtype can describe locale (e.g. en_US, fr_FR...) and mode (e.g. voice, keyboard...), and is
+ * used for IME switch and settings. The input method subtype allows the system to bring up the
+ * specified subtype of the designated input method directly.
*/
public final class InputMethodSubtype implements Parcelable {
private final int mSubtypeNameResId;
diff --git a/core/java/android/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java
index e246717..ec3c329 100644
--- a/core/java/android/webkit/BrowserFrame.java
+++ b/core/java/android/webkit/BrowserFrame.java
@@ -1177,6 +1177,17 @@
contentDisposition, mimeType, contentLength);
}
+ /**
+ * Called by JNI when we load a page over SSL.
+ */
+ private void setCertificate(String issuedTo, String issuedBy,
+ long validNotBeforeMillis, long validNotAfterMillis) {
+ Date validNotBefore = new Date(validNotBeforeMillis);
+ Date validNotAfter = new Date(validNotAfterMillis);
+ mCallbackProxy.onReceivedCertificate(new SslCertificate(
+ issuedTo, issuedBy, validNotBefore, validNotAfter));
+ }
+
//==========================================================================
// native functions
//==========================================================================
diff --git a/core/java/android/webkit/CacheManager.java b/core/java/android/webkit/CacheManager.java
index 6073f7a..a553a459 100644
--- a/core/java/android/webkit/CacheManager.java
+++ b/core/java/android/webkit/CacheManager.java
@@ -244,6 +244,9 @@
* obtained from {@link android.webkit.CacheManager.CacheResult#getLocalPath}, this
* identifies the cache file.
*
+ * Cache files are not guaranteed to be in this directory before
+ * CacheManager#getCacheFile(String, Map<String, String>) is called.
+ *
* @return File The base directory of the cache.
*
* @deprecated Access to the HTTP cache will be removed in a future release.
@@ -611,8 +614,9 @@
return true;
}
// delete rows in the cache database
- WebViewWorker.getHandler().sendEmptyMessage(
- WebViewWorker.MSG_CLEAR_CACHE);
+ if (!JniUtil.useChromiumHttpStack())
+ WebViewWorker.getHandler().sendEmptyMessage(WebViewWorker.MSG_CLEAR_CACHE);
+
// delete cache files in a separate thread to not block UI.
final Runnable clearCache = new Runnable() {
public void run() {
diff --git a/core/java/android/webkit/WebTextView.java b/core/java/android/webkit/WebTextView.java
index 72b0023..59a239a 100644
--- a/core/java/android/webkit/WebTextView.java
+++ b/core/java/android/webkit/WebTextView.java
@@ -135,7 +135,6 @@
// Used to determine whether onFocusChanged was called as a result of
// calling remove().
private boolean mInsideRemove;
- private boolean mInPassword;
// Types used with setType. Keep in sync with CachedInput.h
private static final int NORMAL_TEXT_FIELD = 0;
@@ -374,18 +373,24 @@
}
/**
- * Ensure that the underlying textfield is lined up with the WebTextView.
+ * Ensure that the underlying text field/area is lined up with the WebTextView.
*/
private void lineUpScroll() {
Layout layout = getLayout();
if (mWebView != null && layout != null) {
- float maxScrollX = Touch.getMaxScrollX(this, layout, mScrollY);
- if (DebugFlags.WEB_TEXT_VIEW) {
- Log.v(LOGTAG, "onTouchEvent x=" + mScrollX + " y="
- + mScrollY + " maxX=" + maxScrollX);
+ if (mSingle) {
+ // textfields only need to be lined up horizontally.
+ float maxScrollX = layout.getLineRight(0) - getWidth();
+ if (DebugFlags.WEB_TEXT_VIEW) {
+ Log.v(LOGTAG, "onTouchEvent x=" + mScrollX + " y="
+ + mScrollY + " maxX=" + maxScrollX);
+ }
+ mWebView.scrollFocusedTextInputX(maxScrollX > 0 ?
+ mScrollX / maxScrollX : 0);
+ } else {
+ // textareas only need to be lined up vertically.
+ mWebView.scrollFocusedTextInputY(mScrollY);
}
- mWebView.scrollFocusedTextInput(maxScrollX > 0 ?
- mScrollX / maxScrollX : 0, mScrollY);
}
}
@@ -414,6 +419,7 @@
mLayout.getSpacingAdd(), false, null, ellipsisWidth,
lineHeight);
}
+ lineUpScroll();
}
/**
@@ -786,10 +792,8 @@
}
@Override
- public boolean bringPointIntoView(int offset) {
- if (mInPassword) {
- return getLayout() != null && super.bringPointIntoView(offset);
- }
+ public boolean requestRectangleOnScreen(Rect rectangle, boolean immediate) {
+ // Do nothing, since webkit will put the textfield on screen.
return true;
}
@@ -904,7 +908,6 @@
* @param inPassword True if the textfield is a password field.
*/
/* package */ void setInPassword(boolean inPassword) {
- mInPassword = inPassword;
if (inPassword) {
setInputType(EditorInfo.TYPE_CLASS_TEXT | EditorInfo.
TYPE_TEXT_VARIATION_WEB_PASSWORD);
diff --git a/core/java/android/webkit/WebView.java b/core/java/android/webkit/WebView.java
index 9e09c28..c1fafa2 100644
--- a/core/java/android/webkit/WebView.java
+++ b/core/java/android/webkit/WebView.java
@@ -408,10 +408,13 @@
PluginFullScreenHolder mFullScreenHolder;
/**
- * Position of the last touch event.
+ * Position of the last touch event in pixels.
+ * Use integer to prevent loss of dragging delta calculation accuracy;
+ * which was done in float and converted to integer, and resulted in gradual
+ * and compounding touch position and view dragging mismatch.
*/
- private float mLastTouchX;
- private float mLastTouchY;
+ private int mLastTouchX;
+ private int mLastTouchY;
/**
* Time of the last touch event.
@@ -496,6 +499,15 @@
// if true, multi-touch events will be passed to webkit directly before UI
private boolean mDeferMultitouch = false;
+ // Currently, multi-touch events are sent to WebKit first then back to
+ // WebView while single-touch events are handled in WebView first.
+ // So there is a chance that a single-touch move event is handled in WebView
+ // before multi-touch events are finished.
+ // if mIsHandlingMultiTouch is true, which means multi-touch event handling
+ // is not finished, then any single-touch move event will be skipped.
+ // FIXME: send single-touch events to WebKit first then back to WebView.
+ private boolean mIsHandlingMultiTouch = false;
+
// to avoid interfering with the current touch events, track them
// separately. Currently no snapping or fling in the deferred process mode
private int mDeferTouchMode = TOUCH_DONE_MODE;
@@ -2218,8 +2230,8 @@
if (type == HitTestResult.UNKNOWN_TYPE
|| type == HitTestResult.SRC_ANCHOR_TYPE) {
// Now check to see if it is an image.
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
String text = nativeImageURI(contentX, contentY);
if (text != null) {
result.setType(type == HitTestResult.UNKNOWN_TYPE ?
@@ -2256,8 +2268,8 @@
if (hrefMsg == null) {
return;
}
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
mWebViewCore.sendMessage(EventHub.REQUEST_CURSOR_HREF,
contentX, contentY, hrefMsg);
}
@@ -2271,8 +2283,8 @@
*/
public void requestImageRef(Message msg) {
if (0 == mNativeClass) return; // client isn't initialized
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
String ref = nativeImageURI(contentX, contentY);
Bundle data = msg.getData();
data.putString("url", ref);
@@ -3856,8 +3868,8 @@
* @hide pending API council approval
*/
public boolean selectText() {
- int x = viewToContentX((int) mLastTouchX + mScrollX);
- int y = viewToContentY((int) mLastTouchY + mScrollY);
+ int x = viewToContentX(mLastTouchX + mScrollX);
+ int y = viewToContentY(mLastTouchY + mScrollY);
return selectText(x, y);
}
@@ -4858,8 +4870,8 @@
mSelectX = contentToViewX(rect.left);
mSelectY = contentToViewY(rect.top);
} else if (mLastTouchY > getVisibleTitleHeight()) {
- mSelectX = mScrollX + (int) mLastTouchX;
- mSelectY = mScrollY + (int) mLastTouchY;
+ mSelectX = mScrollX + mLastTouchX;
+ mSelectY = mScrollY + mLastTouchY;
} else {
mSelectX = mScrollX + getViewWidth() / 2;
mSelectY = mScrollY + getViewHeightWithTitle() / 2;
@@ -5235,7 +5247,7 @@
if (event.getAction() == KeyEvent.ACTION_DOWN) {
mGotKeyDown = true;
} else {
- if (!mGotKeyDown) {
+ if (!mGotKeyDown && event.getAction() != KeyEvent.ACTION_MULTIPLE) {
/*
* We got a key up for which we were not the recipient of
* the original key down. Don't give it to the view.
@@ -5353,11 +5365,19 @@
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "passing " + ev.getPointerCount() + " points to webkit");
}
+ if (!mIsHandlingMultiTouch) {
+ mIsHandlingMultiTouch = true;
+ }
passMultiTouchToWebKit(ev);
return true;
+ } else {
+ // Skip ACTION_MOVE for single touch if it's still handling multi-touch.
+ if (mIsHandlingMultiTouch && ev.getActionMasked() == MotionEvent.ACTION_MOVE) {
+ return false;
+ }
}
- return handleTouchEventCommon(ev, ev.getX(), ev.getY());
+ return handleTouchEventCommon(ev, ev.getActionMasked(), Math.round(ev.getX()), Math.round(ev.getY()));
}
/*
@@ -5365,8 +5385,7 @@
* (x, y) denotes current focus point, which is the touch point for single touch
* and the middle point for multi-touch.
*/
- private boolean handleTouchEventCommon(MotionEvent ev, float x, float y) {
- int action = ev.getAction();
+ private boolean handleTouchEventCommon(MotionEvent ev, int action, int x, int y) {
long eventTime = ev.getEventTime();
@@ -5377,17 +5396,16 @@
x = Math.min(x, getViewWidth() - 1);
y = Math.min(y, getViewHeightWithTitle() - 1);
- float fDeltaX = mLastTouchX - x;
- float fDeltaY = mLastTouchY - y;
- int deltaX = (int) fDeltaX;
- int deltaY = (int) fDeltaY;
- int contentX = viewToContentX((int) x + mScrollX);
- int contentY = viewToContentY((int) y + mScrollY);
+ int deltaX = mLastTouchX - x;
+ int deltaY = mLastTouchY - y;
+ int contentX = viewToContentX(x + mScrollX);
+ int contentY = viewToContentY(y + mScrollY);
switch (action) {
case MotionEvent.ACTION_DOWN: {
mPreventDefault = PREVENT_DEFAULT_NO;
mConfirmMove = false;
+ mIsHandlingMultiTouch = false;
mInitialHitTestResult = null;
if (!mScroller.isFinished()) {
// stop the current scroll animation, but if this is
@@ -5607,8 +5625,6 @@
mTouchMode = TOUCH_DRAG_MODE;
mLastTouchX = x;
mLastTouchY = y;
- fDeltaX = 0.0f;
- fDeltaY = 0.0f;
deltaX = 0;
deltaY = 0;
@@ -5619,9 +5635,7 @@
// do pan
boolean done = false;
boolean keepScrollBarsVisible = false;
- if (Math.abs(fDeltaX) < 1.0f && Math.abs(fDeltaY) < 1.0f) {
- mLastTouchX = x;
- mLastTouchY = y;
+ if (deltaX == 0 && deltaY == 0) {
keepScrollBarsVisible = done = true;
} else {
if (mSnapScrollMode == SNAP_X || mSnapScrollMode == SNAP_Y) {
@@ -5670,12 +5684,6 @@
mLastTouchY = y;
}
mHeldMotionless = MOTIONLESS_FALSE;
- } else {
- // keep the scrollbar on the screen even there is no
- // scroll
- mLastTouchX = x;
- mLastTouchY = y;
- keepScrollBarsVisible = true;
}
mLastTouchTime = eventTime;
mUserScroll = true;
@@ -5856,7 +5864,7 @@
private void passMultiTouchToWebKit(MotionEvent ev) {
TouchEventData ted = new TouchEventData();
- ted.mAction = ev.getAction() & MotionEvent.ACTION_MASK;
+ ted.mAction = ev.getActionMasked();
final int count = ev.getPointerCount();
ted.mIds = new int[count];
ted.mPoints = new Point[count];
@@ -5875,7 +5883,7 @@
mPreventDefault = PREVENT_DEFAULT_IGNORE;
}
- private boolean handleMultiTouchInWebView(MotionEvent ev) {
+ private void handleMultiTouchInWebView(MotionEvent ev) {
if (DebugFlags.WEB_VIEW) {
Log.v(LOGTAG, "multi-touch: " + ev + " at " + ev.getEventTime()
+ " mTouchMode=" + mTouchMode
@@ -5888,7 +5896,7 @@
// A few apps use WebView but don't instantiate gesture detector.
// We don't need to support multi touch for them.
- if (detector == null) return false;
+ if (detector == null) return;
float x = ev.getX();
float y = ev.getY();
@@ -5923,7 +5931,7 @@
cancelLongPress();
mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS);
if (!mZoomManager.supportsPanDuringZoom()) {
- return false;
+ return;
}
mTouchMode = TOUCH_DRAG_MODE;
if (mVelocityTracker == null) {
@@ -5937,16 +5945,17 @@
action = MotionEvent.ACTION_DOWN;
} else if (action == MotionEvent.ACTION_POINTER_UP) {
// set mLastTouchX/Y to the remaining point
- mLastTouchX = x;
- mLastTouchY = y;
+ mLastTouchX = Math.round(x);
+ mLastTouchY = Math.round(y);
+ mIsHandlingMultiTouch = false;
} else if (action == MotionEvent.ACTION_MOVE) {
// negative x or y indicate it is on the edge, skip it.
if (x < 0 || y < 0) {
- return false;
+ return;
}
}
- return handleTouchEventCommon(ev, x, y);
+ handleTouchEventCommon(ev, action, Math.round(x), Math.round(y));
}
private void cancelWebCoreTouchEvent(int x, int y, boolean removeEvents) {
@@ -5967,8 +5976,8 @@
private void startTouch(float x, float y, long eventTime) {
// Remember where the motion event started
- mLastTouchX = x;
- mLastTouchY = y;
+ mLastTouchX = Math.round(x);
+ mLastTouchY = Math.round(y);
mLastTouchTime = eventTime;
mVelocityTracker = VelocityTracker.obtain();
mSnapScrollMode = SNAP_NONE;
@@ -6598,8 +6607,8 @@
return;
}
// mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
Rect rect = new Rect(contentX - mNavSlop, contentY - mNavSlop,
contentX + mNavSlop, contentY + mNavSlop);
nativeSelectBestAt(rect);
@@ -6607,31 +6616,42 @@
}
/**
- * Scroll the focused text field/area to match the WebTextView
+ * Scroll the focused text field to match the WebTextView
* @param xPercent New x position of the WebTextView from 0 to 1.
- * @param y New y position of the WebTextView in view coordinates
*/
- /*package*/ void scrollFocusedTextInput(float xPercent, int y) {
+ /*package*/ void scrollFocusedTextInputX(float xPercent) {
if (!inEditingMode() || mWebViewCore == null) {
return;
}
- mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT,
- // Since this position is relative to the top of the text input
- // field, we do not need to take the title bar's height into
- // consideration.
- viewToContentDimension(y),
+ mWebViewCore.sendMessage(EventHub.SCROLL_TEXT_INPUT, 0,
new Float(xPercent));
}
/**
+ * Scroll the focused textarea vertically to match the WebTextView
+ * @param y New y position of the WebTextView in view coordinates
+ */
+ /* package */ void scrollFocusedTextInputY(int y) {
+ if (!inEditingMode()) {
+ return;
+ }
+ int xPos = viewToContentX((mWebTextView.getLeft() + mWebTextView.getRight()) / 2);
+ int yPos = viewToContentY((mWebTextView.getTop() + mWebTextView.getBottom()) / 2);
+ int layer = nativeScrollableLayer(xPos, yPos, null, null);
+ if (layer != 0) {
+ nativeScrollLayer(layer, 0, viewToContentDimension(y));
+ }
+ }
+
+ /**
* Set our starting point and time for a drag from the WebTextView.
*/
/*package*/ void initiateTextFieldDrag(float x, float y, long eventTime) {
if (!inEditingMode()) {
return;
}
- mLastTouchX = x + (float) (mWebTextView.getLeft() - mScrollX);
- mLastTouchY = y + (float) (mWebTextView.getTop() - mScrollY);
+ mLastTouchX = Math.round(x + mWebTextView.getLeft() - mScrollX);
+ mLastTouchY = Math.round(y + mWebTextView.getTop() - mScrollY);
mLastTouchTime = eventTime;
if (!mScroller.isFinished()) {
abortAnimation();
@@ -6690,8 +6710,8 @@
mTouchMode = TOUCH_DONE_MODE;
switchOutDrawHistory();
// mLastTouchX and mLastTouchY are the point in the current viewport
- int contentX = viewToContentX((int) mLastTouchX + mScrollX);
- int contentY = viewToContentY((int) mLastTouchY + mScrollY);
+ int contentX = viewToContentX(mLastTouchX + mScrollX);
+ int contentY = viewToContentY(mLastTouchY + mScrollY);
if (getSettings().supportTouchOnly()) {
removeTouchHighlight(false);
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
@@ -7052,8 +7072,8 @@
|| (msg.arg1 == MotionEvent.ACTION_MOVE
&& mPreventDefault == PREVENT_DEFAULT_NO_FROM_TOUCH_DOWN)) {
cancelWebCoreTouchEvent(
- viewToContentX((int) mLastTouchX + mScrollX),
- viewToContentY((int) mLastTouchY + mScrollY),
+ viewToContentX(mLastTouchX + mScrollX),
+ viewToContentY(mLastTouchY + mScrollY),
true);
}
break;
@@ -7104,8 +7124,8 @@
ted.mIds = new int[1];
ted.mIds[0] = 0;
ted.mPoints = new Point[1];
- ted.mPoints[0] = new Point(viewToContentX((int) mLastTouchX + mScrollX),
- viewToContentY((int) mLastTouchY + mScrollY));
+ ted.mPoints[0] = new Point(viewToContentX(mLastTouchX + mScrollX),
+ viewToContentY(mLastTouchY + mScrollY));
// metaState for long press is tricky. Should it be the
// state when the press started or when the press was
// released? Or some intermediary key state? For
@@ -7958,15 +7978,27 @@
}
}
- // called by JNI
+ /**
+ * Called by JNI to send a message to the webcore thread that the user
+ * touched the webpage.
+ * @param touchGeneration Generation number of the touch, to ignore touches
+ * after a new one has been generated.
+ * @param frame Pointer to the frame holding the node that was touched.
+ * @param node Pointer to the node touched.
+ * @param x x-position of the touch.
+ * @param y y-position of the touch.
+ * @param scrollY Only used when touching on a textarea. Otherwise, use -1.
+ * Tells how much the textarea is scrolled.
+ */
private void sendMotionUp(int touchGeneration,
- int frame, int node, int x, int y) {
+ int frame, int node, int x, int y, int scrollY) {
WebViewCore.TouchUpData touchUpData = new WebViewCore.TouchUpData();
touchUpData.mMoveGeneration = touchGeneration;
touchUpData.mFrame = frame;
touchUpData.mNode = node;
touchUpData.mX = x;
touchUpData.mY = y;
+ touchUpData.mScrollY = scrollY;
mWebViewCore.sendMessage(EventHub.TOUCH_UP, touchUpData);
}
@@ -8292,5 +8324,12 @@
// Returns a pointer to the scrollable LayerAndroid at the given point.
private native int nativeScrollableLayer(int x, int y, Rect scrollRect,
Rect scrollBounds);
- private native boolean nativeScrollLayer(int layer, int dx, int dy);
+ /**
+ * Scroll the specified layer.
+ * @param layer Id of the layer to scroll, as determined by nativeScrollableLayer.
+ * @param newX Destination x position to which to scroll.
+ * @param newY Destination y position to which to scroll.
+ * @return True if the layer is successfully scrolled.
+ */
+ private native boolean nativeScrollLayer(int layer, int newX, int newY);
}
diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java
index c56f252..bb4441f 100644
--- a/core/java/android/webkit/WebViewCore.java
+++ b/core/java/android/webkit/WebViewCore.java
@@ -560,7 +560,7 @@
private native String nativeRetrieveImageSource(int x, int y);
private native void nativeTouchUp(int touchGeneration,
- int framePtr, int nodePtr, int x, int y);
+ int framePtr, int nodePtr, int x, int y, int scrollY);
private native boolean nativeHandleTouchEvent(int action, int[] idArray,
int[] xArray, int[] yArray, int count, int metaState);
@@ -790,6 +790,8 @@
int mNode;
int mX;
int mY;
+ // Used in the case of a scrolled textarea
+ int mScrollY;
}
static class TouchHighlightData {
@@ -1321,7 +1323,8 @@
TouchUpData touchUpData = (TouchUpData) msg.obj;
nativeTouchUp(touchUpData.mMoveGeneration,
touchUpData.mFrame, touchUpData.mNode,
- touchUpData.mX, touchUpData.mY);
+ touchUpData.mX, touchUpData.mY,
+ touchUpData.mScrollY);
break;
case TOUCH_EVENT: {
@@ -1770,7 +1773,7 @@
private void clearCache(boolean includeDiskFiles) {
mBrowserFrame.clearCache();
- if (includeDiskFiles && !JniUtil.useChromiumHttpStack()) {
+ if (includeDiskFiles) {
CacheManager.removeAllCacheFiles();
}
}
diff --git a/core/java/android/webkit/ZoomManager.java b/core/java/android/webkit/ZoomManager.java
index 9a050c5..b47fe86 100644
--- a/core/java/android/webkit/ZoomManager.java
+++ b/core/java/android/webkit/ZoomManager.java
@@ -232,12 +232,26 @@
}
private void setDefaultZoomScale(float defaultScale) {
+ final float originalDefault = mDefaultScale;
mDefaultScale = defaultScale;
mInvDefaultScale = 1 / defaultScale;
mDefaultMaxZoomScale = defaultScale * DEFAULT_MAX_ZOOM_SCALE_FACTOR;
mDefaultMinZoomScale = defaultScale * DEFAULT_MIN_ZOOM_SCALE_FACTOR;
- mMaxZoomScale = mDefaultMaxZoomScale;
- mMinZoomScale = mDefaultMinZoomScale;
+ if (originalDefault > 0.0 && mMaxZoomScale > 0.0) {
+ // Keeps max zoom scale when zoom density changes.
+ mMaxZoomScale = defaultScale / originalDefault * mMaxZoomScale;
+ } else {
+ mMaxZoomScale = mDefaultMaxZoomScale;
+ }
+ if (originalDefault > 0.0 && mMinZoomScale > 0.0) {
+ // Keeps min zoom scale when zoom density changes.
+ mMinZoomScale = defaultScale / originalDefault * mMinZoomScale;
+ } else {
+ mMinZoomScale = mDefaultMinZoomScale;
+ }
+ if (!exceedsMinScaleIncrement(mMinZoomScale, mMaxZoomScale)) {
+ mMaxZoomScale = mMinZoomScale;
+ }
}
public final float getScale() {
@@ -468,7 +482,7 @@
mTextWrapScale = scale;
}
- if (scale != mActualScale || force) {
+ if (exceedsMinScaleIncrement(scale, mActualScale) || force) {
float oldScale = mActualScale;
float oldInvScale = mInvActualScale;
diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java
index c27082f..6eb06ad 100644
--- a/core/java/android/widget/AdapterViewAnimator.java
+++ b/core/java/android/widget/AdapterViewAnimator.java
@@ -323,20 +323,6 @@
setDisplayedChild(mWhichChild - 1);
}
- /**
- * Shows only the specified child. The other displays Views exit the screen,
- * optionally with the with the {@link #getOutAnimation() out animation} and
- * the specified child enters the screen, optionally with the
- * {@link #getInAnimation() in animation}.
- *
- * @param childIndex The index of the child to be shown.
- * @param animate Whether or not to use the in and out animations, defaults
- * to true.
- */
- void showOnly(int childIndex, boolean animate) {
- showOnly(childIndex, animate, false);
- }
-
int modulo(int pos, int size) {
if (size > 0) {
return (size + (pos % size)) % size;
@@ -363,7 +349,7 @@
int getNumActiveViews() {
if (mAdapter != null) {
- return Math.min(mAdapter.getCount() + 1, mMaxNumActiveViews);
+ return Math.min(getCount() + 1, mMaxNumActiveViews);
} else {
return mMaxNumActiveViews;
}
@@ -371,7 +357,7 @@
int getWindowSize() {
if (mAdapter != null) {
- int adapterCount = mAdapter.getCount();
+ int adapterCount = getCount();
if (adapterCount <= getNumActiveViews() && mLoopViews) {
return adapterCount*mMaxNumActiveViews;
} else {
@@ -396,16 +382,16 @@
for (int i = mCurrentWindowStart; i <= mCurrentWindowEnd; i++) {
int index = modulo(i, getWindowSize());
- int adapterCount = mAdapter.getCount();
+ int adapterCount = getCount();
// get the fresh child from the adapter
- View updatedChild = mAdapter.getView(modulo(i, adapterCount), null, this);
+ final View updatedChild = mAdapter.getView(modulo(i, adapterCount), null, this);
if (mViewsMap.containsKey(index)) {
- FrameLayout fl = (FrameLayout) mViewsMap.get(index).view;
- // flush out the old child
- fl.removeAllViewsInLayout();
+ final FrameLayout fl = (FrameLayout) mViewsMap.get(index).view;
// add the new child to the frame, if it exists
if (updatedChild != null) {
+ // flush out the old child
+ fl.removeAllViewsInLayout();
fl.addView(updatedChild);
}
}
@@ -423,9 +409,19 @@
return new FrameLayout(mContext);
}
- void showOnly(int childIndex, boolean animate, boolean onLayout) {
+ /**
+ * Shows only the specified child. The other displays Views exit the screen,
+ * optionally with the with the {@link #getOutAnimation() out animation} and
+ * the specified child enters the screen, optionally with the
+ * {@link #getInAnimation() in animation}.
+ *
+ * @param childIndex The index of the child to be shown.
+ * @param animate Whether or not to use the in and out animations, defaults
+ * to true.
+ */
+ void showOnly(int childIndex, boolean animate) {
if (mAdapter == null) return;
- final int adapterCount = mAdapter.getCount();
+ final int adapterCount = getCount();
if (adapterCount == 0) return;
for (int i = 0; i < mPreviousViews.size(); i++) {
@@ -463,7 +459,7 @@
// This section clears out any items that are in our active views list
// but are outside the effective bounds of our window (this is becomes an issue
// at the extremities of the list, eg. where newWindowStartUnbounded < 0 or
- // newWindowEndUnbounded > mAdapter.getCount() - 1
+ // newWindowEndUnbounded > adapterCount - 1
for (Integer index : mViewsMap.keySet()) {
boolean remove = false;
if (!wrap && (index < rangeStart || index > rangeEnd)) {
@@ -531,22 +527,8 @@
mCurrentWindowEnd = newWindowEnd;
mCurrentWindowStartUnbounded = newWindowStartUnbounded;
}
-
- mFirstTime = false;
- if (!onLayout) {
- requestLayout();
- invalidate();
- } else {
- // If the Adapter tries to layout the current view when we get it using getView
- // above the layout will end up being ignored since we are currently laying out, so
- // we post a delayed requestLayout and invalidate
- mMainQueue.post(new Runnable() {
- public void run() {
- requestLayout();
- invalidate();
- }
- });
- }
+ requestLayout();
+ invalidate();
}
private void addChild(View child) {
@@ -702,21 +684,30 @@
measureChildren();
}
- @Override
- protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ void checkForAndHandleDataChanged() {
boolean dataChanged = mDataChanged;
if (dataChanged) {
- handleDataChanged();
+ post(new Runnable() {
+ public void run() {
+ handleDataChanged();
+ // if the data changes, mWhichChild might be out of the bounds of the adapter
+ // in this case, we reset mWhichChild to the beginning
+ if (mWhichChild >= getWindowSize()) {
+ mWhichChild = 0;
- // if the data changes, mWhichChild might be out of the bounds of the adapter
- // in this case, we reset mWhichChild to the beginning
- if (mWhichChild >= mAdapter.getCount()) {
- mWhichChild = 0;
-
- showOnly(mWhichChild, true, true);
- }
- refreshChildren();
+ showOnly(mWhichChild, true);
+ }
+ refreshChildren();
+ requestLayout();
+ }
+ });
}
+ mDataChanged = false;
+ }
+
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ checkForAndHandleDataChanged();
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -727,7 +718,6 @@
child.layout(mPaddingLeft, mPaddingTop, childRight, childBottom);
}
- mDataChanged = false;
}
static class SavedState extends BaseSavedState {
@@ -921,8 +911,10 @@
if (mAdapter != null) {
mDataSetObserver = new AdapterDataSetObserver();
mAdapter.registerDataSetObserver(mDataSetObserver);
+ mItemCount = mAdapter.getCount();
}
setFocusable(true);
+ setDisplayedChild(0);
}
/**
@@ -981,11 +973,21 @@
// items from the Adapter.
}
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} in order to advance the current view when
+ * it is being used within an app widget.
+ */
public void advance() {
showNext();
}
- public void willBeAdvancedByHost() {
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} to indicate that it will be
+ * automatically advancing the views of this {@link AdapterViewAnimator} by calling
+ * {@link AdapterViewAnimator#advance()} at some point in the future. This allows subclasses to
+ * perform any required setup, for example, to stop automatically advancing their children.
+ */
+ public void fyiWillBeAdvancedByHostKThx() {
}
@Override
diff --git a/core/java/android/widget/AdapterViewFlipper.java b/core/java/android/widget/AdapterViewFlipper.java
index 7721688..273c258 100644
--- a/core/java/android/widget/AdapterViewFlipper.java
+++ b/core/java/android/widget/AdapterViewFlipper.java
@@ -258,8 +258,14 @@
}
};
+ /**
+ * Called by an {@link android.appwidget.AppWidgetHost} to indicate that it will be
+ * automatically advancing the views of this {@link AdapterViewFlipper} by calling
+ * {@link AdapterViewFlipper#advance()} at some point in the future. This allows
+ * {@link AdapterViewFlipper} to prepare by no longer Advancing its children.
+ */
@Override
- public void willBeAdvancedByHost() {
+ public void fyiWillBeAdvancedByHostKThx() {
mAdvancedByHost = true;
updateRunning(false);
}
diff --git a/core/java/android/widget/Advanceable.java b/core/java/android/widget/Advanceable.java
index bb162de..dc13ebb7 100644
--- a/core/java/android/widget/Advanceable.java
+++ b/core/java/android/widget/Advanceable.java
@@ -34,5 +34,5 @@
* Called by the AppWidgetHost once before it begins to call advance(), allowing the
* collection to do any required setup.
*/
- public void willBeAdvancedByHost();
+ public void fyiWillBeAdvancedByHostKThx();
}
diff --git a/core/java/android/widget/ArrayAdapter.java b/core/java/android/widget/ArrayAdapter.java
index b4ece24..593cb59 100644
--- a/core/java/android/widget/ArrayAdapter.java
+++ b/core/java/android/widget/ArrayAdapter.java
@@ -25,9 +25,9 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
-import java.util.List;
-import java.util.Comparator;
import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
/**
* A concrete BaseAdapter that is backed by an array of arbitrary
@@ -86,6 +86,8 @@
private Context mContext;
+ // A copy of the original mObjects array, initialized from and then used instead as soon as
+ // the mFilter ArrayFilter is used. mObjects will then only contain the filtered values.
private ArrayList<T> mOriginalValues;
private ArrayFilter mFilter;
@@ -170,15 +172,14 @@
* @param object The object to add at the end of the array.
*/
public void add(T object) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.add(object);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.add(object);
}
- } else {
- mObjects.add(object);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -187,15 +188,14 @@
* @param collection The Collection to add at the end of the array.
*/
public void addAll(Collection<? extends T> collection) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.addAll(collection);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.addAll(collection);
}
- } else {
- mObjects.addAll(collection);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -204,19 +204,18 @@
* @param items The items to add at the end of the array.
*/
public void addAll(T ... items) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
for (T item : items) {
mOriginalValues.add(item);
}
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ for (T item : items) {
+ mObjects.add(item);
+ }
}
- } else {
- for (T item : items) {
- mObjects.add(item);
- }
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -226,15 +225,14 @@
* @param index The index at which the object must be inserted.
*/
public void insert(T object, int index) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.add(index, object);
- if (mNotifyOnChange) notifyDataSetChanged();
+ } else {
+ mObjects.add(index, object);
}
- } else {
- mObjects.add(index, object);
- if (mNotifyOnChange) notifyDataSetChanged();
}
+ if (mNotifyOnChange) notifyDataSetChanged();
}
/**
@@ -243,12 +241,12 @@
* @param object The object to remove.
*/
public void remove(T object) {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.remove(object);
+ } else {
+ mObjects.remove(object);
}
- } else {
- mObjects.remove(object);
}
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -257,12 +255,12 @@
* Remove all elements from the list.
*/
public void clear() {
- if (mOriginalValues != null) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
mOriginalValues.clear();
+ } else {
+ mObjects.clear();
}
- } else {
- mObjects.clear();
}
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -274,7 +272,13 @@
* in this adapter.
*/
public void sort(Comparator<? super T> comparator) {
- Collections.sort(mObjects, comparator);
+ synchronized (mLock) {
+ if (mOriginalValues != null) {
+ Collections.sort(mOriginalValues, comparator);
+ } else {
+ Collections.sort(mObjects, comparator);
+ }
+ }
if (mNotifyOnChange) notifyDataSetChanged();
}
@@ -482,6 +486,7 @@
final String[] words = valueText.split(" ");
final int wordCount = words.length;
+ // Start at index 0, in case valueText starts with space(s)
for (int k = 0; k < wordCount; k++) {
if (words[k].startsWith(prefixString)) {
newValues.add(value);
diff --git a/core/java/android/widget/AutoCompleteTextView.java b/core/java/android/widget/AutoCompleteTextView.java
index 4d8d21f..707b92d5 100644
--- a/core/java/android/widget/AutoCompleteTextView.java
+++ b/core/java/android/widget/AutoCompleteTextView.java
@@ -16,6 +16,8 @@
package android.widget;
+import com.android.internal.R;
+
import android.content.Context;
import android.content.res.TypedArray;
import android.database.DataSetObserver;
@@ -36,8 +38,6 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputMethodManager;
-import com.android.internal.R;
-
/**
* <p>An editable text view that shows completion suggestions automatically
@@ -113,6 +113,7 @@
private Validator mValidator = null;
+ // Set to true when text is set directly and no filtering shall be performed
private boolean mBlockCompletion;
private PassThroughClickListener mPassThroughClickListener;
@@ -721,6 +722,10 @@
return;
}
+ updateList();
+ }
+
+ private void updateList() {
// the drop down is shown only when a minimum number of characters
// was typed in the text view
if (enoughToFilter()) {
@@ -840,7 +845,7 @@
mBlockCompletion = true;
replaceText(convertSelectionToString(selectedItem));
- mBlockCompletion = false;
+ mBlockCompletion = false;
if (mItemClickListener != null) {
final ListPopupWindow list = mPopup;
@@ -903,10 +908,10 @@
/** {@inheritDoc} */
public void onFilterComplete(int count) {
- updateDropDownForFilter(count);
+ updateDropDownForFilter(count, true);
}
- private void updateDropDownForFilter(int count) {
+ private void updateDropDownForFilter(int count, boolean forceShow) {
// Not attached to window, don't update drop-down
if (getWindowVisibility() == View.GONE) return;
@@ -919,7 +924,7 @@
final boolean dropDownAlwaysVisible = mPopup.isDropDownAlwaysVisible();
if ((count > 0 || dropDownAlwaysVisible) && enoughToFilter()) {
- if (hasFocus() && hasWindowFocus()) {
+ if (hasFocus() && hasWindowFocus() && (forceShow || isPopupShowing())) {
showDropDown();
}
} else if (!dropDownAlwaysVisible) {
@@ -1182,12 +1187,14 @@
// If the popup is not showing already, showing it will cause
// the list of data set observers attached to the adapter to
// change. We can't do it from here, because we are in the middle
- // of iterating throught he list of observers.
+ // of iterating through the list of observers.
post(new Runnable() {
public void run() {
final ListAdapter adapter = mAdapter;
if (adapter != null) {
- updateDropDownForFilter(adapter.getCount());
+ // This will re-layout, thus resetting mDataChanged, so that the
+ // listView click listener stays responsive
+ updateDropDownForFilter(adapter.getCount(), false);
}
}
});
diff --git a/core/java/android/widget/DatePicker.java b/core/java/android/widget/DatePicker.java
index 2c53005..f1786e2 100644
--- a/core/java/android/widget/DatePicker.java
+++ b/core/java/android/widget/DatePicker.java
@@ -30,7 +30,7 @@
import android.util.Log;
import android.util.SparseArray;
import android.view.LayoutInflater;
-import android.widget.NumberPicker.OnValueChangedListener;
+import android.widget.NumberPicker.OnValueChangeListener;
import java.text.ParseException;
import java.text.SimpleDateFormat;
@@ -129,29 +129,32 @@
}
public DatePicker(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ this(context, attrs, R.attr.datePickerStyle);
}
public DatePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker);
+ TypedArray attributesArray = context.obtainStyledAttributes(attrs, R.styleable.DatePicker,
+ defStyle, 0);
boolean spinnersShown = attributesArray.getBoolean(R.styleable.DatePicker_spinnersShown,
DEFAULT_SPINNERS_SHOWN);
boolean calendarViewShown = attributesArray.getBoolean(
R.styleable.DatePicker_calendarViewShown, DEFAULT_CALENDAR_VIEW_SHOWN);
- int startYear = attributesArray
- .getInt(R.styleable.DatePicker_startYear, DEFAULT_START_YEAR);
+ int startYear = attributesArray.getInt(R.styleable.DatePicker_startYear,
+ DEFAULT_START_YEAR);
int endYear = attributesArray.getInt(R.styleable.DatePicker_endYear, DEFAULT_END_YEAR);
String minDate = attributesArray.getString(R.styleable.DatePicker_minDate);
String maxDate = attributesArray.getString(R.styleable.DatePicker_maxDate);
+ int layoutResourceId = attributesArray.getResourceId(R.styleable.DatePicker_layout,
+ R.layout.date_picker);
attributesArray.recycle();
LayoutInflater inflater = (LayoutInflater) context
.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(R.layout.date_picker, this, true);
+ inflater.inflate(layoutResourceId, this, true);
- OnValueChangedListener onChangeListener = new OnValueChangedListener() {
+ OnValueChangeListener onChangeListener = new OnValueChangeListener() {
public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
updateDate(mYearSpinner.getValue(), mMonthSpinner.getValue(), mDaySpinner
.getValue());
diff --git a/core/java/android/widget/HorizontalScrollView.java b/core/java/android/widget/HorizontalScrollView.java
index f6b1dbc..db22a0c 100644
--- a/core/java/android/widget/HorizontalScrollView.java
+++ b/core/java/android/widget/HorizontalScrollView.java
@@ -511,8 +511,10 @@
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
- final float x = ev.getX();
- mIsBeingDragged = true;
+ mIsBeingDragged = getChildCount() != 0;
+ if (!mIsBeingDragged) {
+ return false;
+ }
/*
* If being flinged and user touches, stop the fling. isFinished
@@ -523,7 +525,7 @@
}
// Remember where the motion event started
- mLastMotionX = x;
+ mLastMotionX = ev.getX();
mActivePointerId = ev.getPointerId(0);
break;
}
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 63dbfbf..08db207 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -32,6 +32,7 @@
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Paint.Align;
+import android.graphics.drawable.Drawable;
import android.text.InputFilter;
import android.text.InputType;
import android.text.Spanned;
@@ -39,6 +40,7 @@
import android.text.method.NumberKeyListener;
import android.util.AttributeSet;
import android.util.SparseArray;
+import android.util.TypedValue;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.MotionEvent;
@@ -46,7 +48,7 @@
import android.view.View;
import android.view.ViewConfiguration;
import android.view.LayoutInflater.Filter;
-import android.view.animation.OvershootInterpolator;
+import android.view.animation.DecelerateInterpolator;
import android.view.inputmethod.InputMethodManager;
/**
@@ -62,8 +64,6 @@
* <p>
* For an example of using this widget, see {@link android.widget.TimePicker}.
* </p>
- *
- * @attr ref android.R.styleable#NumberPicker_solidColor
*/
@Widget
public class NumberPicker extends LinearLayout {
@@ -111,6 +111,11 @@
private static final float TOP_AND_BOTTOM_FADING_EDGE_STRENGTH = 0.9f;
/**
+ * The default unscaled height of the selection divider.
+ */
+ private final int UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT = 2;
+
+ /**
* The numbers accepted by the input text's {@link Filter}
*/
private static final char[] DIGIT_CHARACTERS = new char[] {
@@ -183,7 +188,7 @@
/**
* Listener to be notified upon current value change.
*/
- private OnValueChangedListener mOnValueChangedListener;
+ private OnValueChangeListener mOnValueChangeListener;
/**
* Listener to be notified upon scroll state change.
@@ -325,6 +330,21 @@
private final int mSolidColor;
/**
+ * Flag indicating if this widget supports flinging.
+ */
+ private final boolean mFlingable;
+
+ /**
+ * Divider for showing item to be selected while scrolling
+ */
+ private final Drawable mSelectionDivider;
+
+ /**
+ * The height of the selection divider.
+ */
+ private final int mSelectionDividerHeight;
+
+ /**
* Reusable {@link Rect} instance.
*/
private final Rect mTempRect = new Rect();
@@ -335,9 +355,14 @@
private int mScrollState = OnScrollListener.SCROLL_STATE_IDLE;
/**
+ * The duration of the animation for showing the input controls.
+ */
+ private final long mShowInputControlsAnimimationDuration;
+
+ /**
* Interface to listen for changes of the current value.
*/
- public interface OnValueChangedListener {
+ public interface OnValueChangeListener {
/**
* Called upon a change of the current value.
@@ -427,11 +452,19 @@
// process style attributes
TypedArray attributesArray = context.obtainStyledAttributes(attrs,
R.styleable.NumberPicker, defStyle, 0);
- int orientation = attributesArray.getInt(R.styleable.NumberPicker_orientation, VERTICAL);
- setOrientation(orientation);
mSolidColor = attributesArray.getColor(R.styleable.NumberPicker_solidColor, 0);
+ mFlingable = attributesArray.getBoolean(R.styleable.NumberPicker_flingable, true);
+ mSelectionDivider = attributesArray.getDrawable(R.styleable.NumberPicker_selectionDivider);
+ int defSelectionDividerHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP,
+ UNSCALED_DEFAULT_SELECTION_DIVIDER_HEIGHT,
+ getResources().getDisplayMetrics());
+ mSelectionDividerHeight = attributesArray.getDimensionPixelSize(
+ R.styleable.NumberPicker_selectionDividerHeight, defSelectionDividerHeight);
attributesArray.recycle();
+ mShowInputControlsAnimimationDuration = getResources().getInteger(
+ R.integer.config_longAnimTime);
+
// By default Linearlayout that we extend is not drawn. This is
// its draw() method is not called but dispatchDraw() is called
// directly (see ViewGroup.drawChild()). However, this class uses
@@ -521,8 +554,6 @@
mShowInputControlsAnimator = new AnimatorSet();
mShowInputControlsAnimator.playTogether(fadeScroller, showIncrementButton,
showDecrementButton);
- mShowInputControlsAnimator.setDuration(getResources().getInteger(
- R.integer.config_longAnimTime));
mShowInputControlsAnimator.addListener(new AnimatorListenerAdapter() {
private boolean mCanceled = false;
@@ -547,23 +578,30 @@
// create the fling and adjust scrollers
mFlingScroller = new Scroller(getContext(), null, true);
- mAdjustScroller = new Scroller(getContext(), new OvershootInterpolator());
+ mAdjustScroller = new Scroller(getContext(), new DecelerateInterpolator(2.5f));
updateInputTextView();
updateIncrementAndDecrementButtonsVisibilityState();
- }
- @Override
- public void onWindowFocusChanged(boolean hasWindowFocus) {
- super.onWindowFocusChanged(hasWindowFocus);
- if (!hasWindowFocus) {
- removeAllCallbacks();
+ if (mFlingable) {
+ // Start with shown selector wheel and hidden controls. When made
+ // visible hide the selector and fade-in the controls to suggest
+ // fling interaction.
+ setDrawSelectorWheel(true);
+ hideInputControls();
}
}
@Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ // need to do this when we know our size
+ initializeScrollWheel();
+ }
+
+ @Override
public boolean onInterceptTouchEvent(MotionEvent event) {
- if (!isEnabled()) {
+ if (!isEnabled() || !mFlingable) {
return false;
}
switch (event.getActionMasked()) {
@@ -578,7 +616,7 @@
if (!scrollersFinished) {
mFlingScroller.forceFinished(true);
mAdjustScroller.forceFinished(true);
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_IDLE);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
}
mBeginEditOnUpEvent = scrollersFinished;
mAdjustScrollerOnUpEvent = true;
@@ -597,7 +635,7 @@
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
mBeginEditOnUpEvent = false;
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
setDrawSelectorWheel(true);
hideInputControls();
return true;
@@ -625,7 +663,7 @@
int deltaDownY = (int) Math.abs(currentMoveY - mLastDownEventY);
if (deltaDownY > mTouchSlop) {
mBeginEditOnUpEvent = false;
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_TOUCH_SCROLL);
}
}
int deltaMoveY = (int) (currentMoveY - mLastMotionEventY);
@@ -636,7 +674,7 @@
case MotionEvent.ACTION_UP:
if (mBeginEditOnUpEvent) {
setDrawSelectorWheel(false);
- showInputControls();
+ showInputControls(mShowInputControlsAnimimationDuration);
mInputText.requestFocus();
InputMethodManager imm = (InputMethodManager) getContext().getSystemService(
Context.INPUT_METHOD_SERVICE);
@@ -649,7 +687,7 @@
int initialVelocity = (int) velocityTracker.getYVelocity();
if (Math.abs(initialVelocity) > mMinimumFlingVelocity) {
fling(initialVelocity);
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_FLING);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_FLING);
} else {
if (mAdjustScrollerOnUpEvent) {
if (mFlingScroller.isFinished() && mAdjustScroller.isFinished()) {
@@ -731,18 +769,6 @@
@Override
public void scrollBy(int x, int y) {
int[] selectorIndices = getSelectorIndices();
- if (mInitialScrollOffset == Integer.MIN_VALUE) {
- int totalTextHeight = selectorIndices.length * mTextSize;
- int totalTextGapHeight = (mBottom - mTop) - totalTextHeight;
- int textGapCount = selectorIndices.length - 1;
- int selectorTextGapHeight = totalTextGapHeight / textGapCount;
- // compensate for integer division loss of the components used to
- // calculate the text gap
- int integerDivisionLoss = (mTextSize + mBottom - mTop) % textGapCount;
- mInitialScrollOffset = mCurrentScrollOffset = mTextSize - integerDivisionLoss / 2;
- mSelectorElementHeight = mTextSize + selectorTextGapHeight;
- }
-
if (!mWrapSelectorWheel && y > 0
&& selectorIndices[SELECTOR_MIDDLE_ITEM_INDEX] <= mMinValue) {
mCurrentScrollOffset = mInitialScrollOffset;
@@ -782,8 +808,8 @@
*
* @param onValueChangedListener The listener.
*/
- public void setOnValueChangedListener(OnValueChangedListener onValueChangedListener) {
- mOnValueChangedListener = onValueChangedListener;
+ public void setOnValueChangedListener(OnValueChangeListener onValueChangedListener) {
+ mOnValueChangeListener = onValueChangedListener;
}
/**
@@ -813,6 +839,7 @@
}
mFormatter = formatter;
resetSelectorWheelIndices();
+ updateInputTextView();
}
/**
@@ -1021,6 +1048,17 @@
}
@Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ // make sure we show the controls only the very
+ // first time the user sees this widget
+ if (mFlingable) {
+ // animate a bit slower the very first time
+ showInputControls(mShowInputControlsAnimimationDuration * 2);
+ }
+ }
+
+ @Override
protected void onDetachedFromWindow() {
removeAllCallbacks();
}
@@ -1039,9 +1077,7 @@
// However, in View.draw(), the fading is applied after all the children
// have been drawn and we do not want this fading to be applied to the
// buttons which are currently showing in. Therefore, we draw our
- // children
- // after we have completed drawing ourselves.
-
+ // children after we have completed drawing ourselves.
super.draw(canvas);
// Draw our children if we are not showing the selector wheel of fading
@@ -1067,6 +1103,7 @@
float x = (mRight - mLeft) / 2;
float y = mCurrentScrollOffset;
+ // draw the selector wheel
int[] selectorIndices = getSelectorIndices();
for (int i = 0; i < selectorIndices.length; i++) {
int selectorIndex = selectorIndices[i];
@@ -1074,6 +1111,23 @@
canvas.drawText(scrollSelectorValue, x, y, mSelectorPaint);
y += mSelectorElementHeight;
}
+
+ // draw the selection dividers (only if scrolling and drawable specified)
+ if (mSelectionDivider != null) {
+ mSelectionDivider.setAlpha(mSelectorPaint.getAlpha());
+ // draw the top divider
+ int topOfTopDivider =
+ (getHeight() - mSelectorElementHeight - mSelectionDividerHeight) / 2;
+ int bottomOfTopDivider = topOfTopDivider + mSelectionDividerHeight;
+ mSelectionDivider.setBounds(0, topOfTopDivider, mRight, bottomOfTopDivider);
+ mSelectionDivider.draw(canvas);
+
+ // draw the bottom divider
+ int topOfBottomDivider = topOfTopDivider + mSelectorElementHeight;
+ int bottomOfBottomDivider = bottomOfTopDivider + mSelectorElementHeight;
+ mSelectionDivider.setBounds(0, topOfBottomDivider, mRight, bottomOfBottomDivider);
+ mSelectionDivider.draw(canvas);
+ }
}
/**
@@ -1139,26 +1193,46 @@
setVerticalFadingEdgeEnabled(drawSelectorWheel);
}
+ private void initializeScrollWheel() {
+ if (mInitialScrollOffset != Integer.MIN_VALUE) {
+ return;
+
+ }
+ int[] selectorIndices = getSelectorIndices();
+ int totalTextHeight = selectorIndices.length * mTextSize;
+ int totalTextGapHeight = (mBottom - mTop) - totalTextHeight;
+ int textGapCount = selectorIndices.length - 1;
+ int selectorTextGapHeight = totalTextGapHeight / textGapCount;
+ // compensate for integer division loss of the components used to
+ // calculate the text gap
+ int integerDivisionLoss = (mTextSize + mBottom - mTop) % textGapCount;
+ mInitialScrollOffset = mCurrentScrollOffset = mTextSize - integerDivisionLoss / 2;
+ mSelectorElementHeight = mTextSize + selectorTextGapHeight;
+ updateInputTextView();
+ }
+
/**
* Callback invoked upon completion of a given <code>scroller</code>.
*/
private void onScrollerFinished(Scroller scroller) {
if (scroller == mFlingScroller) {
postAdjustScrollerCommand(0);
- tryNotifyScrollListener(OnScrollListener.SCROLL_STATE_IDLE);
+ onScrollStateChange(OnScrollListener.SCROLL_STATE_IDLE);
} else {
updateInputTextView();
- showInputControls();
+ showInputControls(mShowInputControlsAnimimationDuration);
}
}
/**
- * Notifies the scroll listener for the given <code>scrollState</code>
- * if the scroll state differs from the current scroll state.
+ * Handles transition to a given <code>scrollState</code>
*/
- private void tryNotifyScrollListener(int scrollState) {
- if (mOnScrollListener != null && mScrollState != scrollState) {
- mScrollState = scrollState;
+ private void onScrollStateChange(int scrollState) {
+ if (mScrollState == scrollState) {
+ return;
+ }
+ mScrollState = scrollState;
+ if (mOnScrollListener != null) {
mOnScrollListener.onScrollStateChange(this, scrollState);
}
}
@@ -1204,10 +1278,13 @@
/**
* Show the input controls by making them visible and animating the alpha
* property up/down arrows.
+ *
+ * @param animationDuration The duration of the animation.
*/
- private void showInputControls() {
+ private void showInputControls(long animationDuration) {
updateIncrementAndDecrementButtonsVisibilityState();
mInputText.setVisibility(VISIBLE);
+ mShowInputControlsAnimator.setDuration(animationDuration);
mShowInputControlsAnimator.start();
}
@@ -1332,9 +1409,9 @@
/**
* Updates the view of this NumberPicker. If displayValues were specified in
- * {@link #setRange}, the string corresponding to the index specified by the
- * current value will be returned. Otherwise, the formatter specified in
- * {@link #setFormatter} will be used to format the number.
+ * the string corresponding to the index specified by the current value will
+ * be returned. Otherwise, the formatter specified in {@link #setFormatter}
+ * will be used to format the number.
*/
private void updateInputTextView() {
/*
@@ -1355,8 +1432,8 @@
* NumberPicker.
*/
private void notifyChange(int previous, int current) {
- if (mOnValueChangedListener != null) {
- mOnValueChangedListener.onValueChange(this, previous, mValue);
+ if (mOnValueChangeListener != null) {
+ mOnValueChangeListener.onValueChange(this, previous, mValue);
}
}
@@ -1538,7 +1615,7 @@
mPreviousScrollerY = 0;
if (mInitialScrollOffset == mCurrentScrollOffset) {
updateInputTextView();
- showInputControls();
+ showInputControls(mShowInputControlsAnimimationDuration);
return;
}
// adjust to the closest value
@@ -1546,9 +1623,7 @@
if (Math.abs(deltaY) > mSelectorElementHeight / 2) {
deltaY += (deltaY > 0) ? -mSelectorElementHeight : mSelectorElementHeight;
}
- float delayCoef = (float) Math.abs(deltaY) / (float) mTextSize;
- int duration = (int) (delayCoef * SELECTOR_ADJUSTMENT_DURATION_MILLIS);
- mAdjustScroller.startScroll(0, 0, 0, deltaY, duration);
+ mAdjustScroller.startScroll(0, 0, 0, deltaY, SELECTOR_ADJUSTMENT_DURATION_MILLIS);
invalidate();
}
}
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index 79d6a81..439e0ca 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -28,7 +28,6 @@
import android.os.Build;
import android.os.IBinder;
import android.util.AttributeSet;
-import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.MotionEvent;
@@ -1087,7 +1086,14 @@
p.width = Math.min(p.width, displayFrameWidth);
}
- p.y = Math.max(p.y, displayFrame.top);
+ if (onTop) {
+ int popupTop = mScreenLocation[1] + yoff - mPopupHeight;
+ if (popupTop < 0) {
+ p.y += popupTop;
+ }
+ } else {
+ p.y = Math.max(p.y, displayFrame.top);
+ }
}
p.gravity |= Gravity.DISPLAY_CLIP_VERTICAL;
diff --git a/core/java/android/widget/RemoteViews.java b/core/java/android/widget/RemoteViews.java
index c336ccb..482ce56 100644
--- a/core/java/android/widget/RemoteViews.java
+++ b/core/java/android/widget/RemoteViews.java
@@ -1277,18 +1277,6 @@
/**
* Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
*
- * @param viewId The id of the view whose text should change
- * @param intent The intent of the service which will be
- * providing data to the RemoteViewsAdapter
- */
- public void setRemoteAdapter(int viewId, Intent intent) {
- // Do nothing. This method will be removed after all widgets have been updated to the
- // new API.
- }
-
- /**
- * Equivalent to calling {@link android.widget.AbsListView#setRemoteViewsAdapter(Intent)}.
- *
* @param appWidgetId The id of the app widget which contains the specified view
* @param viewId The id of the view whose text should change
* @param intent The intent of the service which will be
diff --git a/core/java/android/widget/RemoteViewsService.java b/core/java/android/widget/RemoteViewsService.java
index 16126aa..e5a3de2 100644
--- a/core/java/android/widget/RemoteViewsService.java
+++ b/core/java/android/widget/RemoteViewsService.java
@@ -42,7 +42,7 @@
/**
* An interface for an adapter between a remote collection view (ListView, GridView, etc) and
* the underlying data for that view. The implementor is responsible for making a RemoteView
- * for each item in the data set.
+ * for each item in the data set. This interface is a thin wrapper around {@link Adapter}.
*
* @see android.widget.Adapter
* @see android.appwidget.AppWidgetManager
@@ -53,24 +53,72 @@
* multiple RemoteViewAdapters depending on the intent passed.
*/
public void onCreate();
+
/**
* Called when notifyDataSetChanged() is triggered on the remote adapter. This allows a
* RemoteViewsFactory to respond to data changes by updating any internal references.
*
+ * Note: expensive tasks can be safely performed synchronously within this method. In the
+ * interim, the old data will be displayed within the widget.
+ *
* @see android.appwidget.AppWidgetManager#notifyAppWidgetViewDataChanged(int[], int)
*/
public void onDataSetChanged();
+
/**
* Called when the last RemoteViewsAdapter that is associated with this factory is
* unbound.
*/
public void onDestroy();
+ /**
+ * See {@link Adapter#getCount()}
+ *
+ * @return Count of items.
+ */
public int getCount();
+
+ /**
+ * See {@link Adapter#getView(int, android.view.View, android.view.ViewGroup)}.
+ *
+ * Note: expensive tasks can be safely performed synchronously within this method, and a
+ * loading view will be displayed in the interim. See {@link #getLoadingView()}.
+ *
+ * @param position The position of the item within the Factory's data set of the item whose
+ * view we want.
+ * @return A RemoteViews object corresponding to the data at the specified position.
+ */
public RemoteViews getViewAt(int position);
+
+ /**
+ * This allows for the use of a custom loading view which appears between the time that
+ * {@link #getViewAt(int)} is called and returns. If null is returned, a default loading
+ * view will be used.
+ *
+ * @return The RemoteViews representing the desired loading view.
+ */
public RemoteViews getLoadingView();
+
+ /**
+ * See {@link Adapter#getViewTypeCount()}.
+ *
+ * @return The number of types of Views that will be returned by this factory.
+ */
public int getViewTypeCount();
+
+ /**
+ * See {@link Adapter#getItemId(int)}.
+ *
+ * @param position The position of the item within the data set whose row id we want.
+ * @return The id of the item at the specified position.
+ */
public long getItemId(int position);
+
+ /**
+ * See {@link Adapter#hasStableIds()}.
+ *
+ * @return True if the same id always refers to the same object.
+ */
public boolean hasStableIds();
}
diff --git a/core/java/android/widget/ScrollView.java b/core/java/android/widget/ScrollView.java
index 8558c70..ce6da72 100644
--- a/core/java/android/widget/ScrollView.java
+++ b/core/java/android/widget/ScrollView.java
@@ -521,8 +521,10 @@
switch (action & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN: {
- final float y = ev.getY();
- mIsBeingDragged = true;
+ mIsBeingDragged = getChildCount() != 0;
+ if (!mIsBeingDragged) {
+ return false;
+ }
/*
* If being flinged and user touches, stop the fling. isFinished
@@ -537,7 +539,7 @@
}
// Remember where the motion event started
- mLastMotionY = y;
+ mLastMotionY = ev.getY();
mActivePointerId = ev.getPointerId(0);
break;
}
diff --git a/core/java/android/widget/SearchView.java b/core/java/android/widget/SearchView.java
index 585dcf2..b86366c 100644
--- a/core/java/android/widget/SearchView.java
+++ b/core/java/android/widget/SearchView.java
@@ -72,10 +72,10 @@
private static final boolean DBG = false;
private static final String LOG_TAG = "SearchView";
- private OnQueryChangeListener mOnQueryChangeListener;
+ private OnQueryTextListener mOnQueryChangeListener;
private OnCloseListener mOnCloseListener;
private OnFocusChangeListener mOnQueryTextFocusChangeListener;
- private OnSuggestionSelectionListener mOnSuggestionListener;
+ private OnSuggestionListener mOnSuggestionListener;
private OnClickListener mOnSearchClickListener;
private boolean mIconifiedByDefault;
@@ -109,7 +109,7 @@
/**
* Callbacks for changes to the query text.
*/
- public interface OnQueryChangeListener {
+ public interface OnQueryTextListener {
/**
* Called when the user submits the query. This could be due to a key press on the
@@ -123,7 +123,7 @@
* @return true if the query has been handled by the listener, false to let the
* SearchView perform the default action.
*/
- boolean onSubmitQuery(String query);
+ boolean onQueryTextSubmit(String query);
/**
* Called when the query text is changed by the user.
@@ -133,7 +133,7 @@
* @return false if the SearchView should perform the default action of showing any
* suggestions if available, true if the action was handled by the listener.
*/
- boolean onQueryTextChanged(String newText);
+ boolean onQueryTextChange(String newText);
}
public interface OnCloseListener {
@@ -151,7 +151,7 @@
* Callback interface for selection events on suggestions. These callbacks
* are only relevant when a SearchableInfo has been specified by {@link #setSearchableInfo}.
*/
- public interface OnSuggestionSelectionListener {
+ public interface OnSuggestionListener {
/**
* Called when a suggestion was selected by navigating to it.
@@ -160,7 +160,7 @@
* @return true if the listener handles the event and wants to override the default
* behavior of possibly rewriting the query based on the selected item, false otherwise.
*/
- boolean onSuggestionSelected(int position);
+ boolean onSuggestionSelect(int position);
/**
* Called when a suggestion was clicked.
@@ -170,7 +170,7 @@
* behavior of launching any intent or submitting a search query specified on that item.
* Return false otherwise.
*/
- boolean onSuggestionClicked(int position);
+ boolean onSuggestionClick(int position);
}
public SearchView(Context context) {
@@ -282,7 +282,7 @@
* @param listener the listener object that receives callbacks when the user performs
* actions in the SearchView such as clicking on buttons or typing a query.
*/
- public void setOnQueryChangeListener(OnQueryChangeListener listener) {
+ public void setOnQueryTextListener(OnQueryTextListener listener) {
mOnQueryChangeListener = listener;
}
@@ -309,7 +309,7 @@
*
* @param listener the listener to inform of suggestion selection events.
*/
- public void setOnSuggestionSelectionListener(OnSuggestionSelectionListener listener) {
+ public void setOnSuggestionListener(OnSuggestionListener listener) {
mOnSuggestionListener = listener;
}
@@ -865,7 +865,7 @@
updateCloseButton();
updateSubmitArea();
if (mOnQueryChangeListener != null) {
- mOnQueryChangeListener.onQueryTextChanged(newText.toString());
+ mOnQueryChangeListener.onQueryTextChange(newText.toString());
}
}
@@ -873,7 +873,7 @@
CharSequence query = mQueryTextView.getText();
if (!TextUtils.isEmpty(query)) {
if (mOnQueryChangeListener == null
- || !mOnQueryChangeListener.onSubmitQuery(query.toString())) {
+ || !mOnQueryChangeListener.onQueryTextSubmit(query.toString())) {
if (mSearchable != null) {
launchQuerySearch(KeyEvent.KEYCODE_UNKNOWN, null, query.toString());
setImeVisibility(false);
@@ -940,7 +940,7 @@
private boolean onItemClicked(int position, int actionKey, String actionMsg) {
if (mOnSuggestionListener == null
- || !mOnSuggestionListener.onSuggestionClicked(position)) {
+ || !mOnSuggestionListener.onSuggestionClick(position)) {
launchSuggestion(position, KeyEvent.KEYCODE_UNKNOWN, null);
setImeVisibility(false);
dismissSuggestions();
@@ -951,7 +951,7 @@
private boolean onItemSelected(int position) {
if (mOnSuggestionListener == null
- || !mOnSuggestionListener.onSuggestionSelected(position)) {
+ || !mOnSuggestionListener.onSuggestionSelect(position)) {
rewriteQueryFromSuggestion(position);
return true;
}
diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java
index 2c10077..9ec4b74 100644
--- a/core/java/android/widget/StackView.java
+++ b/core/java/android/widget/StackView.java
@@ -347,6 +347,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
@android.view.RemotableViewMethod
public void showNext() {
@@ -362,6 +365,9 @@
super.showNext();
}
+ /**
+ * {@inheritDoc}
+ */
@Override
@android.view.RemotableViewMethod
public void showPrevious() {
@@ -378,8 +384,8 @@
}
@Override
- void showOnly(int childIndex, boolean animate, boolean onLayout) {
- super.showOnly(childIndex, animate, onLayout);
+ void showOnly(int childIndex, boolean animate) {
+ super.showOnly(childIndex, animate);
// Here we need to make sure that the z-order of the children is correct
for (int i = mCurrentWindowEnd; i >= mCurrentWindowStart; i--) {
@@ -474,6 +480,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean onInterceptTouchEvent(MotionEvent ev) {
int action = ev.getAction();
@@ -520,7 +529,7 @@
requestDisallowInterceptTouchEvent(true);
if (mAdapter == null) return;
- final int adapterCount = mAdapter.getCount();
+ final int adapterCount = getCount();
int activeIndex;
if (mStackMode == ITEMS_SLIDE_UP) {
@@ -561,6 +570,9 @@
}
}
+ /**
+ * {@inheritDoc}
+ */
@Override
public boolean onTouchEvent(MotionEvent ev) {
super.onTouchEvent(ev);
@@ -939,16 +951,6 @@
}
}
- @Override
- public void onRemoteAdapterConnected() {
- super.onRemoteAdapterConnected();
- // On first run, we want to set the stack to the end.
- if (mWhichChild == -1) {
- mWhichChild = 0;
- }
- setDisplayedChild(mWhichChild);
- }
-
LayoutParams createOrReuseLayoutParams(View v) {
final ViewGroup.LayoutParams currentLp = v.getLayoutParams();
if (currentLp instanceof LayoutParams) {
@@ -964,18 +966,7 @@
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
- boolean dataChanged = mDataChanged;
- if (dataChanged) {
- handleDataChanged();
-
- // if the data changes, mWhichChild might be out of the bounds of the adapter
- // in this case, we reset mWhichChild to the beginning
- if (mWhichChild >= mAdapter.getCount())
- mWhichChild = 0;
-
- showOnly(mWhichChild, true, true);
- refreshChildren();
- }
+ checkForAndHandleDataChanged();
final int childCount = getChildCount();
for (int i = 0; i < childCount; i++) {
@@ -989,8 +980,6 @@
childRight + lp.horizontalOffset, childBottom + lp.verticalOffset);
}
-
- mDataChanged = false;
onLayout();
}
@@ -999,7 +988,7 @@
long timeSinceLastInteraction = System.currentTimeMillis() - mLastInteractionTime;
if (mAdapter == null) return;
- final int adapterCount = mAdapter.getCount();
+ final int adapterCount = getCount();
if (adapterCount == 1 && mLoopViews) return;
if (mSwipeGestureType == GESTURE_NONE &&
@@ -1074,6 +1063,7 @@
heightSpecSize = height;
} else {
heightSpecSize |= MEASURED_STATE_TOO_SMALL;
+
}
} else {
heightSpecSize = 0;
@@ -1097,7 +1087,6 @@
widthSpecSize = 0;
}
}
-
setMeasuredDimension(widthSpecSize, heightSpecSize);
measureChildren();
}
@@ -1279,4 +1268,4 @@
mask.recycle();
}
}
-}
\ No newline at end of file
+}
diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java
index 1ebe622..2cfc016 100644
--- a/core/java/android/widget/SuggestionsAdapter.java
+++ b/core/java/android/widget/SuggestionsAdapter.java
@@ -78,15 +78,15 @@
// URL color
private ColorStateList mUrlColor;
- // Cached column indexes, updated when the cursor changes.
- private int mText1Col;
- private int mText2Col;
- private int mText2UrlCol;
- private int mIconName1Col;
- private int mIconName2Col;
- private int mFlagsCol;
+ static final int INVALID_INDEX = -1;
- static final int NONE = -1;
+ // Cached column indexes, updated when the cursor changes.
+ private int mText1Col = INVALID_INDEX;
+ private int mText2Col = INVALID_INDEX;
+ private int mText2UrlCol = INVALID_INDEX;
+ private int mIconName1Col = INVALID_INDEX;
+ private int mIconName2Col = INVALID_INDEX;
+ private int mFlagsCol = INVALID_INDEX;
private final Runnable mStartSpinnerRunnable;
private final Runnable mStopSpinnerRunnable;
@@ -308,7 +308,7 @@
ChildViewCache views = (ChildViewCache) view.getTag();
int flags = 0;
- if (mFlagsCol != -1) {
+ if (mFlagsCol != INVALID_INDEX) {
flags = cursor.getInt(mFlagsCol);
}
if (views.mText1 != null) {
@@ -391,7 +391,7 @@
}
private Drawable getIcon1(Cursor cursor) {
- if (mIconName1Col < 0) {
+ if (mIconName1Col == INVALID_INDEX) {
return null;
}
String value = cursor.getString(mIconName1Col);
@@ -403,7 +403,7 @@
}
private Drawable getIcon2(Cursor cursor) {
- if (mIconName2Col < 0) {
+ if (mIconName2Col == INVALID_INDEX) {
return null;
}
String value = cursor.getString(mIconName2Col);
@@ -687,7 +687,7 @@
}
private static String getStringOrNull(Cursor cursor, int col) {
- if (col == NONE) {
+ if (col == INVALID_INDEX) {
return null;
}
try {
diff --git a/core/java/android/widget/TextView.java b/core/java/android/widget/TextView.java
index 1895d79..fad0a4f 100644
--- a/core/java/android/widget/TextView.java
+++ b/core/java/android/widget/TextView.java
@@ -307,8 +307,8 @@
int mTextSelectHandleLeftRes;
int mTextSelectHandleRightRes;
int mTextSelectHandleRes;
- int mTextEditPasteWindowLayout;
- int mTextEditNoPasteWindowLayout;
+ int mTextEditPasteWindowLayout, mTextEditSidePasteWindowLayout;
+ int mTextEditNoPasteWindowLayout, mTextEditSideNoPasteWindowLayout;
Drawable mSelectHandleLeft;
Drawable mSelectHandleRight;
@@ -762,6 +762,14 @@
mTextEditNoPasteWindowLayout = a.getResourceId(attr, 0);
break;
+ case com.android.internal.R.styleable.TextView_textEditSidePasteWindowLayout:
+ mTextEditSidePasteWindowLayout = a.getResourceId(attr, 0);
+ break;
+
+ case com.android.internal.R.styleable.TextView_textEditSideNoPasteWindowLayout:
+ mTextEditSideNoPasteWindowLayout = a.getResourceId(attr, 0);
+ break;
+
case com.android.internal.R.styleable.TextView_textIsSelectable:
mTextIsSelectable = a.getBoolean(attr, false);
break;
@@ -3426,8 +3434,7 @@
setError(null, null);
} else {
Drawable dr = getContext().getResources().
- getDrawable(com.android.internal.R.drawable.
- indicator_input_error);
+ getDrawable(com.android.internal.R.drawable.indicator_input_error);
dr.setBounds(0, 0, dr.getIntrinsicWidth(), dr.getIntrinsicHeight());
setError(error, dr);
@@ -3450,8 +3457,7 @@
mErrorWasChanged = true;
final Drawables dr = mDrawables;
if (dr != null) {
- setCompoundDrawables(dr.mDrawableLeft, dr.mDrawableTop,
- icon, dr.mDrawableBottom);
+ setCompoundDrawables(dr.mDrawableLeft, dr.mDrawableTop, icon, dr.mDrawableBottom);
} else {
setCompoundDrawables(null, null, icon, null);
}
@@ -3479,8 +3485,8 @@
if (mPopup == null) {
LayoutInflater inflater = LayoutInflater.from(getContext());
- final TextView err = (TextView) inflater.inflate(com.android.internal.R.layout.textview_hint,
- null);
+ final TextView err = (TextView) inflater.inflate(
+ com.android.internal.R.layout.textview_hint, null);
final float scale = getResources().getDisplayMetrics().density;
mPopup = new ErrorPopup(err, (int) (200 * scale + 0.5f),
@@ -8424,8 +8430,11 @@
private final PopupWindow mContainer;
private int mPositionX;
private int mPositionY;
- private View mPasteView, mNoPasteView;
-
+ private final View[] mPasteViews = new View[4];
+ private final int[] mPasteViewLayouts = new int[] {
+ mTextEditPasteWindowLayout, mTextEditNoPasteWindowLayout,
+ mTextEditSidePasteWindowLayout, mTextEditSideNoPasteWindowLayout };
+
public PastePopupMenu() {
mContainer = new PopupWindow(TextView.this.mContext, null,
com.android.internal.R.attr.textSelectHandleWindowStyle);
@@ -8437,12 +8446,16 @@
mContainer.setHeight(ViewGroup.LayoutParams.WRAP_CONTENT);
}
- private void updateContent() {
- View view = canPaste() ? mPasteView : mNoPasteView;
+ private int viewIndex(boolean onTop) {
+ return (onTop ? 0 : 1<<1) + (canPaste() ? 0 : 1<<0);
+ }
+
+ private void updateContent(boolean onTop) {
+ final int viewIndex = viewIndex(onTop);
+ View view = mPasteViews[viewIndex];
if (view == null) {
- final int layout = canPaste() ? mTextEditPasteWindowLayout :
- mTextEditNoPasteWindowLayout;
+ final int layout = mPasteViewLayouts[viewIndex];
LayoutInflater inflater = (LayoutInflater)TextView.this.mContext.
getSystemService(Context.LAYOUT_INFLATER_SERVICE);
if (inflater != null) {
@@ -8459,26 +8472,16 @@
view.measure(size, size);
view.setOnClickListener(this);
-
- if (canPaste()) mPasteView = view;
- else mNoPasteView = view;
+
+ mPasteViews[viewIndex] = view;
}
mContainer.setContentView(view);
}
public void show() {
- updateContent();
- final int[] coords = mTempCoords;
- TextView.this.getLocationInWindow(coords);
+ updateContent(true);
positionAtCursor();
- coords[0] += mPositionX;
- coords[1] += mPositionY;
- coords[0] = Math.max(0, coords[0]);
- final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
- coords[0] = Math.min(screenWidth - mContainer.getContentView().getMeasuredWidth(),
- coords[0]);
- mContainer.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
}
public void hide() {
@@ -8498,15 +8501,16 @@
}
void positionAtCursor() {
- final int offset = TextView.this.getSelectionStart();
View contentView = mContainer.getContentView();
- final int width = contentView.getMeasuredWidth();
- final int height = contentView.getMeasuredHeight();
+ int width = contentView.getMeasuredWidth();
+ int height = contentView.getMeasuredHeight();
+ final int offset = TextView.this.getSelectionStart();
final int line = mLayout.getLineForOffset(offset);
final int lineTop = mLayout.getLineTop(line);
+ float primaryHorizontal = mLayout.getPrimaryHorizontal(offset);
final Rect bounds = sCursorControllerTempRect;
- bounds.left = (int) (mLayout.getPrimaryHorizontal(offset) - width / 2.0f);
+ bounds.left = (int) (primaryHorizontal - width / 2.0f);
bounds.top = lineTop - height;
bounds.right = bounds.left + width;
@@ -8516,6 +8520,44 @@
mPositionX = bounds.left;
mPositionY = bounds.top;
+
+
+ final int[] coords = mTempCoords;
+ TextView.this.getLocationInWindow(coords);
+ coords[0] += mPositionX;
+ coords[1] += mPositionY;
+
+ final int screenWidth = mContext.getResources().getDisplayMetrics().widthPixels;
+ if (coords[1] < 0) {
+ updateContent(false);
+ // Update dimensions from new view
+ contentView = mContainer.getContentView();
+ width = contentView.getMeasuredWidth();
+ height = contentView.getMeasuredHeight();
+
+ // Vertical clipping, move under edited line and to the side of insertion cursor
+ // TODO bottom clipping in case there is no system bar
+ coords[1] += height;
+ final int lineBottom = mLayout.getLineBottom(line);
+ final int lineHeight = lineBottom - lineTop;
+ coords[1] += lineHeight;
+
+ // Move to right hand side of insertion cursor by default. TODO RTL text.
+ final Drawable handle = mContext.getResources().getDrawable(mTextSelectHandleRes);
+ final int handleHalfWidth = handle.getIntrinsicWidth() / 2;
+
+ if (primaryHorizontal + handleHalfWidth + width < screenWidth) {
+ coords[0] += handleHalfWidth + width / 2;
+ } else {
+ coords[0] -= handleHalfWidth + width / 2;
+ }
+ } else {
+ // Horizontal clipping
+ coords[0] = Math.max(0, coords[0]);
+ coords[0] = Math.min(screenWidth - width, coords[0]);
+ }
+
+ mContainer.showAtLocation(TextView.this, Gravity.NO_GRAVITY, coords[0], coords[1]);
}
}
@@ -8917,11 +8959,11 @@
hideDelayed();
getHandle().show();
removePastePopupCallback();
- if (canPaste()) {
- final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
- if (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION) {
- delayBeforePaste = 0;
- }
+ final long durationSinceCutOrCopy = SystemClock.uptimeMillis() - sLastCutOrCopyTime;
+ if (durationSinceCutOrCopy < RECENT_CUT_COPY_DURATION) {
+ delayBeforePaste = 0;
+ }
+ if (delayBeforePaste == 0 || canPaste()) {
if (mPastePopupShower == null) {
mPastePopupShower = new Runnable() {
public void run() {
diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java
index 8f3442e..2688b95 100644
--- a/core/java/android/widget/TimePicker.java
+++ b/core/java/android/widget/TimePicker.java
@@ -20,61 +20,67 @@
import android.annotation.Widget;
import android.content.Context;
+import android.content.res.TypedArray;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
-import android.widget.NumberPicker.OnValueChangedListener;
+import android.widget.NumberPicker.OnValueChangeListener;
import java.text.DateFormatSymbols;
import java.util.Calendar;
/**
- * A view for selecting the time of day, in either 24 hour or AM/PM mode.
- *
- * The hour, each minute digit, and AM/PM (if applicable) can be conrolled by
- * vertical spinners.
- *
- * The hour can be entered by keyboard input. Entering in two digit hours
- * can be accomplished by hitting two digits within a timeout of about a
- * second (e.g. '1' then '2' to select 12).
- *
- * The minutes can be entered by entering single digits.
- *
- * Under AM/PM mode, the user can hit 'a', 'A", 'p' or 'P' to pick.
- *
- * For a dialog using this view, see {@link android.app.TimePickerDialog}.
- *
- * <p>See the <a href="{@docRoot}resources/tutorials/views/hello-timepicker.html">Time Picker
- * tutorial</a>.</p>
+ * A view for selecting the time of day, in either 24 hour or AM/PM mode. The
+ * hour, each minute digit, and AM/PM (if applicable) can be conrolled by
+ * vertical spinners. The hour can be entered by keyboard input. Entering in two
+ * digit hours can be accomplished by hitting two digits within a timeout of
+ * about a second (e.g. '1' then '2' to select 12). The minutes can be entered
+ * by entering single digits. Under AM/PM mode, the user can hit 'a', 'A", 'p'
+ * or 'P' to pick. For a dialog using this view, see
+ * {@link android.app.TimePickerDialog}.
+ *<p>
+ * See the <a href="{@docRoot}
+ * resources/tutorials/views/hello-timepicker.html">Time Picker tutorial</a>.
+ * </p>
*/
@Widget
public class TimePicker extends FrameLayout {
private static final boolean DEFAULT_ENABLED_STATE = true;
+ private static final int HOURS_IN_HALF_DAY = 12;
+
/**
- * A no-op callback used in the constructor to avoid null checks
- * later in the code.
+ * A no-op callback used in the constructor to avoid null checks later in
+ * the code.
*/
private static final OnTimeChangedListener NO_OP_CHANGE_LISTENER = new OnTimeChangedListener() {
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
}
};
-
+
// state
- private int mCurrentHour = 0; // 0-23
- private int mCurrentMinute = 0; // 0-59
- private Boolean mIs24HourView = false;
+ private boolean mIs24HourView;
+
private boolean mIsAm;
// ui components
private final NumberPicker mHourSpinner;
+
private final NumberPicker mMinuteSpinner;
+
private final NumberPicker mAmPmSpinner;
+
private final TextView mDivider;
+ // Note that the legacy implementation of the TimePicker is
+ // using a button for toggling between AM/PM while the new
+ // version uses a NumberPicker spinner. Therefore the code
+ // accommodates these two cases to be backwards compatible.
+ private final Button mAmPmButton;
+
private final String[] mAmPmStrings;
private boolean mIsEnabled = DEFAULT_ENABLED_STATE;
@@ -98,74 +104,77 @@
public TimePicker(Context context) {
this(context, null);
}
-
+
public TimePicker(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
+ this(context, attrs, R.attr.timePickerStyle);
}
public TimePicker(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
- LayoutInflater inflater =
- (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
- inflater.inflate(R.layout.time_picker,
- this, // we are the parent
- true);
+ // process style attributes
+ TypedArray attributesArray = context.obtainStyledAttributes(
+ attrs, R.styleable.TimePicker, defStyle, 0);
+ int layoutResourceId = attributesArray.getResourceId(
+ R.styleable.TimePicker_layout, R.layout.time_picker);
+ attributesArray.recycle();
+
+ LayoutInflater inflater = (LayoutInflater) context.getSystemService(
+ Context.LAYOUT_INFLATER_SERVICE);
+ inflater.inflate(layoutResourceId, this, true);
// hour
mHourSpinner = (NumberPicker) findViewById(R.id.hour);
- mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangedListener() {
+ mHourSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
- mCurrentHour = newVal;
- if (!mIs24HourView) {
- // adjust from [1-12] to [0-11] internally, with the times
- // written "12:xx" being the start of the half-day
- if (mCurrentHour == 12) {
- mCurrentHour = 0;
- }
- if (!mIsAm) {
- // PM means 12 hours later than nominal
- mCurrentHour += 12;
+ if (!is24HourView()) {
+ int minValue = mHourSpinner.getMinValue();
+ int maxValue = mHourSpinner.getMaxValue();
+ // toggle AM/PM if the spinner has wrapped and not in 24
+ // format
+ if ((oldVal == maxValue && newVal == minValue)
+ || (oldVal == minValue && newVal == maxValue)) {
+ mIsAm = !mIsAm;
+ updateAmPmControl();
}
}
onTimeChanged();
}
});
- // divider
+ // divider (only for the new widget style)
mDivider = (TextView) findViewById(R.id.divider);
- mDivider.setText(R.string.time_picker_separator);
+ if (mDivider != null) {
+ mDivider.setText(R.string.time_picker_separator);
+ }
- // digits of minute
+ // minute
mMinuteSpinner = (NumberPicker) findViewById(R.id.minute);
mMinuteSpinner.setMinValue(0);
mMinuteSpinner.setMaxValue(59);
mMinuteSpinner.setOnLongPressUpdateInterval(100);
mMinuteSpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
- mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangedListener() {
+ mMinuteSpinner.setOnValueChangedListener(new NumberPicker.OnValueChangeListener() {
public void onValueChange(NumberPicker spinner, int oldVal, int newVal) {
- mCurrentMinute = newVal;
- onTimeChanged();
- }
- });
-
- // am/pm
- mAmPmSpinner = (NumberPicker) findViewById(R.id.amPm);
- mAmPmSpinner.setOnValueChangedListener(new OnValueChangedListener() {
- public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
- picker.requestFocus();
- if (mIsAm) {
- // Currently AM switching to PM
- if (mCurrentHour < 12) {
- mCurrentHour += 12;
+ int minValue = mMinuteSpinner.getMinValue();
+ int maxValue = mMinuteSpinner.getMaxValue();
+ if (oldVal == maxValue && newVal == minValue) {
+ int currentHour = mHourSpinner.getValue();
+ // toggle AM/PM if the spinner is about to wrap
+ if (!is24HourView() && currentHour == mHourSpinner.getMaxValue()) {
+ mIsAm = !mIsAm;
+ updateAmPmControl();
}
- } else {
- // Currently PM switching to AM
- if (mCurrentHour >= 12) {
- mCurrentHour -= 12;
+ mHourSpinner.setValue(currentHour + 1);
+ } else if (oldVal == minValue && newVal == maxValue) {
+ int currentHour = mHourSpinner.getValue();
+ // toggle AM/PM if the spinner is about to wrap
+ if (!is24HourView() && currentHour == mHourSpinner.getMinValue()) {
+ mIsAm = !mIsAm;
+ updateAmPmControl();
}
+ mHourSpinner.setValue(currentHour - 1);
}
- mIsAm = !mIsAm;
onTimeChanged();
}
});
@@ -173,17 +182,44 @@
/* Get the localized am/pm strings and use them in the spinner */
mAmPmStrings = new DateFormatSymbols().getAmPmStrings();
- // now that the hour/minute picker objects have been initialized, set
- // the hour range properly based on the 12/24 hour display mode.
- configurePickerRanges();
+ // am/pm
+ View amPmView = findViewById(R.id.amPm);
+ if (amPmView instanceof Button) {
+ mAmPmSpinner = null;
+ mAmPmButton = (Button) amPmView;
+ mAmPmButton.setOnClickListener(new OnClickListener() {
+ public void onClick(View button) {
+ button.requestFocus();
+ mIsAm = !mIsAm;
+ updateAmPmControl();
+ }
+ });
+ } else {
+ mAmPmButton = null;
+ mAmPmSpinner = (NumberPicker) amPmView;
+ mAmPmSpinner.setMinValue(0);
+ mAmPmSpinner.setMaxValue(1);
+ mAmPmSpinner.setDisplayedValues(mAmPmStrings);
+ mAmPmSpinner.setOnValueChangedListener(new OnValueChangeListener() {
+ public void onValueChange(NumberPicker picker, int oldVal, int newVal) {
+ picker.requestFocus();
+ mIsAm = !mIsAm;
+ updateAmPmControl();
+ }
+ });
+ }
+
+ // update controls to initial state
+ updateHourControl();
+ updateAmPmControl();
// initialize to current time
- Calendar cal = Calendar.getInstance();
+ Calendar calendar = Calendar.getInstance();
setOnTimeChangedListener(NO_OP_CHANGE_LISTENER);
- // by default we're not in 24 hour mode
- setCurrentHour(cal.get(Calendar.HOUR_OF_DAY));
- setCurrentMinute(cal.get(Calendar.MINUTE));
+ // set to current time
+ setCurrentHour(calendar.get(Calendar.HOUR_OF_DAY));
+ setCurrentMinute(calendar.get(Calendar.MINUTE));
if (!isEnabled()) {
setEnabled(false);
@@ -197,9 +233,15 @@
}
super.setEnabled(enabled);
mMinuteSpinner.setEnabled(enabled);
- mDivider.setEnabled(enabled);
+ if (mDivider != null) {
+ mDivider.setEnabled(enabled);
+ }
mHourSpinner.setEnabled(enabled);
- mAmPmSpinner.setEnabled(enabled);
+ if (mAmPmSpinner != null) {
+ mAmPmSpinner.setEnabled(enabled);
+ } else {
+ mAmPmButton.setEnabled(enabled);
+ }
mIsEnabled = enabled;
}
@@ -214,6 +256,7 @@
private static class SavedState extends BaseSavedState {
private final int mHour;
+
private final int mMinute;
private SavedState(Parcelable superState, int hour, int minute) {
@@ -221,7 +264,7 @@
mHour = hour;
mMinute = minute;
}
-
+
private SavedState(Parcel in) {
super(in);
mHour = in.readInt();
@@ -244,8 +287,7 @@
}
@SuppressWarnings("unused")
- public static final Parcelable.Creator<SavedState> CREATOR
- = new Creator<SavedState>() {
+ public static final Parcelable.Creator<SavedState> CREATOR = new Creator<SavedState>() {
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@@ -259,7 +301,7 @@
@Override
protected Parcelable onSaveInstanceState() {
Parcelable superState = super.onSaveInstanceState();
- return new SavedState(superState, mCurrentHour, mCurrentMinute);
+ return new SavedState(superState, getCurrentHour(), getCurrentMinute());
}
@Override
@@ -272,6 +314,7 @@
/**
* Set the callback that indicates the time has been adjusted by the user.
+ *
* @param onTimeChangedListener the callback, should not be null.
*/
public void setOnTimeChangedListener(OnTimeChangedListener onTimeChangedListener) {
@@ -279,30 +322,58 @@
}
/**
- * @return The current hour (0-23).
+ * @return The current hour in the range (0-23).
*/
public Integer getCurrentHour() {
- return mCurrentHour;
+ int currentHour = mHourSpinner.getValue();
+ if (is24HourView() || mIsAm) {
+ return currentHour;
+ } else {
+ return (currentHour == HOURS_IN_HALF_DAY) ? 0 : currentHour + HOURS_IN_HALF_DAY;
+ }
}
/**
* Set the current hour.
*/
public void setCurrentHour(Integer currentHour) {
- this.mCurrentHour = currentHour;
- updateHourDisplay();
+ // why was Integer used in the first place?
+ if (currentHour == null || currentHour == getCurrentHour()) {
+ return;
+ }
+ if (!is24HourView()) {
+ // convert [0,23] ordinal to wall clock display
+ if (currentHour > HOURS_IN_HALF_DAY) {
+ currentHour -= HOURS_IN_HALF_DAY;
+ mIsAm = false;
+ } else {
+ if (currentHour == 0) {
+ currentHour = HOURS_IN_HALF_DAY;
+ }
+ mIsAm = true;
+ }
+ updateAmPmControl();
+ }
+ mHourSpinner.setValue(currentHour);
+ onTimeChanged();
}
/**
* Set whether in 24 hour or AM/PM mode.
+ *
* @param is24HourView True = 24 hour mode. False = AM/PM.
*/
public void setIs24HourView(Boolean is24HourView) {
- if (mIs24HourView != is24HourView) {
- mIs24HourView = is24HourView;
- configurePickerRanges();
- updateHourDisplay();
+ if (mIs24HourView == is24HourView) {
+ return;
}
+ mIs24HourView = is24HourView;
+ // cache the current hour since spinner range changes
+ int currentHour = getCurrentHour();
+ updateHourControl();
+ // set value after spinner range is updated
+ setCurrentHour(currentHour);
+ updateAmPmControl();
}
/**
@@ -311,20 +382,23 @@
public boolean is24HourView() {
return mIs24HourView;
}
-
+
/**
* @return The current minute.
*/
public Integer getCurrentMinute() {
- return mCurrentMinute;
+ return mMinuteSpinner.getValue();
}
/**
* Set the current minute (0-59).
*/
public void setCurrentMinute(Integer currentMinute) {
- this.mCurrentMinute = currentMinute;
- updateMinuteDisplay();
+ if (currentMinute == getCurrentMinute()) {
+ return;
+ }
+ mMinuteSpinner.setValue(currentMinute);
+ onTimeChanged();
}
@Override
@@ -332,39 +406,34 @@
return mHourSpinner.getBaseline();
}
- /**
- * Set the state of the spinners appropriate to the current hour.
- */
- private void updateHourDisplay() {
- int currentHour = mCurrentHour;
- if (!mIs24HourView) {
- // convert [0,23] ordinal to wall clock display
- if (currentHour > 12) {
- currentHour -= 12;
- } else if (currentHour == 0) {
- currentHour = 12;
- }
- }
- mHourSpinner.setValue(currentHour);
- mIsAm = mCurrentHour < 12;
- mAmPmSpinner.setValue(mIsAm ? Calendar.AM : Calendar.PM);
- onTimeChanged();
- }
-
- private void configurePickerRanges() {
- if (mIs24HourView) {
+ private void updateHourControl() {
+ if (is24HourView()) {
mHourSpinner.setMinValue(0);
mHourSpinner.setMaxValue(23);
mHourSpinner.setFormatter(NumberPicker.TWO_DIGIT_FORMATTER);
- mAmPmSpinner.setVisibility(View.GONE);
} else {
mHourSpinner.setMinValue(1);
mHourSpinner.setMaxValue(12);
mHourSpinner.setFormatter(null);
- mAmPmSpinner.setVisibility(View.VISIBLE);
- mAmPmSpinner.setMinValue(0);
- mAmPmSpinner.setMaxValue(1);
- mAmPmSpinner.setDisplayedValues(mAmPmStrings);
+ }
+ }
+
+ private void updateAmPmControl() {
+ if (is24HourView()) {
+ if (mAmPmSpinner != null) {
+ mAmPmSpinner.setVisibility(View.GONE);
+ } else {
+ mAmPmButton.setVisibility(View.GONE);
+ }
+ } else {
+ int index = mIsAm ? Calendar.AM : Calendar.PM;
+ if (mAmPmSpinner != null) {
+ mAmPmSpinner.setValue(index);
+ mAmPmSpinner.setVisibility(View.VISIBLE);
+ } else {
+ mAmPmButton.setText(mAmPmStrings[index]);
+ mAmPmButton.setVisibility(View.VISIBLE);
+ }
}
}
@@ -373,12 +442,4 @@
mOnTimeChangedListener.onTimeChanged(this, getCurrentHour(), getCurrentMinute());
}
}
-
- /**
- * Set the state of the spinners appropriate to the current minute.
- */
- private void updateMinuteDisplay() {
- mMinuteSpinner.setValue(mCurrentMinute);
- onTimeChanged();
- }
}
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index 29ca49a..bb23173 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -67,15 +67,9 @@
*/
public static final int LENGTH_LONG = 1;
- final Handler mHandler = new Handler();
final Context mContext;
final TN mTN;
int mDuration;
- int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
- int mX, mY;
- float mHorizontalMargin;
- float mVerticalMargin;
- View mView;
View mNextView;
/**
@@ -88,7 +82,7 @@
public Toast(Context context) {
mContext = context;
mTN = new TN();
- mY = context.getResources().getDimensionPixelSize(
+ mTN.mY = context.getResources().getDimensionPixelSize(
com.android.internal.R.dimen.toast_y_offset);
}
@@ -101,10 +95,9 @@
}
INotificationManager service = getService();
-
String pkg = mContext.getPackageName();
-
TN tn = mTN;
+ tn.mNextView = mNextView;
try {
service.enqueueToast(pkg, tn, mDuration);
@@ -167,22 +160,22 @@
* notification
*/
public void setMargin(float horizontalMargin, float verticalMargin) {
- mHorizontalMargin = horizontalMargin;
- mVerticalMargin = verticalMargin;
+ mTN.mHorizontalMargin = horizontalMargin;
+ mTN.mVerticalMargin = verticalMargin;
}
/**
* Return the horizontal margin.
*/
public float getHorizontalMargin() {
- return mHorizontalMargin;
+ return mTN.mHorizontalMargin;
}
/**
* Return the vertical margin.
*/
public float getVerticalMargin() {
- return mVerticalMargin;
+ return mTN.mVerticalMargin;
}
/**
@@ -191,9 +184,9 @@
* @see #getGravity
*/
public void setGravity(int gravity, int xOffset, int yOffset) {
- mGravity = gravity;
- mX = xOffset;
- mY = yOffset;
+ mTN.mGravity = gravity;
+ mTN.mX = xOffset;
+ mTN.mY = yOffset;
}
/**
@@ -202,21 +195,21 @@
* @see #getGravity
*/
public int getGravity() {
- return mGravity;
+ return mTN.mGravity;
}
/**
* Return the X offset in pixels to apply to the gravity's location.
*/
public int getXOffset() {
- return mX;
+ return mTN.mX;
}
/**
* Return the Y offset in pixels to apply to the gravity's location.
*/
public int getYOffset() {
- return mY;
+ return mTN.mY;
}
/**
@@ -283,21 +276,6 @@
tv.setText(s);
}
- private void trySendAccessibilityEvent() {
- AccessibilityManager accessibilityManager = AccessibilityManager.getInstance(mContext);
- if (!accessibilityManager.isEnabled()) {
- return;
- }
- // treat toasts as notifications since they are used to
- // announce a transient piece of information to the user
- AccessibilityEvent event = AccessibilityEvent.obtain(
- AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
- event.setClassName(getClass().getName());
- event.setPackageName(mContext.getPackageName());
- mView.dispatchPopulateAccessibilityEvent(event);
- accessibilityManager.sendAccessibilityEvent(event);
- }
-
// =======================================================================================
// All the gunk below is the interaction with the Notification Service, which handles
// the proper ordering of these system-wide.
@@ -313,7 +291,7 @@
return sService;
}
- private class TN extends ITransientNotification.Stub {
+ private static class TN extends ITransientNotification.Stub {
final Runnable mShow = new Runnable() {
public void run() {
handleShow();
@@ -323,10 +301,22 @@
final Runnable mHide = new Runnable() {
public void run() {
handleHide();
+ // Don't do this in handleHide() because it is also invoked by handleShow()
+ mNextView = null;
}
};
private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams();
+ final Handler mHandler = new Handler();
+
+ int mGravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
+ int mX, mY;
+ float mHorizontalMargin;
+ float mVerticalMargin;
+
+
+ View mView;
+ View mNextView;
WindowManagerImpl mWM;
@@ -382,8 +372,7 @@
mParams.verticalMargin = mVerticalMargin;
mParams.horizontalMargin = mHorizontalMargin;
if (mView.getParent() != null) {
- if (localLOGV) Log.v(
- TAG, "REMOVE! " + mView + " in " + this);
+ if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
mWM.removeView(mView);
}
if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this);
@@ -392,6 +381,22 @@
}
}
+ private void trySendAccessibilityEvent() {
+ AccessibilityManager accessibilityManager =
+ AccessibilityManager.getInstance(mView.getContext());
+ if (!accessibilityManager.isEnabled()) {
+ return;
+ }
+ // treat toasts as notifications since they are used to
+ // announce a transient piece of information to the user
+ AccessibilityEvent event = AccessibilityEvent.obtain(
+ AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED);
+ event.setClassName(getClass().getName());
+ event.setPackageName(mView.getContext().getPackageName());
+ mView.dispatchPopulateAccessibilityEvent(event);
+ accessibilityManager.sendAccessibilityEvent(event);
+ }
+
public void handleHide() {
if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView);
if (mView != null) {
@@ -399,8 +404,7 @@
// been added... i have seen cases where we get here when
// the view isn't yet added, so let's try not to crash.
if (mView.getParent() != null) {
- if (localLOGV) Log.v(
- TAG, "REMOVE! " + mView + " in " + this);
+ if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this);
mWM.removeView(mView);
}
diff --git a/core/java/com/android/internal/app/ActionBarImpl.java b/core/java/com/android/internal/app/ActionBarImpl.java
index a8eb6fe..b1b5d71 100644
--- a/core/java/com/android/internal/app/ActionBarImpl.java
+++ b/core/java/com/android/internal/app/ActionBarImpl.java
@@ -277,36 +277,6 @@
setSubtitle(mContext.getString(resId));
}
- public void setCustomNavigationMode(View view) {
- cleanupTabs();
- setCustomView(view);
- setDisplayOptions(DISPLAY_SHOW_CUSTOM, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE);
- mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
- mActionView.setCallback(null);
- }
-
- public void setDropdownNavigationMode(SpinnerAdapter adapter, OnNavigationListener callback) {
- setDropdownNavigationMode(adapter, callback, -1);
- }
-
- public void setDropdownNavigationMode(SpinnerAdapter adapter, OnNavigationListener callback,
- int defaultSelectedPosition) {
- cleanupTabs();
- setDisplayOptions(0, DISPLAY_SHOW_CUSTOM | DISPLAY_SHOW_TITLE);
- mActionView.setNavigationMode(NAVIGATION_MODE_LIST);
- setListNavigationCallbacks(adapter, callback);
- if (defaultSelectedPosition >= 0) {
- mActionView.setDropdownSelectedPosition(defaultSelectedPosition);
- }
- }
-
- public void setStandardNavigationMode() {
- cleanupTabs();
- setDisplayOptions(DISPLAY_SHOW_TITLE, DISPLAY_SHOW_TITLE | DISPLAY_SHOW_CUSTOM);
- mActionView.setNavigationMode(NAVIGATION_MODE_STANDARD);
- mActionView.setCallback(null);
- }
-
public void setSelectedNavigationItem(int position) {
switch (mActionView.getNavigationMode()) {
case NAVIGATION_MODE_TABS:
@@ -321,10 +291,6 @@
}
}
- public int getSelectedNavigationItem() {
- return getSelectedNavigationIndex();
- }
-
public void removeAllTabs() {
cleanupTabs();
}
@@ -359,10 +325,6 @@
mContainerView.setBackgroundDrawable(d);
}
- public View getCustomNavigationView() {
- return getCustomView();
- }
-
public View getCustomView() {
return mActionView.getCustomNavigationView();
}
@@ -477,16 +439,6 @@
}
@Override
- public void setTabNavigationMode() {
- if (mActivity == null) {
- throw new IllegalStateException(
- "Tab navigation mode cannot be used outside of an Activity");
- }
- setDisplayOptions(0, DISPLAY_SHOW_TITLE | DISPLAY_SHOW_CUSTOM);
- mActionView.setNavigationMode(NAVIGATION_MODE_TABS);
- }
-
- @Override
public void selectTab(Tab tab) {
if (getNavigationMode() != NAVIGATION_MODE_TABS) {
mSavedTabPosition = tab != null ? tab.getPosition() : INVALID_POSITION;
diff --git a/core/java/com/android/internal/app/PlatLogoActivity.java b/core/java/com/android/internal/app/PlatLogoActivity.java
index e1c5564..9fbbb3d 100644
--- a/core/java/com/android/internal/app/PlatLogoActivity.java
+++ b/core/java/com/android/internal/app/PlatLogoActivity.java
@@ -29,11 +29,11 @@
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- mToast = Toast.makeText(this, "Zombie art by Jack Larson", Toast.LENGTH_SHORT);
+ mToast = Toast.makeText(this, "REZZZZZZZ...", Toast.LENGTH_SHORT);
ImageView content = new ImageView(this);
content.setImageResource(com.android.internal.R.drawable.platlogo);
- content.setScaleType(ImageView.ScaleType.FIT_CENTER);
+ content.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
setContentView(content);
}
diff --git a/core/java/com/android/internal/widget/ActionBarView.java b/core/java/com/android/internal/widget/ActionBarView.java
index 297dde7..d44d4a5 100644
--- a/core/java/com/android/internal/widget/ActionBarView.java
+++ b/core/java/com/android/internal/widget/ActionBarView.java
@@ -370,12 +370,6 @@
}
public void setDisplayOptions(int options) {
- // TODO Remove this once DISPLAY_HIDE_HOME is removed
- if ((options & ActionBar.DISPLAY_HIDE_HOME) != 0) {
- options &= ~(ActionBar.DISPLAY_HIDE_HOME | ActionBar.DISPLAY_SHOW_HOME);
- }
- // End TODO
-
final int flagsChanged = options ^ mDisplayOptions;
mDisplayOptions = options;
if ((flagsChanged & DISPLAY_RELAYOUT_MASK) != 0) {
diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java
index 6a1beb4..e992e7c 100644
--- a/core/java/com/android/internal/widget/EditableInputConnection.java
+++ b/core/java/com/android/internal/widget/EditableInputConnection.java
@@ -142,10 +142,6 @@
boolean success = super.commitText(text, newCursorPosition);
CharSequence errorAfter = mTextView.getError();
- if (errorAfter != null && errorBefore == errorAfter) {
- mTextView.setError(null, null);
- }
-
return success;
}
}
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
index facda36..3c01c69 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboard.java
@@ -20,16 +20,9 @@
import android.content.Context;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
-import android.graphics.Bitmap;
-import android.graphics.Canvas;
-import android.graphics.Paint;
-import android.graphics.PorterDuff;
-import android.graphics.Paint.Align;
-import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.inputmethodservice.Keyboard;
import android.inputmethodservice.KeyboardView;
-import android.util.Log;
import com.android.internal.R;
/**
@@ -40,7 +33,6 @@
* keypad with alpha characters hints.
*/
public class PasswordEntryKeyboard extends Keyboard {
- private static final String TAG = "PasswordEntryKeyboard";
private static final int SHIFT_OFF = 0;
private static final int SHIFT_ON = 1;
private static final int SHIFT_LOCKED = 2;
@@ -48,17 +40,14 @@
private Drawable mShiftIcon;
private Drawable mShiftLockIcon;
- private Drawable mShiftLockPreviewIcon;
- private Drawable mOldShiftIcon;
- private Drawable mOldShiftPreviewIcon;
- private Drawable mSpaceIcon;
- private Key mShiftKey;
+
+ // These two arrays must be the same length
+ private Drawable[] mOldShiftIcons = { null, null };
+ private Key[] mShiftKeys = { null, null };
+
private Key mEnterKey;
private Key mF1Key;
private Key mSpaceKey;
- private Locale mLocale;
- private Resources mRes;
- private int mExtensionResId;
private int mShiftState = SHIFT_OFF;
static int sSpacebarVerticalCorrection;
@@ -84,14 +73,8 @@
private void init(Context context) {
final Resources res = context.getResources();
- mRes = res;
mShiftIcon = res.getDrawable(R.drawable.sym_keyboard_shift);
mShiftLockIcon = res.getDrawable(R.drawable.sym_keyboard_shift_locked);
- mShiftLockPreviewIcon = res.getDrawable(R.drawable.sym_keyboard_feedback_shift_locked);
- mShiftLockPreviewIcon.setBounds(0, 0,
- mShiftLockPreviewIcon.getIntrinsicWidth(),
- mShiftLockPreviewIcon.getIntrinsicHeight());
- mSpaceIcon = res.getDrawable(R.drawable.sym_keyboard_space);
sSpacebarVerticalCorrection = res.getDimensionPixelOffset(
R.dimen.password_keyboard_spacebar_vertical_correction);
}
@@ -157,14 +140,16 @@
*
*/
void enableShiftLock() {
- int index = getShiftKeyIndex();
- if (index >= 0) {
- mShiftKey = getKeys().get(index);
- if (mShiftKey instanceof LatinKey) {
- ((LatinKey)mShiftKey).enableShiftLock();
+ int i = 0;
+ for (int index : getShiftKeyIndices()) {
+ if (index >= 0 && i < mShiftKeys.length) {
+ mShiftKeys[i] = getKeys().get(index);
+ if (mShiftKeys[i] instanceof LatinKey) {
+ ((LatinKey)mShiftKeys[i]).enableShiftLock();
+ }
+ mOldShiftIcons[i] = mShiftKeys[i].icon;
+ i++;
}
- mOldShiftIcon = mShiftKey.icon;
- mOldShiftPreviewIcon = mShiftKey.iconPreview;
}
}
@@ -176,17 +161,13 @@
* @param shiftLocked
*/
void setShiftLocked(boolean shiftLocked) {
- if (mShiftKey != null) {
- if (shiftLocked) {
- mShiftKey.on = true;
- mShiftKey.icon = mShiftLockIcon;
- mShiftState = SHIFT_LOCKED;
- } else {
- mShiftKey.on = false;
- mShiftKey.icon = mShiftLockIcon;
- mShiftState = SHIFT_ON;
+ for (Key shiftKey : mShiftKeys) {
+ if (shiftKey != null) {
+ shiftKey.on = shiftLocked;
+ shiftKey.icon = mShiftLockIcon;
}
}
+ mShiftState = shiftLocked ? SHIFT_LOCKED : SHIFT_ON;
}
/**
@@ -199,20 +180,25 @@
@Override
public boolean setShifted(boolean shiftState) {
boolean shiftChanged = false;
- if (mShiftKey != null) {
- if (shiftState == false) {
- shiftChanged = mShiftState != SHIFT_OFF;
- mShiftState = SHIFT_OFF;
- mShiftKey.on = false;
- mShiftKey.icon = mOldShiftIcon;
- } else if (mShiftState == SHIFT_OFF) {
- shiftChanged = mShiftState == SHIFT_OFF;
- mShiftState = SHIFT_ON;
- mShiftKey.on = false;
- mShiftKey.icon = mShiftIcon;
+ if (shiftState == false) {
+ shiftChanged = mShiftState != SHIFT_OFF;
+ mShiftState = SHIFT_OFF;
+ } else if (mShiftState == SHIFT_OFF) {
+ shiftChanged = mShiftState == SHIFT_OFF;
+ mShiftState = SHIFT_ON;
+ }
+ for (int i = 0; i < mShiftKeys.length; i++) {
+ if (mShiftKeys[i] != null) {
+ if (shiftState == false) {
+ mShiftKeys[i].on = false;
+ mShiftKeys[i].icon = mOldShiftIcons[i];
+ } else if (mShiftState == SHIFT_OFF) {
+ mShiftKeys[i].on = false;
+ mShiftKeys[i].icon = mShiftIcon;
+ }
+ } else {
+ // return super.setShifted(shiftState);
}
- } else {
- return super.setShifted(shiftState);
}
return shiftChanged;
}
@@ -223,7 +209,7 @@
*/
@Override
public boolean isShifted() {
- if (mShiftKey != null) {
+ if (mShiftKeys[0] != null) {
return mShiftState != SHIFT_OFF;
} else {
return super.isShifted();
diff --git a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
index 3e6f6f3..b37adff 100644
--- a/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
+++ b/core/java/com/android/internal/widget/PasswordEntryKeyboardView.java
@@ -36,4 +36,15 @@
super(context, attrs, defStyle);
}
+ @Override
+ public boolean setShifted(boolean shifted) {
+ boolean result = super.setShifted(shifted);
+ // invalidate both shift keys
+ int[] indices = getKeyboard().getShiftKeyIndices();
+ for (int index : indices) {
+ invalidateKey(index);
+ }
+ return result;
+ }
+
}
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index f023e94..342b884 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -568,6 +568,7 @@
char jniOptsBuf[sizeof("-Xjniopts:")-1 + PROPERTY_VALUE_MAX];
char heapstartsizeOptsBuf[sizeof("-Xms")-1 + PROPERTY_VALUE_MAX];
char heapsizeOptsBuf[sizeof("-Xmx")-1 + PROPERTY_VALUE_MAX];
+ char heapgrowthlimitOptsBuf[sizeof("-XX:HeapGrowthLimit=")-1 + PROPERTY_VALUE_MAX];
char extraOptsBuf[PROPERTY_VALUE_MAX];
char* stackTraceFile = NULL;
bool checkJni = false;
@@ -659,6 +660,13 @@
opt.optionString = heapsizeOptsBuf;
mOptions.add(opt);
+ strcpy(heapgrowthlimitOptsBuf, "-XX:HeapGrowthLimit=");
+ property_get("dalvik.vm.heapgrowthlimit", heapgrowthlimitOptsBuf+20, "");
+ if (heapgrowthlimitOptsBuf[20] != '\0') {
+ opt.optionString = heapgrowthlimitOptsBuf;
+ mOptions.add(opt);
+ }
+
/*
* Enable or disable dexopt features, such as bytecode verification and
* calculation of register maps for precise GC.
diff --git a/core/jni/android/graphics/Region.cpp b/core/jni/android/graphics/Region.cpp
index c43b5ce..2445229 100644
--- a/core/jni/android/graphics/Region.cpp
+++ b/core/jni/android/graphics/Region.cpp
@@ -154,6 +154,16 @@
scale_rgn(rgn, *rgn, scale);
}
+static jstring Region_toString(JNIEnv* env, jobject clazz, SkRegion* region) {
+ char* str = region->toString();
+ if (str == NULL) {
+ return NULL;
+ }
+ jstring result = env->NewStringUTF(str);
+ free(str);
+ return result;
+}
+
////////////////////////////////////////////////////////////////////////////////////////////////////////////
static SkRegion* Region_createFromParcel(JNIEnv* env, jobject clazz, jobject parcel)
@@ -262,6 +272,7 @@
{ "quickReject", "(Landroid/graphics/Region;)Z", (void*)Region_quickRejectRgn },
{ "scale", "(FLandroid/graphics/Region;)V", (void*)Region_scale },
{ "translate", "(IILandroid/graphics/Region;)V", (void*)Region_translate },
+ { "nativeToString", "(I)Ljava/lang/String;", (void*)Region_toString },
// parceling methods
{ "nativeCreateFromParcel", "(Landroid/os/Parcel;)I", (void*)Region_createFromParcel },
{ "nativeWriteToParcel", "(ILandroid/os/Parcel;)Z", (void*)Region_writeToParcel },
diff --git a/core/jni/android_bluetooth_common.h b/core/jni/android_bluetooth_common.h
index 9222e1a..3364703 100644
--- a/core/jni/android_bluetooth_common.h
+++ b/core/jni/android_bluetooth_common.h
@@ -38,6 +38,7 @@
#ifdef HAVE_BLUETOOTH
#define BLUEZ_DBUS_BASE_PATH "/org/bluez"
#define BLUEZ_DBUS_BASE_IFC "org.bluez"
+#define BLUEZ_ERROR_IFC "org.bluez.Error"
// It would be nicer to retrieve this from bluez using GetDefaultAdapter,
// but this is only possible when the adapter is up (and hcid is running).
@@ -171,6 +172,30 @@
bool debug_no_encrypt();
+
+// Result codes from Bluez DBus calls
+#define BOND_RESULT_ERROR -1
+#define BOND_RESULT_SUCCESS 0
+#define BOND_RESULT_AUTH_FAILED 1
+#define BOND_RESULT_AUTH_REJECTED 2
+#define BOND_RESULT_AUTH_CANCELED 3
+#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
+#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
+#define BOND_RESULT_AUTH_TIMEOUT 6
+#define BOND_RESULT_REPEATED_ATTEMPTS 7
+
+#define PAN_DISCONNECT_FAILED_NOT_CONNECTED 1000
+#define PAN_CONNECT_FAILED_ALREADY_CONNECTED 1001
+#define PAN_CONNECT_FAILED_ATTEMPT_FAILED 1002
+#define PAN_OPERATION_GENERIC_FAILURE 1003
+#define PAN_OPERATION_SUCCESS 1004
+
+#define INPUT_DISCONNECT_FAILED_NOT_CONNECTED 5000
+#define INPUT_CONNECT_FAILED_ALREADY_CONNECTED 5001
+#define INPUT_CONNECT_FAILED_ATTEMPT_FAILED 5002
+#define INPUT_OPERATION_GENERIC_FAILURE 5003
+#define INPUT_OPERATION_SUCCESS 5004
+
#endif
} /* namespace android */
diff --git a/core/jni/android_server_BluetoothEventLoop.cpp b/core/jni/android_server_BluetoothEventLoop.cpp
index b0ba695..fd12c2d7 100644
--- a/core/jni/android_server_BluetoothEventLoop.cpp
+++ b/core/jni/android_server_BluetoothEventLoop.cpp
@@ -134,11 +134,11 @@
method_onInputDevicePropertyChanged = env->GetMethodID(clazz, "onInputDevicePropertyChanged",
"(Ljava/lang/String;[Ljava/lang/String;)V");
method_onInputDeviceConnectionResult = env->GetMethodID(clazz, "onInputDeviceConnectionResult",
- "(Ljava/lang/String;Z)V");
+ "(Ljava/lang/String;I)V");
method_onPanDevicePropertyChanged = env->GetMethodID(clazz, "onPanDevicePropertyChanged",
"(Ljava/lang/String;[Ljava/lang/String;)V");
method_onPanDeviceConnectionResult = env->GetMethodID(clazz, "onPanDeviceConnectionResult",
- "(Ljava/lang/String;Z)V");
+ "(Ljava/lang/String;I)V");
method_onRequestOobData = env->GetMethodID(clazz, "onRequestOobData",
"(Ljava/lang/String;I)V");
@@ -1227,16 +1227,6 @@
#ifdef HAVE_BLUETOOTH
-//TODO: Unify result codes in a header
-#define BOND_RESULT_ERROR -1000
-#define BOND_RESULT_SUCCESS 0
-#define BOND_RESULT_AUTH_FAILED 1
-#define BOND_RESULT_AUTH_REJECTED 2
-#define BOND_RESULT_AUTH_CANCELED 3
-#define BOND_RESULT_REMOTE_DEVICE_DOWN 4
-#define BOND_RESULT_DISCOVERY_IN_PROGRESS 5
-#define BOND_RESULT_AUTH_TIMEOUT 6
-#define BOND_RESULT_REPEATED_ATTEMPTS 7
void onCreatePairedDeviceResult(DBusMessage *msg, void *user, void *n) {
LOGV(__FUNCTION__);
@@ -1406,11 +1396,25 @@
JNIEnv *env;
nat->vm->GetEnv((void**)&env, nat->envVer);
- bool result = JNI_TRUE;
+ jint result = INPUT_OPERATION_SUCCESS;
if (dbus_set_error_from_message(&err, msg)) {
+ if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
+ result = INPUT_CONNECT_FAILED_ATTEMPT_FAILED;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".AlreadyConnected")) {
+ result = INPUT_CONNECT_FAILED_ALREADY_CONNECTED;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
+ // TODO():This is flaky, need to change Bluez to add new error codes
+ if (!strcmp(err.message, "Transport endpoint is not connected")) {
+ result = INPUT_DISCONNECT_FAILED_NOT_CONNECTED;
+ } else {
+ result = INPUT_OPERATION_GENERIC_FAILURE;
+ }
+ } else {
+ result = INPUT_OPERATION_GENERIC_FAILURE;
+ }
LOG_AND_FREE_DBUS_ERROR(&err);
- result = JNI_FALSE;
}
+
LOGV("... Device Path = %s, result = %d", path, result);
jstring jPath = env->NewStringUTF(path);
env->CallVoidMethod(nat->me,
@@ -1431,11 +1435,25 @@
JNIEnv *env;
nat->vm->GetEnv((void**)&env, nat->envVer);
- bool result = JNI_TRUE;
+ jint result = PAN_OPERATION_SUCCESS;
if (dbus_set_error_from_message(&err, msg)) {
+ if (!strcmp(err.name, BLUEZ_ERROR_IFC ".ConnectionAttemptFailed")) {
+ result = PAN_CONNECT_FAILED_ATTEMPT_FAILED;
+ } else if (!strcmp(err.name, BLUEZ_ERROR_IFC ".Failed")) {
+ // TODO():This is flaky, need to change Bluez to add new error codes
+ if (!strcmp(err.message, "Device already connected")) {
+ result = PAN_CONNECT_FAILED_ALREADY_CONNECTED;
+ } else if (!strcmp(err.message, "Device not connected")) {
+ result = PAN_DISCONNECT_FAILED_NOT_CONNECTED;
+ } else {
+ result = PAN_OPERATION_GENERIC_FAILURE;
+ }
+ } else {
+ result = PAN_OPERATION_GENERIC_FAILURE;
+ }
LOG_AND_FREE_DBUS_ERROR(&err);
- result = JNI_FALSE;
}
+
LOGV("... Pan Device Path = %s, result = %d", path, result);
jstring jPath = env->NewStringUTF(path);
env->CallVoidMethod(nat->me,
diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp
index 619a293..1bce332 100644
--- a/core/jni/android_util_AssetManager.cpp
+++ b/core/jni/android_util_AssetManager.cpp
@@ -1111,6 +1111,7 @@
if (value.dataType == Res_value::TYPE_REFERENCE && value.data == 0) {
DEBUG_STYLES(LOGI("-> Setting to @null!"));
value.dataType = Res_value::TYPE_NULL;
+ block = kXmlBlock;
}
DEBUG_STYLES(LOGI("Attribute 0x%08x: type=0x%x, data=0x%08x",
diff --git a/core/jni/android_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp
index ac491ea..554e336f 100644
--- a/core/jni/android_view_GLES20Canvas.cpp
+++ b/core/jni/android_view_GLES20Canvas.cpp
@@ -271,6 +271,22 @@
renderer->drawBitmap(bitmap, matrix, paint);
}
+static void android_view_GLES20Canvas_drawBitmapMesh(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer,
+ jint meshWidth, jint meshHeight, jfloatArray vertices, jint offset,
+ jintArray colors, jint colorOffset, SkPaint* paint) {
+ // This object allows the renderer to allocate a global JNI ref to the buffer object.
+ JavaHeapBitmapRef bitmapRef(env, bitmap, buffer);
+
+ jfloat* verticesArray = vertices ? env->GetFloatArrayElements(vertices, NULL) + offset : NULL;
+ jint* colorsArray = colors ? env->GetIntArrayElements(colors, NULL) + colorOffset : NULL;
+
+ renderer->drawBitmapMesh(bitmap, meshWidth, meshHeight, verticesArray, colorsArray, paint);
+
+ if (vertices) env->ReleaseFloatArrayElements(vertices, verticesArray, 0);
+ if (colors) env->ReleaseIntArrayElements(colors, colorsArray, 0);
+}
+
static void android_view_GLES20Canvas_drawPatch(JNIEnv* env, jobject canvas,
OpenGLRenderer* renderer, SkBitmap* bitmap, jbyteArray buffer, jbyteArray chunks,
float left, float top, float right, float bottom, SkPaint* paint) {
@@ -299,6 +315,17 @@
renderer->drawRect(left, top, right, bottom, paint);
}
+static void android_view_GLES20Canvas_drawRoundRect(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, jfloat left, jfloat top, jfloat right, jfloat bottom,
+ jfloat rx, jfloat ry, SkPaint* paint) {
+ renderer->drawRoundRect(left, top, right, bottom, rx, ry, paint);
+}
+
+static void android_view_GLES20Canvas_drawCircle(JNIEnv* env, jobject canvas,
+ OpenGLRenderer* renderer, jfloat x, jfloat y, jfloat radius, SkPaint* paint) {
+ renderer->drawCircle(x, y, radius, paint);
+}
+
static void android_view_GLES20Canvas_drawRects(JNIEnv* env, jobject canvas,
OpenGLRenderer* renderer, SkRegion* region, SkPaint* paint) {
SkRegion::Iterator it(*region);
@@ -382,24 +409,24 @@
}
static void android_view_GLES20Canvas_drawTextArray(JNIEnv* env, jobject canvas,
- OpenGLRenderer* renderer, jcharArray text, int index, int count,
- jfloat x, jfloat y, int flags, SkPaint* paint) {
+ OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
+ jfloat x, jfloat y, jint flags, SkPaint* paint) {
jchar* textArray = env->GetCharArrayElements(text, NULL);
renderText(renderer, textArray + index, count, x, y, flags, paint);
env->ReleaseCharArrayElements(text, textArray, JNI_ABORT);
}
static void android_view_GLES20Canvas_drawText(JNIEnv* env, jobject canvas,
- OpenGLRenderer* renderer, jstring text, int start, int end,
- jfloat x, jfloat y, int flags, SkPaint* paint) {
+ OpenGLRenderer* renderer, jstring text, jint start, jint end,
+ jfloat x, jfloat y, jint flags, SkPaint* paint) {
const jchar* textArray = env->GetStringChars(text, NULL);
renderText(renderer, textArray + start, end - start, x, y, flags, paint);
env->ReleaseStringChars(text, textArray);
}
static void android_view_GLES20Canvas_drawTextRunArray(JNIEnv* env, jobject canvas,
- OpenGLRenderer* renderer, jcharArray text, int index, int count,
- int contextIndex, int contextCount, jfloat x, jfloat y, int dirFlags,
+ OpenGLRenderer* renderer, jcharArray text, jint index, jint count,
+ jint contextIndex, jint contextCount, jfloat x, jfloat y, jint dirFlags,
SkPaint* paint) {
jchar* textArray = env->GetCharArrayElements(text, NULL);
renderTextRun(renderer, textArray + contextIndex, index - contextIndex,
@@ -408,8 +435,8 @@
}
static void android_view_GLES20Canvas_drawTextRun(JNIEnv* env, jobject canvas,
- OpenGLRenderer* renderer, jstring text, int start, int end,
- int contextStart, int contextEnd, jfloat x, jfloat y, int dirFlags,
+ OpenGLRenderer* renderer, jstring text, jint start, jint end,
+ jint contextStart, int contextEnd, jfloat x, jfloat y, jint dirFlags,
SkPaint* paint) {
const jchar* textArray = env->GetStringChars(text, NULL);
jint count = end - start;
@@ -562,14 +589,19 @@
{ "nGetMatrix", "(II)V", (void*) android_view_GLES20Canvas_getMatrix },
{ "nConcatMatrix", "(II)V", (void*) android_view_GLES20Canvas_concatMatrix },
- { "nDrawBitmap", "(II[BFFI)V", (void*) android_view_GLES20Canvas_drawBitmap },
- { "nDrawBitmap", "(II[BFFFFFFFFI)V", (void*) android_view_GLES20Canvas_drawBitmapRect },
- { "nDrawBitmap", "(II[BII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
- { "nDrawPatch", "(II[B[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch },
+ { "nDrawBitmap", "(II[BFFI)V", (void*) android_view_GLES20Canvas_drawBitmap },
+ { "nDrawBitmap", "(II[BFFFFFFFFI)V",(void*) android_view_GLES20Canvas_drawBitmapRect },
+ { "nDrawBitmap", "(II[BII)V", (void*) android_view_GLES20Canvas_drawBitmapMatrix },
+
+ { "nDrawBitmapMesh", "(II[BII[FI[III)V",(void*) android_view_GLES20Canvas_drawBitmapMesh },
+
+ { "nDrawPatch", "(II[B[BFFFFI)V", (void*) android_view_GLES20Canvas_drawPatch },
{ "nDrawColor", "(III)V", (void*) android_view_GLES20Canvas_drawColor },
{ "nDrawRect", "(IFFFFI)V", (void*) android_view_GLES20Canvas_drawRect },
{ "nDrawRects", "(III)V", (void*) android_view_GLES20Canvas_drawRects },
+ { "nDrawRoundRect", "(IFFFFFFI)V", (void*) android_view_GLES20Canvas_drawRoundRect },
+ { "nDrawCircle", "(IFFFI)V", (void*) android_view_GLES20Canvas_drawCircle },
{ "nDrawPath", "(III)V", (void*) android_view_GLES20Canvas_drawPath },
{ "nDrawLines", "(I[FIII)V", (void*) android_view_GLES20Canvas_drawLines },
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 9b890fa..08ce256 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1284,6 +1284,13 @@
android:description="@string/permlab_copyProtectedData"
android:protectionLevel="signature" />
+ <!-- Internal permission protecting access to the encryption methods
+ @hide
+ -->
+ <permission android:name="android.permission.CRYPT_KEEPER"
+ android:protectionLevel="signatureOrSystem" />
+
+
<!-- C2DM permission.
@hide Used internally.
-->
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_default.png b/core/res/res/drawable-hdpi/btn_code_lock_default.png
index df3137f..4469ce0 100644
--- a/core/res/res/drawable-hdpi/btn_code_lock_default.png
+++ b/core/res/res/drawable-hdpi/btn_code_lock_default.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_code_lock_touched.png b/core/res/res/drawable-hdpi/btn_code_lock_touched.png
index bf9e46a..0410dd3 100644
--- a/core/res/res/drawable-hdpi/btn_code_lock_touched.png
+++ b/core/res/res/drawable-hdpi/btn_code_lock_touched.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_dialog_disable.png b/core/res/res/drawable-hdpi/btn_dialog_disable.png
old mode 100644
new mode 100755
index 2fc5d1a..4ff634b
--- a/core/res/res/drawable-hdpi/btn_dialog_disable.png
+++ b/core/res/res/drawable-hdpi/btn_dialog_disable.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_dialog_normal.png b/core/res/res/drawable-hdpi/btn_dialog_normal.png
old mode 100644
new mode 100755
index c4a1026..e0cc339
--- a/core/res/res/drawable-hdpi/btn_dialog_normal.png
+++ b/core/res/res/drawable-hdpi/btn_dialog_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_dialog_pressed.png b/core/res/res/drawable-hdpi/btn_dialog_pressed.png
old mode 100644
new mode 100755
index 846f8bf..ed8e008
--- a/core/res/res/drawable-hdpi/btn_dialog_pressed.png
+++ b/core/res/res/drawable-hdpi/btn_dialog_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_dialog_selected.png b/core/res/res/drawable-hdpi/btn_dialog_selected.png
old mode 100644
new mode 100755
index 659c289..9b1a100
--- a/core/res/res/drawable-hdpi/btn_dialog_selected.png
+++ b/core/res/res/drawable-hdpi/btn_dialog_selected.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_off.png b/core/res/res/drawable-hdpi/btn_radio_off.png
old mode 100644
new mode 100755
index c0b14aa..48ee2ba
--- a/core/res/res/drawable-hdpi/btn_radio_off.png
+++ b/core/res/res/drawable-hdpi/btn_radio_off.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_off_pressed.png b/core/res/res/drawable-hdpi/btn_radio_off_pressed.png
old mode 100644
new mode 100755
index 3189581..5a4ad89
--- a/core/res/res/drawable-hdpi/btn_radio_off_pressed.png
+++ b/core/res/res/drawable-hdpi/btn_radio_off_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_off_selected.png b/core/res/res/drawable-hdpi/btn_radio_off_selected.png
old mode 100644
new mode 100755
index f337703..7d5c676
--- a/core/res/res/drawable-hdpi/btn_radio_off_selected.png
+++ b/core/res/res/drawable-hdpi/btn_radio_off_selected.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_on.png b/core/res/res/drawable-hdpi/btn_radio_on.png
old mode 100644
new mode 100755
index c90d2eb..2472c20
--- a/core/res/res/drawable-hdpi/btn_radio_on.png
+++ b/core/res/res/drawable-hdpi/btn_radio_on.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_on_pressed.png b/core/res/res/drawable-hdpi/btn_radio_on_pressed.png
old mode 100644
new mode 100755
index d79450b8..98d74ce
--- a/core/res/res/drawable-hdpi/btn_radio_on_pressed.png
+++ b/core/res/res/drawable-hdpi/btn_radio_on_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/btn_radio_on_selected.png b/core/res/res/drawable-hdpi/btn_radio_on_selected.png
old mode 100644
new mode 100755
index db50c43..b6ab46c
--- a/core/res/res/drawable-hdpi/btn_radio_on_selected.png
+++ b/core/res/res/drawable-hdpi/btn_radio_on_selected.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default.png
index 0102a61..c45b956 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_default.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png
index 82ad8f7..b9fd0a4 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_green.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png
index f9d0d33..94e947d 100644
--- a/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png
+++ b/core/res/res/drawable-hdpi/indicator_code_lock_point_area_red.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_bar_left_end_normal.9.png b/core/res/res/drawable-hdpi/jog_tab_bar_left_end_normal.9.png
index 109be42..b9ec237 100644
--- a/core/res/res/drawable-hdpi/jog_tab_bar_left_end_normal.9.png
+++ b/core/res/res/drawable-hdpi/jog_tab_bar_left_end_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_bar_right_end_normal.9.png b/core/res/res/drawable-hdpi/jog_tab_bar_right_end_normal.9.png
index 030c9e9..30fcda5 100644
--- a/core/res/res/drawable-hdpi/jog_tab_bar_right_end_normal.9.png
+++ b/core/res/res/drawable-hdpi/jog_tab_bar_right_end_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png b/core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png
old mode 100644
new mode 100755
index 3499208..9599fb5
--- a/core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png b/core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png
old mode 100644
new mode 100755
index 91eaec8..46d9ab3
--- a/core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_confirm_red.png b/core/res/res/drawable-hdpi/jog_tab_left_confirm_red.png
old mode 100644
new mode 100755
index 8818b9e..6c0dc0a
--- a/core/res/res/drawable-hdpi/jog_tab_left_confirm_red.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_confirm_red.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png b/core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png
old mode 100644
new mode 100755
index e5bc5f6..3f9fb8f
--- a/core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_normal.png b/core/res/res/drawable-hdpi/jog_tab_left_normal.png
index 5326c7c..d43c5e2 100644
--- a/core/res/res/drawable-hdpi/jog_tab_left_normal.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_left_pressed.png b/core/res/res/drawable-hdpi/jog_tab_left_pressed.png
old mode 100644
new mode 100755
index 7b906df..ec98790
--- a/core/res/res/drawable-hdpi/jog_tab_left_pressed.png
+++ b/core/res/res/drawable-hdpi/jog_tab_left_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png b/core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png
old mode 100644
new mode 100755
index ea8c315..2861e8d
--- a/core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png b/core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png
old mode 100644
new mode 100755
index aa0ceb9..e974bbc
--- a/core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_confirm_red.png b/core/res/res/drawable-hdpi/jog_tab_right_confirm_red.png
old mode 100644
new mode 100755
index d772fb6..9647fa6
--- a/core/res/res/drawable-hdpi/jog_tab_right_confirm_red.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_confirm_red.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png b/core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png
old mode 100644
new mode 100755
index 3cfeb67..ad878e1
--- a/core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_normal.png b/core/res/res/drawable-hdpi/jog_tab_right_normal.png
index da7726b..1eb4234 100644
--- a/core/res/res/drawable-hdpi/jog_tab_right_normal.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_normal.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/jog_tab_right_pressed.png b/core/res/res/drawable-hdpi/jog_tab_right_pressed.png
old mode 100644
new mode 100755
index 450a325..647e802
--- a/core/res/res/drawable-hdpi/jog_tab_right_pressed.png
+++ b/core/res/res/drawable-hdpi/jog_tab_right_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
new file mode 100644
index 0000000..7719df8
--- /dev/null
+++ b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-hdpi/text_edit_side_paste_window.9.png b/core/res/res/drawable-hdpi/text_edit_side_paste_window.9.png
new file mode 100644
index 0000000..7cd000b
--- /dev/null
+++ b/core/res/res/drawable-hdpi/text_edit_side_paste_window.9.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/core/res/res/drawable-hdpi/vpn_connected.png
similarity index 100%
rename from packages/VpnServices/res/drawable/vpn_connected.png
rename to core/res/res/drawable-hdpi/vpn_connected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/core/res/res/drawable-hdpi/vpn_disconnected.png
similarity index 100%
rename from packages/VpnServices/res/drawable/vpn_disconnected.png
rename to core/res/res/drawable-hdpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-land-mdpi/jog_tab_target_gray.png b/core/res/res/drawable-land-mdpi/jog_tab_target_gray.png
new file mode 100644
index 0000000..1319b6e
--- /dev/null
+++ b/core/res/res/drawable-land-mdpi/jog_tab_target_gray.png
Binary files differ
diff --git a/core/res/res/drawable-land-mdpi/jog_tab_target_green.png b/core/res/res/drawable-land-mdpi/jog_tab_target_green.png
new file mode 100644
index 0000000..88a3f30
--- /dev/null
+++ b/core/res/res/drawable-land-mdpi/jog_tab_target_green.png
Binary files differ
diff --git a/core/res/res/drawable-land-mdpi/jog_tab_target_red.png b/core/res/res/drawable-land-mdpi/jog_tab_target_red.png
new file mode 100644
index 0000000..300c401
--- /dev/null
+++ b/core/res/res/drawable-land-mdpi/jog_tab_target_red.png
Binary files differ
diff --git a/core/res/res/drawable-land-mdpi/jog_tab_target_yellow.png b/core/res/res/drawable-land-mdpi/jog_tab_target_yellow.png
new file mode 100644
index 0000000..efa30ee
--- /dev/null
+++ b/core/res/res/drawable-land-mdpi/jog_tab_target_yellow.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/core/res/res/drawable-ldpi/vpn_connected.png
similarity index 100%
copy from packages/VpnServices/res/drawable/vpn_connected.png
copy to core/res/res/drawable-ldpi/vpn_connected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/core/res/res/drawable-ldpi/vpn_disconnected.png
similarity index 100%
copy from packages/VpnServices/res/drawable/vpn_disconnected.png
copy to core/res/res/drawable-ldpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_default.png b/core/res/res/drawable-mdpi/btn_code_lock_default.png
index c2e0b05..f524317 100755
--- a/core/res/res/drawable-mdpi/btn_code_lock_default.png
+++ b/core/res/res/drawable-mdpi/btn_code_lock_default.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_code_lock_touched.png b/core/res/res/drawable-mdpi/btn_code_lock_touched.png
index 70e95a2..5cd436c 100755
--- a/core/res/res/drawable-mdpi/btn_code_lock_touched.png
+++ b/core/res/res/drawable-mdpi/btn_code_lock_touched.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_dialog_disable.png b/core/res/res/drawable-mdpi/btn_dialog_disable.png
index f041cab..3de9895 100755
--- a/core/res/res/drawable-mdpi/btn_dialog_disable.png
+++ b/core/res/res/drawable-mdpi/btn_dialog_disable.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_dialog_normal.png b/core/res/res/drawable-mdpi/btn_dialog_normal.png
index a2d27fa..eca5828 100755
--- a/core/res/res/drawable-mdpi/btn_dialog_normal.png
+++ b/core/res/res/drawable-mdpi/btn_dialog_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_dialog_pressed.png b/core/res/res/drawable-mdpi/btn_dialog_pressed.png
index 9c9922a..f9c4551 100755
--- a/core/res/res/drawable-mdpi/btn_dialog_pressed.png
+++ b/core/res/res/drawable-mdpi/btn_dialog_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_dialog_selected.png b/core/res/res/drawable-mdpi/btn_dialog_selected.png
index 7656de5..b0afd7f 100755
--- a/core/res/res/drawable-mdpi/btn_dialog_selected.png
+++ b/core/res/res/drawable-mdpi/btn_dialog_selected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_off.png b/core/res/res/drawable-mdpi/btn_radio_off.png
index 407632b..cf76ace 100644
--- a/core/res/res/drawable-mdpi/btn_radio_off.png
+++ b/core/res/res/drawable-mdpi/btn_radio_off.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_off_pressed.png b/core/res/res/drawable-mdpi/btn_radio_off_pressed.png
index d6d8a9d..e03561a 100644
--- a/core/res/res/drawable-mdpi/btn_radio_off_pressed.png
+++ b/core/res/res/drawable-mdpi/btn_radio_off_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_off_selected.png b/core/res/res/drawable-mdpi/btn_radio_off_selected.png
index 53f3e87..b3aa94e 100644
--- a/core/res/res/drawable-mdpi/btn_radio_off_selected.png
+++ b/core/res/res/drawable-mdpi/btn_radio_off_selected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on.png b/core/res/res/drawable-mdpi/btn_radio_on.png
index 25a3ccc..5f978c0 100644
--- a/core/res/res/drawable-mdpi/btn_radio_on.png
+++ b/core/res/res/drawable-mdpi/btn_radio_on.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_pressed.png b/core/res/res/drawable-mdpi/btn_radio_on_pressed.png
index c904a35..a0636fe 100644
--- a/core/res/res/drawable-mdpi/btn_radio_on_pressed.png
+++ b/core/res/res/drawable-mdpi/btn_radio_on_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/btn_radio_on_selected.png b/core/res/res/drawable-mdpi/btn_radio_on_selected.png
index 78e1fc0..b510d47 100644
--- a/core/res/res/drawable-mdpi/btn_radio_on_selected.png
+++ b/core/res/res/drawable-mdpi/btn_radio_on_selected.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_green_up.png b/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_green_up.png
index ef91dc4..7ddeba5 100644
--- a/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_green_up.png
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_green_up.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_red_up.png b/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_red_up.png
index f3d4204b..7201e58 100644
--- a/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_red_up.png
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_drag_direction_red_up.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default.png
index 4e88b37..8546c5f 100755
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default.png
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_default.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green.png
index 8020846..a98a29a 100755
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green.png
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_green.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red.png b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red.png
index b7aee1ba..6d579cb 100755
--- a/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red.png
+++ b/core/res/res/drawable-mdpi/indicator_code_lock_point_area_red.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_gray.9.png b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_gray.9.png
index 4ce09fa..a6ee329 100644
--- a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_gray.9.png
+++ b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_gray.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_green.9.png b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_green.9.png
index 9d7565f..386ed9d 100644
--- a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_green.9.png
+++ b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_green.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_red.9.png b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_red.9.png
index d5f9bd8..0242a42 100644
--- a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_red.9.png
+++ b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_red.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_yellow.9.png b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_yellow.9.png
index 5b9c5b4..b8c2e18 100644
--- a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_yellow.9.png
+++ b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_confirm_yellow.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_pressed.9.png b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_pressed.9.png
index f41750d..8bdfd84 100644
--- a/core/res/res/drawable-mdpi/jog_tab_bar_right_end_pressed.9.png
+++ b/core/res/res/drawable-mdpi/jog_tab_bar_right_end_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.png b/core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.png
old mode 100644
new mode 100755
index e8544ff..3dce451
--- a/core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_confirm_green.png b/core/res/res/drawable-mdpi/jog_tab_left_confirm_green.png
old mode 100644
new mode 100755
index d0ba8f8..829b146
--- a/core/res/res/drawable-mdpi/jog_tab_left_confirm_green.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_confirm_red.png b/core/res/res/drawable-mdpi/jog_tab_left_confirm_red.png
index 5188c86..f2ceb2e 100644
--- a/core/res/res/drawable-mdpi/jog_tab_left_confirm_red.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_confirm_red.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.png b/core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.png
old mode 100644
new mode 100755
index 861e17a..5a29262
--- a/core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_normal.png b/core/res/res/drawable-mdpi/jog_tab_left_normal.png
old mode 100644
new mode 100755
index 7af1b85..eb91e97
--- a/core/res/res/drawable-mdpi/jog_tab_left_normal.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_left_pressed.png b/core/res/res/drawable-mdpi/jog_tab_left_pressed.png
old mode 100644
new mode 100755
index b76e83e..9951992
--- a/core/res/res/drawable-mdpi/jog_tab_left_pressed.png
+++ b/core/res/res/drawable-mdpi/jog_tab_left_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.png b/core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.png
old mode 100644
new mode 100755
index 814a50d..d446480
--- a/core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_confirm_gray.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_confirm_green.png b/core/res/res/drawable-mdpi/jog_tab_right_confirm_green.png
old mode 100644
new mode 100755
index cf157fc..96d7acb
--- a/core/res/res/drawable-mdpi/jog_tab_right_confirm_green.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_confirm_green.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_confirm_red.png b/core/res/res/drawable-mdpi/jog_tab_right_confirm_red.png
index 74f2935..2e1e105 100644
--- a/core/res/res/drawable-mdpi/jog_tab_right_confirm_red.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_confirm_red.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.png b/core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.png
old mode 100644
new mode 100755
index 6655731..8224c38
--- a/core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_confirm_yellow.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_normal.png b/core/res/res/drawable-mdpi/jog_tab_right_normal.png
old mode 100644
new mode 100755
index 479c9a5..f2113f2
--- a/core/res/res/drawable-mdpi/jog_tab_right_normal.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_normal.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/jog_tab_right_pressed.png b/core/res/res/drawable-mdpi/jog_tab_right_pressed.png
old mode 100644
new mode 100755
index 454aaf2..65cd51e
--- a/core/res/res/drawable-mdpi/jog_tab_right_pressed.png
+++ b/core/res/res/drawable-mdpi/jog_tab_right_pressed.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
new file mode 100644
index 0000000..a933d9a
--- /dev/null
+++ b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/text_edit_side_paste_window.9.png b/core/res/res/drawable-mdpi/text_edit_side_paste_window.9.png
new file mode 100644
index 0000000..d87c35b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/text_edit_side_paste_window.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png
new file mode 100644
index 0000000..137923b
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png
new file mode 100644
index 0000000..62b1deb
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
new file mode 100644
index 0000000..ab30a77
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png
new file mode 100644
index 0000000..9274bc7
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png
Binary files differ
diff --git a/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png
new file mode 100644
index 0000000..e46155e
--- /dev/null
+++ b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/core/res/res/drawable-mdpi/vpn_connected.png
similarity index 100%
copy from packages/VpnServices/res/drawable/vpn_connected.png
copy to core/res/res/drawable-mdpi/vpn_connected.png
Binary files differ
diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/core/res/res/drawable-mdpi/vpn_disconnected.png
similarity index 100%
copy from packages/VpnServices/res/drawable/vpn_disconnected.png
copy to core/res/res/drawable-mdpi/vpn_disconnected.png
Binary files differ
diff --git a/core/res/res/drawable-nodpi/platlogo.png b/core/res/res/drawable-nodpi/platlogo.png
index e5af356..67e6ac3 100644
--- a/core/res/res/drawable-nodpi/platlogo.png
+++ b/core/res/res/drawable-nodpi/platlogo.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png
new file mode 100644
index 0000000..0fbdbfa
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png
new file mode 100644
index 0000000..ae97453
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png
new file mode 100644
index 0000000..4127d1e
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
new file mode 100644
index 0000000..525ab8a
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
new file mode 100644
index 0000000..eb05820
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png
Binary files differ
diff --git a/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
new file mode 100644
index 0000000..416b2c7
--- /dev/null
+++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png
Binary files differ
diff --git a/core/res/res/drawable/lockscreen_password_field_dark.xml b/core/res/res/drawable/lockscreen_password_field_dark.xml
new file mode 100644
index 0000000..92ceb79
--- /dev/null
+++ b/core/res/res/drawable/lockscreen_password_field_dark.xml
@@ -0,0 +1,26 @@
+<?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.
+-->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_window_focused="false" android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
+ <item android:state_window_focused="false" android:state_enabled="false" android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
+ <item android:state_enabled="true" android:state_focused="true" android:drawable="@drawable/textfield_bg_activated_holo_dark" />
+ <iten android:state_enabled="true" android:state_activated="true" android:drawable="@drawable/textfield_bg_focused_holo_dark" />
+ <item android:state_enabled="true" android:drawable="@drawable/textfield_bg_default_holo_dark" />
+ <item android:state_focused="true" android:drawable="@drawable/textfield_bg_disabled_focused_holo_dark" />
+ <item android:drawable="@drawable/textfield_bg_disabled_holo_dark" />
+</selector>
+
diff --git a/core/res/res/layout-xlarge/activity_list.xml b/core/res/res/layout-xlarge/activity_list.xml
index 9d6b8f5..ad485c1 100644
--- a/core/res/res/layout-xlarge/activity_list.xml
+++ b/core/res/res/layout-xlarge/activity_list.xml
@@ -32,15 +32,14 @@
<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:gravity="center_vertical|left"
+ android:minHeight="60dip"
+ android:layout_marginLeft="32dip"
android:layout_marginRight="32dip">
<ImageView android:id="@+id/icon"
android:layout_width="wrap_content"
@@ -49,7 +48,7 @@
android:src="@null"
android:visibility="gone" />
<com.android.internal.widget.DialogTitle android:id="@+id/alertTitle"
- style="?android:attr/textAppearanceLarge"
+ style="?android:attr/textAppearanceMedium"
android:singleLine="true"
android:ellipsize="end"
android:layout_width="match_parent"
@@ -57,15 +56,19 @@
</LinearLayout>
<ImageView android:id="@+id/titleDivider"
android:layout_width="match_parent"
- android:layout_height="1dip"
+ android:layout_height="4dip"
+ android:layout_marginLeft="16dip"
+ android:layout_marginRight="16dip"
android:scaleType="fitXY"
android:gravity="fill_horizontal"
- android:src="@android:drawable/divider_horizontal_dark" />
+ android:src="@android:drawable/divider_strong_holo" />
<!-- 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_marginLeft="32dip"
+ android:layout_marginRight="32dip"
android:layout_height="0dip"
android:layout_weight="1">
@@ -86,23 +89,19 @@
/>
</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" >
+ android:orientation="vertical"
+ android:divider="?android:attr/dividerHorizontal"
+ android:showDividers="beginning"
+ android:dividerPadding="16dip">
<LinearLayout
+ style="?android:attr/buttonBarStyle"
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">
@@ -111,20 +110,21 @@
android:layout_width="0dip"
android:layout_height="wrap_content"
android:orientation="horizontal"
- />
+ android:visibility="gone" />
<Button android:id="@+id/button1"
android:layout_width="0dip"
- android:layout_gravity="center"
+ android:layout_gravity="left"
android:layout_weight="1"
android:maxLines="2"
android:text="@string/cancel"
+ style="?android:attr/buttonBarButtonStyle"
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"
- />
+ android:visibility="gone" />
</LinearLayout>
</LinearLayout>
</com.android.internal.widget.WeightedLinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
index 4bc7292..5ea43dc 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml
@@ -20,76 +20,88 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="horizontal"
- >
+ android:orientation="vertical">
- <!-- left side: status -->
- <RelativeLayout
- android:layout_height="match_parent"
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
android:layout_weight="1"
- android:layout_width="0dip">
+ />
+ <RelativeLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <!-- left side: status -->
<include layout="@layout/keyguard_screen_status_land"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="102dip"
- android:layout_marginTop="320dip"
- android:layout_alignParentTop="true"
+ android:paddingTop="50dip"
+ android:layout_centerVertical="true"
android:layout_alignParentLeft="true"/>
+ <!-- right side: password -->
+ <LinearLayout
+ android:layout_width="330dip"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_alignParentRight="true"
+ android:layout_centerVertical="true"
+ android:layout_marginRight="155dip">
+
+ <!-- Password entry field -->
+ <EditText android:id="@+id/passwordEntry"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:singleLine="true"
+ android:textStyle="normal"
+ android:inputType="textPassword"
+ android:gravity="center"
+ android:textSize="24sp"
+ android:textAppearance="?android:attr/textAppearanceMedium"
+ android:background="@drawable/lockscreen_password_field_dark"
+ android:textColor="#ffffffff"
+ />
+
+ <!-- Numeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
+ android:layout_width="330dip"
+ android:layout_height="330dip"
+ android:background="#00000000"
+ android:layout_marginTop="5dip"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ android:visibility="gone"
+ />
+ </LinearLayout>
+
</RelativeLayout>
- <!-- right side: password -->
- <LinearLayout
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:orientation="vertical"
+ <View
+ android:layout_width="match_parent"
+ android:layout_height="0dip"
android:layout_weight="1"
- android:gravity="center">
+ />
- <!-- Password entry field -->
- <EditText android:id="@+id/passwordEntry"
- android:layout_height="wrap_content"
- android:layout_width="330dip"
- android:singleLine="true"
- android:textStyle="normal"
- android:inputType="textPassword"
- android:gravity="center"
- android:layout_gravity="center"
- android:textSize="24sp"
- android:layout_marginTop="120dip"
- android:layout_marginBottom="5dip"
- android:textAppearance="?android:attr/textAppearanceMedium"
- android:background="@drawable/password_field_default"
- android:textColor="#ffffffff"
- />
+ <!-- Alphanumeric keyboard -->
+ <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="#00000000"
+ android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
+ android:visibility="gone"
+ />
- <!-- Numeric keyboard -->
- <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboard"
- android:layout_width="330dip"
- android:layout_height="260dip"
- android:background="#00000000"
- android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
- />
- <!-- Alphanumeric keyboard -->
- <com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
- android:layout_width="450dip"
- android:layout_height="230dip"
- android:background="#00000000"
- android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
- />
+ <!-- emergency call button NOT CURRENTLY USED -->
+ <Button
+ android:id="@+id/emergencyCall"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:drawableLeft="@drawable/ic_emergency"
+ android:drawablePadding="8dip"
+ android:text="@string/lockscreen_emergency_call"
+ android:visibility="gone"
+ style="@style/Widget.Button.Transparent"
+ />
- <!-- emergency call button -->
- <Button
- android:id="@+id/emergencyCall"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:drawableLeft="@drawable/ic_emergency"
- android:drawablePadding="8dip"
- android:text="@string/lockscreen_emergency_call"
- android:visibility="gone"
- style="@style/Widget.Button.Transparent"
- />
-
- </LinearLayout>
</LinearLayout>
diff --git a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
index e63fb9b..8a059f5 100644
--- a/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
+++ b/core/res/res/layout-xlarge/keyguard_screen_password_portrait.xml
@@ -56,7 +56,7 @@
android:layout_marginTop="120dip"
android:layout_marginBottom="5dip"
android:textAppearance="?android:attr/textAppearanceMedium"
- android:background="@drawable/password_field_default"
+ android:background="@drawable/lockscreen_password_field_dark"
android:textColor="#ffffffff"
/>
@@ -69,7 +69,7 @@
/>
<!-- Alphanumeric keyboard -->
<com.android.internal.widget.PasswordEntryKeyboardView android:id="@+id/keyboardAlpha"
- android:layout_width="450dip"
+ android:layout_width="match_parent"
android:layout_height="230dip"
android:background="#00000000"
android:keyBackground="@drawable/btn_keyboard_key_fulltrans"
diff --git a/core/res/res/layout/activity_list_item_2.xml b/core/res/res/layout/activity_list_item_2.xml
index e937d7b..3b84c733 100644
--- a/core/res/res/layout/activity_list_item_2.xml
+++ b/core/res/res/layout/activity_list_item_2.xml
@@ -18,8 +18,8 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:minHeight="?android:attr/listPreferredItemHeight"
- android:textAppearance="?android:attr/textAppearanceLarge"
+ android:textAppearance="?android:attr/textAppearanceMedium"
android:gravity="center_vertical"
android:drawablePadding="14dip"
- android:paddingLeft="15dip"
- android:paddingRight="15dip" />
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip" />
diff --git a/core/res/res/layout/date_picker.xml b/core/res/res/layout/date_picker.xml
index e9663b1..1649466 100644
--- a/core/res/res/layout/date_picker.xml
+++ b/core/res/res/layout/date_picker.xml
@@ -40,10 +40,10 @@
<!-- Month -->
<NumberPicker
android:id="@+id/month"
- android:layout_width="48dip"
+ android:layout_width="80dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="1dip"
+ android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -51,10 +51,10 @@
<!-- Day -->
<NumberPicker
android:id="@+id/day"
- android:layout_width="48dip"
+ android:layout_width="80dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="1dip"
+ android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -62,10 +62,10 @@
<!-- Year -->
<NumberPicker
android:id="@+id/year"
- android:layout_width="48dip"
+ android:layout_width="95dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="1dip"
+ android:layout_marginRight="1dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
@@ -81,6 +81,7 @@
android:layout_weight="1"
android:focusable="true"
android:focusableInTouchMode="true"
+ android:visibility="gone"
/>
</LinearLayout>
diff --git a/core/res/res/layout/date_picker_holo.xml b/core/res/res/layout/date_picker_holo.xml
new file mode 100644
index 0000000..026cbfb
--- /dev/null
+++ b/core/res/res/layout/date_picker_holo.xml
@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<!-- Layout of date picker-->
+
+<!-- Warning: everything within the "pickers" layout is removed and re-ordered
+ depending on the date format selected by the user.
+-->
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:layout_gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:gravity="center">
+
+ <LinearLayout android:id="@+id/pickers"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_marginRight="22dip"
+ android:layout_weight="1"
+ android:orientation="horizontal"
+ android:gravity="center">
+
+ <!-- Month -->
+ <NumberPicker
+ android:id="@+id/month"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- Day -->
+ <NumberPicker
+ android:id="@+id/day"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- Year -->
+ <NumberPicker
+ android:id="@+id/year"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ </LinearLayout>
+
+ <!-- calendar view -->
+ <CalendarView
+ android:id="@+id/calendar_view"
+ android:layout_width="245dip"
+ android:layout_height="280dip"
+ android:layout_marginLeft="22dip"
+ android:layout_weight="1"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/layout/text_edit_side_no_paste_window.xml b/core/res/res/layout/text_edit_side_no_paste_window.xml
new file mode 100644
index 0000000..0ed3849
--- /dev/null
+++ b/core/res/res/layout/text_edit_side_no_paste_window.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:drawableLeft="@android:drawable/ic_menu_paste_dark"
+ android:drawablePadding="8dip"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textColor="@android:color/dim_foreground_dark_inverse_disabled"
+ android:background="@android:drawable/text_edit_side_paste_window"
+ android:text="@android:string/pasteDisabled"
+ android:layout_marginBottom="12dip"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/layout/text_edit_side_paste_window.xml b/core/res/res/layout/text_edit_side_paste_window.xml
new file mode 100644
index 0000000..689a039
--- /dev/null
+++ b/core/res/res/layout/text_edit_side_paste_window.xml
@@ -0,0 +1,38 @@
+<?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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <TextView android:id="@+id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dip"
+ android:paddingRight="16dip"
+ android:paddingTop="8dip"
+ android:paddingBottom="8dip"
+ android:drawableLeft="@android:drawable/ic_menu_paste_light"
+ android:drawablePadding="8dip"
+ android:gravity="center"
+ android:textAppearance="?android:attr/textAppearanceMediumInverse"
+ android:textColor="@android:color/black"
+ android:background="@android:drawable/text_edit_side_paste_window"
+ android:text="@android:string/paste"
+ android:layout_marginBottom="12dip"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/layout/time_picker.xml b/core/res/res/layout/time_picker.xml
index 382b2f6..df46db4 100644
--- a/core/res/res/layout/time_picker.xml
+++ b/core/res/res/layout/time_picker.xml
@@ -28,42 +28,33 @@
<!-- hour -->
<NumberPicker
android:id="@+id/hour"
- android:layout_width="48dip"
+ android:layout_width="70dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="20dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
- <!-- divider -->
- <TextView
- android:id="@+id/divider"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="center_vertical"
- />
-
<!-- minute -->
<NumberPicker
android:id="@+id/minute"
- android:layout_width="48dip"
+ android:layout_width="70dip"
android:layout_height="wrap_content"
- android:layout_marginLeft="20dip"
- android:layout_marginRight="22dip"
+ android:layout_marginLeft="5dip"
android:focusable="true"
android:focusableInTouchMode="true"
/>
<!-- AM / PM -->
- <NumberPicker
+ <Button
android:id="@+id/amPm"
- android:layout_width="48dip"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_marginLeft="22dip"
- android:layout_marginRight="22dip"
- android:focusable="true"
- android:focusableInTouchMode="true"
+ android:layout_marginTop="43dip"
+ android:layout_marginLeft="5dip"
+ android:paddingLeft="20dip"
+ android:paddingRight="20dip"
+ style="?android:attr/textAppearanceLargeInverse"
+ android:textColor="@android:color/primary_text_light_nodisable"
/>
</LinearLayout>
diff --git a/core/res/res/layout/time_picker_holo.xml b/core/res/res/layout/time_picker_holo.xml
new file mode 100644
index 0000000..ca6fe2d
--- /dev/null
+++ b/core/res/res/layout/time_picker_holo.xml
@@ -0,0 +1,69 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<!-- Layout of time picker -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_gravity="center_horizontal"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+
+ <!-- hour -->
+ <NumberPicker
+ android:id="@+id/hour"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="20dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- divider -->
+ <TextView
+ android:id="@+id/divider"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ />
+
+ <!-- minute -->
+ <NumberPicker
+ android:id="@+id/minute"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="20dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+ <!-- AM / PM -->
+ <NumberPicker
+ android:id="@+id/amPm"
+ android:layout_width="48dip"
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="22dip"
+ android:layout_marginRight="22dip"
+ android:focusable="true"
+ android:focusableInTouchMode="true"
+ />
+
+</LinearLayout>
diff --git a/core/res/res/values-xlarge-land/dimens.xml b/core/res/res/values-xlarge-land/dimens.xml
index 6a2b93f..0b43a42 100644
--- a/core/res/res/values-xlarge-land/dimens.xml
+++ b/core/res/res/values-xlarge-land/dimens.xml
@@ -17,6 +17,9 @@
*/
-->
<resources>
+ <!-- Default height of a key in the password keyboard for alpha -->
+ <dimen name="password_keyboard_key_height_alpha">100dip</dimen>
+ <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
<!-- Minimum width of the search view text entry area. -->
<dimen name="search_view_text_min_width">256dip</dimen>
</resources>
diff --git a/core/res/res/values-xlarge/dimens.xml b/core/res/res/values-xlarge/dimens.xml
index 5b0ea30..63d3619 100644
--- a/core/res/res/values-xlarge/dimens.xml
+++ b/core/res/res/values-xlarge/dimens.xml
@@ -24,15 +24,17 @@
<dimen name="status_bar_icon_size">32dip</dimen>
<!-- Size of the giant number (unread count) in the notifications -->
<dimen name="status_bar_content_number_size">48sp</dimen>
-
+
<!-- Margin at the edge of the screen to ignore touch events for in the windowshade. -->
<!-- Margin for permanent screen decorations at the bottom. -->
<dimen name="screen_margin_bottom">48dip</dimen>
-
+
<!-- Default height of a key in the password keyboard for alpha -->
- <dimen name="password_keyboard_key_height_alpha">0.35in</dimen>
+ <dimen name="password_keyboard_key_height_alpha">75dip</dimen>
<!-- Default height of a key in the password keyboard for numeric -->
- <dimen name="password_keyboard_key_height_numeric">0.47in</dimen>
+ <dimen name="password_keyboard_key_height_numeric">75dip</dimen>
+ <!-- keyboardHeight = key_height*4 + key_bottom_gap*3 -->
+ <dimen name="password_keyboard_height">48.0mm</dimen>
<!-- The width that is used when creating thumbnails of applications. -->
<dimen name="thumbnail_width">230dp</dimen>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index de233c8..e76692a 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -534,6 +534,12 @@
<!-- The CalndarView style. -->
<attr name="calendarViewStyle" format="reference" />
+ <!-- The TimePicker style. -->
+ <attr name="timePickerStyle" format="reference" />
+
+ <!-- The DatePicker style. -->
+ <attr name="datePickerStyle" format="reference" />
+
<!-- Fast scroller styles -->
<eat-comment />
@@ -643,6 +649,11 @@
<attr name="textEditPasteWindowLayout" format="reference" />
<!-- Variation of textEditPasteWindowLayout displayed when the clipboard is empty. -->
<attr name="textEditNoPasteWindowLayout" format="reference" />
+ <!-- Used instead of textEditPasteWindowLayout when the window is moved on the side of the
+ insertion cursor because it would be clipped if it were positioned on top. -->
+ <attr name="textEditSidePasteWindowLayout" format="reference" />
+ <!-- Variation of textEditSidePasteWindowLayout displayed when the clipboard is empty. -->
+ <attr name="textEditSideNoPasteWindowLayout" format="reference" />
<!-- Theme to use for dialogs spawned from this theme. -->
<attr name="dialogTheme" format="reference" />
@@ -2735,6 +2746,12 @@
<attr name="textEditPasteWindowLayout" />
<!-- Variation of textEditPasteWindowLayout displayed when the clipboard is empty. -->
<attr name="textEditNoPasteWindowLayout" />
+ <!-- Used instead of textEditPasteWindowLayout when the window is moved on the side of the
+ insertion cursor because it would be clipped if it were positioned on top. -->
+ <attr name="textEditSidePasteWindowLayout" />
+ <!-- Variation of textEditSidePasteWindowLayout displayed when the clipboard is empty. -->
+ <attr name="textEditSideNoPasteWindowLayout" />
+
<!-- Indicates that the content of a non-editable text can be selected. -->
<attr name="textIsSelectable" />
</declare-styleable>
@@ -2869,6 +2886,7 @@
<!-- Gravity setting for positioning the currently selected item. -->
<attr name="gravity" />
</declare-styleable>
+
<declare-styleable name="DatePicker">
<!-- The first year (inclusive), for example "1940". -->
<attr name="startYear" format="integer" />
@@ -2882,6 +2900,8 @@
<attr name="minDate" format="string" />
<!-- The minimal date shown by this calendar view in mm/dd/yyyy format. -->
<attr name="maxDate" format="string" />
+ <!-- @hide The layout of the time picker. -->
+ <attr name="layout" />
</declare-styleable>
<declare-styleable name="TwoLineListItem">
@@ -3080,9 +3100,24 @@
</declare-styleable>
<declare-styleable name="NumberPicker">
- <attr name="orientation" />
- <!-- Color for the solid color background if such for optimized rendering. -->
+ <!-- @hide Color for the solid color background if such for optimized rendering. -->
<attr name="solidColor" format="color|reference" />
+ <!-- @hide Whether the number picker supports fligning. -->
+ <attr name="flingable" format="boolean" />
+ <!-- @hide The divider for making the selection area. -->
+ <attr name="selectionDivider" format="reference" />
+ <!-- @hide The height of the selection divider. -->
+ <attr name="selectionDividerHeight" format="dimension" />
+ </declare-styleable>
+
+ <declare-styleable name="TimePicker">
+ <!-- @hide The layout of the time picker. -->
+ <attr name="layout" />
+ </declare-styleable>
+
+ <declare-styleable name="DatePicker">
+ <!-- @hide The layout of the time picker. -->
+ <attr name="layout" />
</declare-styleable>
<!-- ========================= -->
@@ -4624,8 +4659,6 @@
<flag name="homeAsUp" value="0x4" />
<flag name="showTitle" value="0x8" />
<flag name="showCustom" value="0x10" />
- <!-- DEPRECATED - Remove this later!! -->
- <flag name="hideHome" value="0x1000" />
</attr>
<!-- Specifies title text used for navigationMode="normal" -->
<attr name="title" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 1b47b54..e6552dfc 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -1426,6 +1426,8 @@
<public type="attr" name="fastScrollTextColor" />
<public type="attr" name="largeHeap" />
<public type="attr" name="windowCloseOnTouchOutside" />
+ <public type="attr" name="datePickerStyle" />
+ <public type="attr" name="calendarViewStyle" />
<!-- A simple fade-in animation. -->
<public type="animator" name="fade_in" id="0x010b0000" />
@@ -1466,7 +1468,6 @@
<!-- Context menu ID for the "Select text..." menu item to switch to text
selection context mode in text views. -->
<public type="id" name="selectTextMode" />
- <public type="id" name="up" />
<public type="dimen" name="dialog_min_width_major" />
<public type="dimen" name="dialog_min_width_minor" />
@@ -1627,21 +1628,17 @@
<public type="style" name="Holo.Light.ButtonBar.AlertDialog" />
<public type="style" name="Holo.SegmentedButton" />
<public type="style" name="Holo.Light.SegmentedButton" />
- <public type="style" name="Widget.ImageButton.NumberPickerUpButton" />
- <public type="style" name="Widget.EditText.NumberPickerInputText" />
- <public type="style" name="Widget.ImageButton.NumberPickerDownButton" />
- <public type="style" name="Widget.Holo.ImageButton.NumberPickerUpButton" />
- <public type="style" name="Widget.Holo.EditText.NumberPickerInputText" />
- <public type="style" name="Widget.Holo.ImageButton.NumberPickerDownButton" />
- <public type="style" name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" />
- <public type="style" name="Widget.Holo.Light.EditText.NumberPickerInputText" />
- <public type="style" name="Widget.Holo.Light.ImageButton.NumberPickerDownButton" />
<public type="style" name="Widget.CalendarView" />
<public type="style" name="Widget.Holo.CalendarView" />
<public type="style" name="Widget.Holo.Light.CalendarView" />
+ <public type="style" name="Widget.DatePicker" />
+ <public type="style" name="Widget.Holo.DatePicker" />
+ <public type="attr" name="textEditSidePasteWindowLayout" />
+ <public type="attr" name="textEditSideNoPasteWindowLayout" />
<public type="string" name="selectTextMode" />
<!-- Default icon for applications that don't specify an icon. -->
<public type="mipmap" name="sym_def_app_icon" id="0x010d0000" />
+
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 9a1b42d..46e45db 100755
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -2677,4 +2677,11 @@
<string name="sync_undo_deletes">Undo the deletes.</string>
<!-- Dialog action for when there are too many deletes that would take place and we want user confirmation, and the user wants to do nothing for now -->
<string name="sync_do_nothing">Do nothing for now.</string>
+
+ <!-- Title of the VPN service notification: VPN connected [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_title_connected"><xliff:g id="profilename" example="Home PPTP">%s</xliff:g> VPN connected</string>
+ <!-- Title of the VPN service notification: VPN disconnected [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_title_disconnected"><xliff:g id="profilename" example="Home PPTP">%s</xliff:g> VPN disconnected</string>
+ <!-- Message of the VPN service notification: Hint to reconnect VPN [CHAR LIMIT=NONE] -->
+ <string name="vpn_notification_hint_disconnected">Touch to reconnect to a VPN.</string>
</resources>
diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml
index 16c80d0..2c62730 100644
--- a/core/res/res/values/styles.xml
+++ b/core/res/res/values/styles.xml
@@ -419,6 +419,8 @@
<item name="android:textSelectHandle">?android:attr/textSelectHandle</item>
<item name="android:textEditPasteWindowLayout">?android:attr/textEditPasteWindowLayout</item>
<item name="android:textEditNoPasteWindowLayout">?android:attr/textEditNoPasteWindowLayout</item>
+ <item name="android:textEditSidePasteWindowLayout">?android:attr/textEditSidePasteWindowLayout</item>
+ <item name="android:textEditSideNoPasteWindowLayout">?android:attr/textEditSideNoPasteWindowLayout</item>
</style>
<style name="Widget.TextView.ListSeparator">
@@ -489,7 +491,16 @@
<item name="android:orientation">vertical</item>
<item name="android:fadingEdge">vertical</item>
<item name="android:fadingEdgeLength">50dip</item>
- <item name="android:solidColor">@android:color/transparent</item>
+ <item name="android:flingable">false</item>
+ </style>
+
+ <style name="Widget.TimePicker">
+ <item name="android:layout">@android:layout/time_picker</item>
+ </style>
+
+ <style name="Widget.DatePicker">
+ <item name="android:layout">@android:layout/date_picker</item>
+ <item name="android:calendarViewShown">false</item>
</style>
<style name="Widget.ImageButton.NumberPickerUpButton">
@@ -1502,6 +1513,22 @@
<item name="android:background">@android:drawable/btn_default_holo_dark</item>
</style>
+ <style name="Widget.Holo.NumberPicker" parent="Widget.NumberPicker">
+ <item name="android:solidColor">@android:color/transparent</item>
+ <item name="android:flingable">true</item>
+ <item name="android:selectionDivider">@android:drawable/numberpicker_selection_divider</item>
+ <item name="android:selectionDividerHeight">2dip</item>
+ </style>
+
+ <style name="Widget.Holo.TimePicker" parent="Widget.TimePicker">
+ <item name="android:layout">@android:layout/time_picker_holo</item>
+ </style>
+
+ <style name="Widget.Holo.DatePicker" parent="Widget.DatePicker">
+ <item name="android:layout">@android:layout/date_picker_holo</item>
+ <item name="android:calendarViewShown">true</item>
+ </style>
+
<style name="Widget.Holo.ImageButton.NumberPickerUpButton">
<item name="android:background">@null</item>
<item name="android:src">@android:drawable/numberpicker_up_btn_holo_dark</item>
@@ -1870,6 +1897,15 @@
<item name="android:weekDayTextAppearance">@android:style/TextAppearance.Holo.Light.CalendarViewWeekDayView</item>
</style>
+ <style name="Widget.Holo.Light.NumberPicker" parent="Widget.Holo.NumberPicker">
+ </style>
+
+ <style name="Widget.Holo.Light.TimePicker" parent="Widget.Holo.TimePicker">
+ </style>
+
+ <style name="Widget.Holo.Light.DatePicker" parent="Widget.Holo.DatePicker">
+ </style>
+
<style name="Widget.Holo.Light.ImageButton.NumberPickerUpButton" parent="Widget.Holo.ImageButton.NumberPickerUpButton">
<item name="android:src">@android:drawable/numberpicker_up_btn_holo_light</item>
</style>
diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml
index b257a73..e6e23aa 100644
--- a/core/res/res/values/themes.xml
+++ b/core/res/res/values/themes.xml
@@ -174,6 +174,8 @@
<item name="textSelectHandleWindowStyle">@android:style/Widget.TextSelectHandle</item>
<item name="textEditPasteWindowLayout">@android:layout/text_edit_paste_window</item>
<item name="textEditNoPasteWindowLayout">@android:layout/text_edit_no_paste_window</item>
+ <item name="textEditSidePasteWindowLayout">@android:layout/text_edit_side_paste_window</item>
+ <item name="textEditSideNoPasteWindowLayout">@android:layout/text_edit_side_no_paste_window</item>
<!-- Widget styles -->
<item name="absListViewStyle">@android:style/Widget.AbsListView</item>
@@ -290,6 +292,12 @@
<!-- CalendarView style-->
<item name="calendarViewStyle">@style/Widget.CalendarView</item>
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.DatePicker</item>
+
<item name="fastScrollThumbDrawable">@android:drawable/scrollbar_handle_accelerated_anim2</item>
<item name="fastScrollTrackDrawable">@null</item>
<item name="fastScrollPreviewBackgroundRight">@android:drawable/menu_submenu_background</item>
@@ -978,10 +986,17 @@
<item name="numberPickerUpButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerUpButton</item>
<item name="numberPickerDownButtonStyle">@style/Widget.Holo.ImageButton.NumberPickerDownButton</item>
<item name="numberPickerInputTextStyle">@style/Widget.Holo.EditText.NumberPickerInputText</item>
+ <item name="numberPickerStyle">@style/Widget.Holo.NumberPicker</item>
<!-- CalendarView style-->
<item name="calendarViewStyle">@style/Widget.Holo.CalendarView</item>
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.Holo.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.Holo.DatePicker</item>
+
<item name="fastScrollThumbDrawable">@android:drawable/fastscroll_thumb_holo</item>
<item name="fastScrollPreviewBackgroundLeft">@android:drawable/fastscroll_label_left_holo_dark</item>
<item name="fastScrollPreviewBackgroundRight">@android:drawable/fastscroll_label_right_holo_dark</item>
@@ -1003,6 +1018,7 @@
<item name="disabledAlpha">0.5</item>
<item name="backgroundDimAmount">0.6</item>
+
<!-- Text styles -->
<item name="textAppearance">@android:style/TextAppearance.Holo.Light</item>
<item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item>
@@ -1236,10 +1252,17 @@
<item name="numberPickerUpButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerUpButton</item>
<item name="numberPickerDownButtonStyle">@style/Widget.Holo.Light.ImageButton.NumberPickerDownButton</item>
<item name="numberPickerInputTextStyle">@style/Widget.Holo.Light.EditText.NumberPickerInputText</item>
+ <item name="numberPickerStyle">@style/Widget.Holo.Light.NumberPicker</item>
<!-- CalendarView style-->
<item name="calendarViewStyle">@style/Widget.Holo.Light.CalendarView</item>
+ <!-- TimePicker style -->
+ <item name="timePickerStyle">@style/Widget.Holo.Light.TimePicker</item>
+
+ <!-- DatePicker style -->
+ <item name="datePickerStyle">@style/Widget.Holo.Light.DatePicker</item>
+
<item name="fastScrollThumbDrawable">@android:drawable/fastscroll_thumb_holo</item>
<item name="fastScrollPreviewBackgroundLeft">@android:drawable/fastscroll_label_left_holo_light</item>
<item name="fastScrollPreviewBackgroundRight">@android:drawable/fastscroll_label_right_holo_light</item>
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty.xml b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
index 0a35040..fd1d5f1 100755
--- a/core/res/res/xml-xlarge/password_kbd_qwerty.xml
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2008, The Android Open Source Project
+** Copyright 2011, 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.
@@ -19,26 +19,15 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
- android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:keyWidth="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- >
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
- <Row android:rowEdgeFlags="top">
- <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="2"/>
- <Key android:keyLabel="3"/>
- <Key android:keyLabel="4"/>
- <Key android:keyLabel="5"/>
- <Key android:keyLabel="6"/>
- <Key android:keyLabel="7"/>
- <Key android:keyLabel="8"/>
- <Key android:keyLabel="9"/>
- <Key android:keyLabel="0" android:keyEdgeFlags="right"/>
- </Row>
-
- <Row>
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
<Key android:keyLabel="q" android:keyEdgeFlags="left"/>
<Key android:keyLabel="w"/>
<Key android:keyLabel="e"/>
@@ -48,12 +37,21 @@
<Key android:keyLabel="u"/>
<Key android:keyLabel="i"/>
<Key android:keyLabel="o"/>
- <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
+ <Key android:keyLabel="p"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row>
- <Key android:keyLabel="a" android:horizontalGap="5%p"
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_symbol_key"
+ android:keyWidth="11.167%p"
android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="a"/>
<Key android:keyLabel="s"/>
<Key android:keyLabel="d"/>
<Key android:keyLabel="f"/>
@@ -61,14 +59,22 @@
<Key android:keyLabel="h"/>
<Key android:keyLabel="j"/>
<Key android:keyLabel="k"/>
- <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
+ <Key android:keyLabel="l"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row>
- <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
- android:keyWidth="15%p" android:isModifier="true"
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
android:iconPreview="@drawable/sym_keyboard_feedback_shift"
- android:isSticky="true" android:keyEdgeFlags="left"/>
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
<Key android:keyLabel="z"/>
<Key android:keyLabel="x"/>
<Key android:keyLabel="c"/>
@@ -76,26 +82,26 @@
<Key android:keyLabel="b"/>
<Key android:keyLabel="n"/>
<Key android:keyLabel="m"/>
- <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
- android:keyWidth="15%p" android:keyEdgeFlags="right"
- android:iconPreview="@drawable/sym_keyboard_feedback_delete"
- android:isRepeatable="true"/>
+ <Key android:keyLabel="," />
+ <Key android:keyLabel="." />
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
- <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_symbol_key"
- android:keyWidth="20%p" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="," />
- <Key android:keyLabel="-" />
- <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
+ <Row android:keyWidth="8.042%p"
+ android:keyboardMode="@+id/mode_normal">
+ <Key android:keyLabel="/" android:horizontalGap="24.126%p"/>
+ <Key android:codes="32"
+ android:keyIcon="@drawable/sym_keyboard_space"
android:iconPreview="@drawable/sym_keyboard_feedback_space"
- android:keyWidth="20%p"/>
- <Key android:keyLabel="=" />
- <Key android:keyLabel="."
- android:keyWidth="10%p"/>
- <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
- android:iconPreview="@drawable/sym_keyboard_feedback_ok"
- android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel="'" />
+ <Key android:keyLabel="-" />
</Row>
</Keyboard>
diff --git a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
index 9e9db81..671d87f 100755
--- a/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
+++ b/core/res/res/xml-xlarge/password_kbd_qwerty_shifted.xml
@@ -2,7 +2,7 @@
<!--
/*
**
-** Copyright 2008, The Android Open Source Project
+** Copyright 2011, 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.
@@ -19,82 +19,89 @@
-->
<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
- android:keyWidth="10%p"
- android:horizontalGap="0px"
- android:verticalGap="0px"
+ android:keyWidth="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
android:keyHeight="@dimen/password_keyboard_key_height_alpha"
- >
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
- <Row android:rowEdgeFlags="top">
- <Key android:keyLabel="\@" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="\#"/>
- <Key android:keyLabel="$"/>
- <Key android:keyLabel="%"/>
- <Key android:keyLabel="&"/>
- <Key android:keyLabel="*"/>
- <Key android:keyLabel="-"/>
- <Key android:keyLabel="+"/>
- <Key android:keyLabel="("/>
- <Key android:keyLabel=")" android:keyEdgeFlags="right"/>
- </Row>
-
- <Row>
- <Key android:keyLabel="q" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="w"/>
- <Key android:keyLabel="e"/>
- <Key android:keyLabel="r"/>
- <Key android:keyLabel="t"/>
- <Key android:keyLabel="y"/>
- <Key android:keyLabel="u"/>
- <Key android:keyLabel="i"/>
- <Key android:keyLabel="o"/>
- <Key android:keyLabel="p" android:keyEdgeFlags="right"/>
- </Row>
-
- <Row>
- <Key android:keyLabel="a" android:horizontalGap="5%p"
- android:keyEdgeFlags="left"/>
- <Key android:keyLabel="s"/>
- <Key android:keyLabel="d"/>
- <Key android:keyLabel="f"/>
- <Key android:keyLabel="g"/>
- <Key android:keyLabel="h"/>
- <Key android:keyLabel="j"/>
- <Key android:keyLabel="k"/>
- <Key android:keyLabel="l" android:keyEdgeFlags="right"/>
- </Row>
-
- <Row>
- <Key android:codes="-1" android:keyIcon="@drawable/sym_keyboard_shift"
- android:keyWidth="15%p" android:isModifier="true"
- android:iconPreview="@drawable/sym_keyboard_feedback_shift"
- android:isSticky="true" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="z"/>
- <Key android:keyLabel="x"/>
- <Key android:keyLabel="c"/>
- <Key android:keyLabel="v"/>
- <Key android:keyLabel="b"/>
- <Key android:keyLabel="n"/>
- <Key android:keyLabel="m"/>
- <Key android:codes="-5" android:keyIcon="@drawable/sym_keyboard_delete"
- android:keyWidth="15%p" android:keyEdgeFlags="right"
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
+ <Key android:keyLabel="Q" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="W"/>
+ <Key android:keyLabel="E"/>
+ <Key android:keyLabel="R"/>
+ <Key android:keyLabel="T"/>
+ <Key android:keyLabel="Y"/>
+ <Key android:keyLabel="U"/>
+ <Key android:keyLabel="I"/>
+ <Key android:keyLabel="O"/>
+ <Key android:keyLabel="P"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
android:iconPreview="@drawable/sym_keyboard_feedback_delete"
- android:isRepeatable="true"/>
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
</Row>
- <Row android:keyboardMode="@+id/mode_normal" android:rowEdgeFlags="bottom">
- <Key android:codes="-2" android:keyLabel="@string/password_keyboard_label_symbol_key"
- android:keyWidth="20%p" android:keyEdgeFlags="left"/>
- <Key android:keyLabel="," />
- <Key android:keyLabel="_" />
- <Key android:codes="32" android:keyIcon="@drawable/sym_keyboard_space"
- android:iconPreview="@drawable/sym_keyboard_feedback_space"
- android:keyWidth="20%p"/>
- <Key android:keyLabel="+" />
- <Key android:keyLabel="."/>
- <Key android:codes="10" android:keyIcon="@drawable/sym_keyboard_ok"
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_symbol_key"
+ android:keyWidth="11.167%p"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="A"/>
+ <Key android:keyLabel="S"/>
+ <Key android:keyLabel="D"/>
+ <Key android:keyLabel="F"/>
+ <Key android:keyLabel="G"/>
+ <Key android:keyLabel="H"/>
+ <Key android:keyLabel="J"/>
+ <Key android:keyLabel="K"/>
+ <Key android:keyLabel="L"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
android:iconPreview="@drawable/sym_keyboard_feedback_ok"
- android:keyWidth="20%p" android:keyEdgeFlags="right"/>
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="Z"/>
+ <Key android:keyLabel="X"/>
+ <Key android:keyLabel="C"/>
+ <Key android:keyLabel="V"/>
+ <Key android:keyLabel="B"/>
+ <Key android:keyLabel="N"/>
+ <Key android:keyLabel="M"/>
+ <Key android:keyLabel="!" />
+ <Key android:keyLabel="\?" />
+ <Key android:codes="-1"
+ android:keyIcon="@drawable/sym_keyboard_shift"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:iconPreview="@drawable/sym_keyboard_feedback_shift"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p"
+ android:keyboardMode="@+id/mode_normal">
+ <Key android:keyLabel="\@" android:horizontalGap="24.126%p"/>
+ <Key android:codes="32"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel=""" />
+ <Key android:keyLabel="_" />
</Row>
</Keyboard>
diff --git a/core/res/res/xml-xlarge/password_kbd_symbols.xml b/core/res/res/xml-xlarge/password_kbd_symbols.xml
new file mode 100755
index 0000000..5ae5577
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_symbols.xml
@@ -0,0 +1,106 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+ android:keyWidth="8.272%p"
+ keyboardHeight="@dimen/password_keyboard_height"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha"
+ android:horizontalGap="0px"
+ android:verticalGap="0px">
+
+ <Row android:keyWidth="8.272%p">
+ <Key android:keyLabel="Tab"
+ android:codes="9"/>
+ <Key android:keyLabel="1" android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="2"/>
+ <Key android:keyLabel="3"/>
+ <Key android:keyLabel="4"/>
+ <Key android:keyLabel="5"/>
+ <Key android:keyLabel="6"/>
+ <Key android:keyLabel="7"/>
+ <Key android:keyLabel="8"/>
+ <Key android:keyLabel="9"/>
+ <Key android:keyLabel="0"/>
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_alpha_key"
+ android:keyWidth="11.167%p"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="\#"/>
+ <Key android:keyLabel="$"/>
+ <Key android:keyLabel="%"/>
+ <Key android:keyLabel="&"/>
+ <Key android:keyLabel="*"/>
+ <Key android:keyLabel="-"/>
+ <Key android:keyLabel="+"/>
+ <Key android:keyLabel="("/>
+ <Key android:keyLabel=")"/>
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="<"/>
+ <Key android:keyLabel=">"/>
+ <Key android:keyLabel="="/>
+ <Key android:keyLabel=":"/>
+ <Key android:keyLabel=";"/>
+ <Key android:keyLabel=","/>
+ <Key android:keyLabel="."/>
+ <Key android:keyLabel="!" />
+ <Key android:keyLabel="\?" />
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:keyLabel="\@" android:horizontalGap="16.084%p"/>
+ <Key android:keyLabel="/" />
+ <Key android:codes="32"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="37.454%p"/>
+ <Key android:keyLabel="\'" />
+ <Key android:keyLabel="-" />
+ </Row>
+
+</Keyboard>
+
diff --git a/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml b/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
new file mode 100755
index 0000000..26ade76
--- /dev/null
+++ b/core/res/res/xml-xlarge/password_kbd_symbols_shift.xml
@@ -0,0 +1,100 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+/*
+**
+** Copyright 2011, 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.
+*/
+-->
+
+<Keyboard xmlns:android="http://schemas.android.com/apk/res/android"
+ android:keyWidth="10%p"
+ android:horizontalGap="0px"
+ android:verticalGap="0px"
+ android:keyHeight="@dimen/password_keyboard_key_height_alpha">
+
+ <Row android:keyWidth="8.272%p"
+ android:rowEdgeFlags="top">
+ <Key android:keyLabel="Tab" android:codes="9"/>
+ <Key android:keyLabel="~" />
+ <Key android:keyLabel="`" />
+ <Key android:keyLabel="|" />
+ <Key android:keyLabel="•" />
+ <Key android:keyLabel="√" />
+ <Key android:keyLabel="π" />
+ <Key android:keyLabel="÷" />
+ <Key android:keyLabel="×" />
+ <Key android:keyLabel="§" />
+ <Key android:keyLabel="Δ" />
+ <Key android:keyIcon="@drawable/sym_keyboard_delete"
+ android:codes="-5"
+ android:keyWidth="9.331%p"
+ android:iconPreview="@drawable/sym_keyboard_feedback_delete"
+ android:isRepeatable="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.157%p">
+ <Key android:codes="-2"
+ android:keyLabel="@string/password_keyboard_label_alpha_key"
+ android:keyWidth="11.167%p"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="£" />
+ <Key android:keyLabel="¢" />
+ <Key android:keyLabel="€" />
+ <Key android:keyLabel="¥" />
+ <Key android:keyLabel="^"/>
+ <Key android:keyLabel="°" />
+ <Key android:keyLabel="±" />
+ <Key android:keyLabel="{" />
+ <Key android:keyLabel="}" />
+ <Key android:codes="10"
+ android:keyIcon="@drawable/sym_keyboard_ok"
+ android:iconPreview="@drawable/sym_keyboard_feedback_ok"
+ android:keyWidth="15.750%p"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="15.192%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="left"/>
+ <Key android:keyLabel="\\" />
+ <Key android:keyLabel="©" />
+ <Key android:keyLabel="®" />
+ <Key android:keyLabel="™" />
+ <Key android:keyLabel="℅" />
+ <Key android:keyLabel="[" />
+ <Key android:keyLabel="]" />
+ <Key android:keyLabel="¡" />
+ <Key android:keyLabel="¿" />
+ <Key android:codes="-1"
+ android:keyLabel="@string/password_keyboard_label_alt_key"
+ android:keyWidth="12.530%p"
+ android:isModifier="true"
+ android:isSticky="true"
+ android:keyEdgeFlags="right"/>
+ </Row>
+
+ <!-- This row is intentionally not marked as a bottom row -->
+ <Row android:keyWidth="8.042%p">
+ <Key android:codes="32" android:horizontalGap="32.168%p"
+ android:keyIcon="@drawable/sym_keyboard_space"
+ android:iconPreview="@drawable/sym_keyboard_feedback_space"
+ android:keyWidth="37.454%p"/>
+ </Row>
+</Keyboard>
diff --git a/docs/html/guide/developing/device.jd b/docs/html/guide/developing/device.jd
index 4bed963c..657f549 100644
--- a/docs/html/guide/developing/device.jd
+++ b/docs/html/guide/developing/device.jd
@@ -13,8 +13,12 @@
</ol>
<h2>See also</h2>
<ol>
+ <li><a href="{@docRoot}sdk/win-usb.html">Google USB Driver</a></li>
+ <li><a href="{@docRoot}sdk/oem-usb.html">OEM USB Drivers</a></li>
<li><a
- href="{@docRoot}sdk/win-usb.html">USB Driver for Windows</a></li>
+href="{@docRoot}guide/developing/eclipse-adt.html">Developing in Eclipse, with ADT</a></li>
+ <li><a
+href="{@docRoot}guide/developing/other-ide.html">Developing in other IDEs</a></li>
</ol>
</div>
</div>
@@ -66,8 +70,10 @@
<li>Setup your system to detect your device.
<ul>
<li>If you're developing on Windows, you need to install a USB driver
- for adb. See the <a href="{@docRoot}sdk/win-usb.html">Windows USB
- Driver</a> documentation.</li>
+ for adb. If you're using an Android Developer Phone (ADP), Nexus One, or Nexus S,
+ see the <a href="{@docRoot}sdk/win-usb.html">Google Windows USB
+ Driver</a>. Otherwise, you can find a link to the appropriate OEM driver in the
+ <a href="{@docRoot}sdk/oem-usb.html">OEM USB Drivers</a> document.</li>
<li>If you're developing on Mac OS X, it just works. Skip this step.</li>
<li>If you're developing on Ubuntu Linux, you need to add a rules file
that contains a USB configuration for each type of device you want to use for
diff --git a/docs/html/guide/guide_toc.cs b/docs/html/guide/guide_toc.cs
index 67f1fec..270d153 100644
--- a/docs/html/guide/guide_toc.cs
+++ b/docs/html/guide/guide_toc.cs
@@ -213,6 +213,9 @@
<li><a href="<?cs var:toroot ?>guide/topics/graphics/opengl.html">
<span class="en">3D with OpenGL</span>
</a></li>
+ <li><a href="<?cs var:toroot ?>guide/topics/graphics/animation.html">
+ <span class="en">Animation</span>
+ </a><span class="new">new!</span></li>
</ul>
</li>
<li><a href="<?cs var:toroot ?>guide/topics/media/index.html">
diff --git a/docs/html/guide/topics/graphics/2d-graphics.jd b/docs/html/guide/topics/graphics/2d-graphics.jd
index 05f4023..6594568 100644
--- a/docs/html/guide/topics/graphics/2d-graphics.jd
+++ b/docs/html/guide/topics/graphics/2d-graphics.jd
@@ -17,8 +17,6 @@
<li><a href="#shape-drawable">Shape Drawable</a></li>
<!-- <li><a href="#state-list">StateListDrawable</a></li> -->
<li><a href="#nine-patch">Nine-patch</a></li>
- <li><a href="#tween-animation">Tween Animation</a></li>
- <li><a href="#frame-animation">Frame Animation</a></li>
</ol>
</div>
</div>
@@ -328,172 +326,4 @@
stretches to accommodate it.
</p>
-<img src="{@docRoot}images/ninepatch_examples.png" alt=""/>
-
-
-<h2 id="tween-animation">Tween Animation</h2>
-
-<p>A tween animation can perform a series of simple transformations (position, size, rotation, and transparency) on
-the contents of a View object. So, if you have a TextView object, you can move, rotate, grow, or shrink the text.
-If it has a background image, the background image will be transformed along with the text.
-The {@link android.view.animation animation package} provides all the classes used in a tween animation.</p>
-
-<p>A sequence of animation instructions defines the tween animation, defined by either XML or Android code.
-Like defining a layout, an XML file is recommended because it's more readable, reusable, and swappable
-than hard-coding the animation. In the example below, we use XML. (To learn more about defining an animation
-in your application code, instead of XML, refer to the
-{@link android.view.animation.AnimationSet} class and other {@link android.view.animation.Animation} subclasses.)</p>
-
-<p>The animation instructions define the transformations that you want to occur, when they will occur,
-and how long they should take to apply. Transformations can be sequential or simultaneous —
-for example, you can have the contents of a TextView move from left to right, and then
-rotate 180 degrees, or you can have the text move and rotate simultaneously. Each transformation
-takes a set of parameters specific for that transformation (starting size and ending size
-for size change, starting angle and ending angle for rotation, and so on), and
-also a set of common parameters (for instance, start time and duration). To make
-several transformations happen simultaneously, give them the same start time;
-to make them sequential, calculate the start time plus the duration of the preceding transformation.
-</p>
-
-<p>The animation XML file belongs in the <code>res/anim/</code> directory of your Android project.
-The file must have a single root element: this will be either a single <code><alpha></code>,
-<code><scale></code>, <code><translate></code>, <code><rotate></code>, interpolator element,
-or <code><set></code> element that holds groups of these elements (which may include another
-<code><set></code>). By default, all animation instructions are applied simultaneously.
-To make them occur sequentially, you must specify the <code>startOffset</code> attribute, as shown in the example below.
-</p>
-
-<p>The following XML from one of the ApiDemos is used to stretch,
-then simultaneously spin and rotate a View object.
-</p>
-<pre>
-<set android:shareInterpolator="false">
- <scale
- android:interpolator="@android:anim/accelerate_decelerate_interpolator"
- android:fromXScale="1.0"
- android:toXScale="1.4"
- android:fromYScale="1.0"
- android:toYScale="0.6"
- android:pivotX="50%"
- android:pivotY="50%"
- android:fillAfter="false"
- android:duration="700" />
- <set android:interpolator="@android:anim/decelerate_interpolator">
- <scale
- android:fromXScale="1.4"
- android:toXScale="0.0"
- android:fromYScale="0.6"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="700"
- android:duration="400"
- android:fillBefore="false" />
- <rotate
- android:fromDegrees="0"
- android:toDegrees="-45"
- android:toYScale="0.0"
- android:pivotX="50%"
- android:pivotY="50%"
- android:startOffset="700"
- android:duration="400" />
- </set>
-</set>
-</pre>
-<p>Screen coordinates (not used in this example) are (0,0) at the upper left hand corner,
-and increase as you go down and to the right.</p>
-
-<p>Some values, such as pivotX, can be specified relative to the object itself or relative to the parent.
-Be sure to use the proper format for what you want ("50" for 50% relative to the parent, or "50%" for 50%
-relative to itself).</p>
-
-<p>You can determine how a transformation is applied over time by assigning an
-{@link android.view.animation.Interpolator}. Android includes
-several Interpolator subclasses that specify various speed curves: for instance,
-{@link android.view.animation.AccelerateInterpolator} tells
-a transformation to start slow and speed up. Each one has an attribute value that can be applied in the XML.</p>
-
-<p>With this XML saved as <code>hyperspace_jump.xml</code> in the <code>res/anim/</code> directory of the
-project, the following Java code will reference it and apply it to an {@link android.widget.ImageView} object
-from the layout.
-</p>
-<pre>
-ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
-Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
-spaceshipImage.startAnimation(hyperspaceJumpAnimation);
-</pre>
-
-<p>As an alternative to <code>startAnimation()</code>, you can define a starting time for the animation with
-<code>{@link android.view.animation.Animation#setStartTime(long) Animation.setStartTime()}</code>,
-then assign the animation to the View with
-<code>{@link android.view.View#setAnimation(android.view.animation.Animation) View.setAnimation()}</code>.
-</p>
-
-<p>For more information on the XML syntax, available tags and attributes, see <a
-href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
-
-<p class="note"><strong>Note:</strong> Regardless of how your animation may move or resize, the bounds of the
-View that holds your animation will not automatically adjust to accommodate it. Even so, the animation will still
-be drawn beyond the bounds of its View and will not be clipped. However, clipping <em>will occur</em>
-if the animation exceeds the bounds of the parent View.</p>
-
-
-<h2 id="frame-animation">Frame Animation</h2>
-
-<p>This is a traditional animation in the sense that it is created with a sequence of different
-images, played in order, like a roll of film. The {@link android.graphics.drawable.AnimationDrawable}
-class is the basis for frame animations.</p>
-
-<p>While you can define the frames of an animation in your code, using the
-{@link android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished with a single XML
-file that lists the frames that compose the animation. Like the tween animation above, the XML file for this kind
-of animation belongs in the <code>res/drawable/</code> directory of your Android project. In this case,
-the instructions are the order and duration for each frame of the animation.</p>
-
-<p>The XML file consists of an <code><animation-list></code> element as the root node and a series
-of child <code><item></code> nodes that each define a frame: a drawable resource for the frame and the frame duration.
-Here's an example XML file for a frame-by-frame animation:</p>
-<pre>
-<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
- android:oneshot="true">
- <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
- <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
- <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
-</animation-list>
-</pre>
-
-<p>This animation runs for just three frames. By setting the <code>android:oneshot</code> attribute of the
-list to <var>true</var>, it will cycle just once then stop and hold on the last frame. If it is set <var>false</var> then
-the animation will loop. With this XML saved as <code>rocket_thrust.xml</code> in the <code>res/drawable/</code> directory
-of the project, it can be added as the background image to a View and then called to play. Here's an example Activity,
-in which the animation is added to an {@link android.widget.ImageView} and then animated when the screen is touched:</p>
-<pre>
-AnimationDrawable rocketAnimation;
-
-public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
- rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
- rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
-}
-
-public boolean onTouchEvent(MotionEvent event) {
- if (event.getAction() == MotionEvent.ACTION_DOWN) {
- rocketAnimation.start();
- return true;
- }
- return super.onTouchEvent(event);
-}
-</pre>
-<p>It's important to note that the <code>start()</code> method called on the AnimationDrawable cannot be
-called during the <code>onCreate()</code> method of your Activity, because the AnimationDrawable is not yet fully attached
-to the window. If you want to play the animation immediately, without
-requiring interaction, then you might want to call it from the
-<code>{@link android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code> method in
-your Activity, which will get called when Android brings your window into focus.</p>
-
-<p>For more information on the XML syntax, available tags and attributes, see <a
-href="{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
-
+<img src="{@docRoot}images/ninepatch_examples.png" alt=""/>
\ No newline at end of file
diff --git a/docs/html/guide/topics/graphics/animation.jd b/docs/html/guide/topics/graphics/animation.jd
new file mode 100644
index 0000000..c977d51
--- /dev/null
+++ b/docs/html/guide/topics/graphics/animation.jd
@@ -0,0 +1,839 @@
+page.title=Animation
+@jd:body
+ <div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+
+ <ol>
+ <li>
+ <a href="#property-animation">Property Animation</a>
+
+ <ol>
+ <li><a href="#value-animator">Animating with ValueAnimator</a></li>
+
+ <li><a href="#object-animator">Animating with ObjectAnimator</a></li>
+
+ <li><a href="#type-evaluator">Using the TypeEvaluator</a></li>
+
+ <li><a href="#interpolators">Using interpolators</a></li>
+
+ <li><a href="#keyframes">Specifying keyframes</a></li>
+
+ <li><a href="#choreography">Choreographing multiple animations with AnimatorSet</a></li>
+
+ <li><a href="#declaring-xml">Declaring animations in XML</a></li>
+ </ol>
+ </li>
+
+ <li>
+ <a href="#view-animation">View Animation</a>
+
+ <ol>
+ <li><a href="#tween-animation">Tween animation</a></li>
+
+ <li><a href="#frame-animation">Frame animation</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>Key classes</h2>
+
+ <ol>
+ <li><code><a href=
+ "/reference/android/animation/ValueAnimator.html">ValueAnimator</a></code></li>
+
+ <li><code><a href=
+ "/reference/android/animation/ObjectAnimator.html">ObjectAnimator</a></code></li>
+
+ <li><code><a href=
+ "/reference/android/animation/TypeEvaluator.html">TypeEvaluator</a></code></li>
+ </ol>
+
+ <h2>Related samples</h2>
+
+ <ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">API Demos</a></li>
+ </ol>
+
+ </div>
+ </div>
+
+ <p>The Android system provides a flexible animation system that allows you to animate
+ almost anything, either programmatically or declaratively with XML. There are two
+ animation systems that you can choose from: <a href="property-animation">property
+ animation</a> and <a href="#view-animation">view animation</a>. You can use whichever
+ system that matches your needs, but use only one system for each object that you
+ are animating.</p>
+
+ <h2 id="property-animation">Property Animation</h2>
+
+ <p>Introduced in Android 3.0, the property animation system allows you to animate
+ object properties of any type. <code>int</code>, <code>float</code>,
+ and hexadecimal color values are supported by default. You can animate any other type by telling the
+ system how to calculate the values for that given type.</p>
+
+ <p>The property animation system allows you to define many aspects of an animation,
+ such as:</p>
+
+ <ul>
+ <li>Duration</li>
+
+ <li>Repeat amount and behavior</li>
+
+ <li>Type of time interpolation</li>
+
+ <li>Animator sets to play animations together, sequentially, or after specified
+ delays</li>
+
+ <li>Frame refresh delay</li>
+
+ </ul>
+
+ <p>Most of the property animation system's features can be found in
+ {@link android.animation android.animation}. Because the
+ <a href="#view-animation>view animation</a> system already
+ defines many interpolators in {@link android.view.animation android.view.animation},
+ you will use those to define your animation's interpolation in the property animation
+ system as well.
+ </p>
+
+ <p>The following items are the main components of the property animation system:</p>
+
+ <dl>
+ <dt><strong>Animators</strong></dt>
+
+ <dd>
+ The {@link android.animation.Animator} class provides the basic structure for
+ creating animations. You normally do not use this class directly as it only provides
+ minimal functionality that must be extended to fully support animating values.
+ The following subclasses extend {@link android.animation.Animator}, which you might find more useful:
+
+ <ul>
+ <li>{@link android.animation.ValueAnimator} is the main timing engine for
+ property animation and computes the values for the property to be animated.
+ {@link android.animation.ValueAnimator} only computes the animation values and is
+ not aware of the specific object and property that is being animated or what the
+ values might be used for. You must listen for updates to values calculated by the
+ {@link android.animation.ValueAnimator} and process the data with your own logic.
+ See the section about <a href="#value-animator">Animating with ValueAnimator</a>
+ for more information.</li>
+
+ <li>{@link android.animation.ObjectAnimator} is a subclass of {@link
+ android.animation.ValueAnimator} and allows you to set a target object and object
+ property to animate. This class is aware of the object and property to be
+ animated, and updates the property accordingly when it computes a new value for
+ the animation. See the section about <a href="#object-animator">
+ Animating with ObjectAnimator</a> for more information.</li>
+
+ <li>{@link android.animation.AnimatorSet} provides a mechanism to group
+ animations together so that they are rendered in relation to one another. You can
+ set animations to play together, sequentially, or after a specified delay.
+ See the section about <a href="#choreography">
+ Choreographing multiple animations with Animator Sets</a> for more information.</li>
+ </ul>
+ </dd>
+
+ <dt><strong>Evaluators</strong></dt>
+
+ <dd>
+ <p>If you are animating an object property that is <em>not</em> an <code>int</code>,
+ <code>float</code>, or color, implement the {@link android.animation.TypeEvaluator}
+ interface to specify how to compute the object property's animated values. You give
+ a {@link android.animation.TypeEvaluator} the timing data that is provided by an
+ {@link android.animation.Animator} class, the animation's start and end value, and
+ provide logic that computes the animated values of the property based on this data.</p>
+
+ <p>You can also specify a custom {@link android.animation.TypeEvaluator} for
+ <code>int</code>, <code>float</code>, and color values as well, if you want to
+ process those types differently than the default behavior.</p>
+
+ <p>See <a href="#type-evaluator">Using a TypeEvaluator</a> for more information on
+ how to write a custom evaluator.</p>
+ </dd>
+
+ <dt><strong>Interpolators</strong></dt>
+
+ <dd>
+ <p>A time interpolator defines how specific values in an animation are calculated
+ as a function of time. For example, you can specify animations to happen linearly
+ across the whole animation, meaning the animation moves evenly the entire time, or
+ you can specify animations to use non-linear time, for example, using acceleration
+ or deceleration at the beginning or end of the animation.</p>
+
+ <p>The Android system provides a set of common interpolators in
+ {@link android.view.animation android.view.animation}. If none of these suits your needs, you
+ can implement the {@link android.animation.TimeInterpolator} interface and create
+ your own. See <a href="#interpolators">Interpolators</a> for more information on
+ how to write a custom interpolator.</p>
+ </dd>
+ </dl>
+
+
+ <p>The <code>com.example.android.apis.animation</code> package in the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/index.html">
+ API Demos</a> sample project also provides a good overview and many examples on how to
+ use the property animation system.</p>
+
+
+ <h3>How the property animation system calculates animated values</h3>
+
+ <p>When you call {@link android.animation.ValueAnimator#start start()} to begin an animation,
+ the {@link android.animation.ValueAnimator} calculates
+ an <em>elapsed fraction</em> between 0 and 1, based on the duration of the animation
+ and how much time has elapsed. The elapsed fraction represents the percentage of time
+ that the animation has completed, 0 meaning 0% and 1 meaning 100%. The Animator then
+ calls the {@link android.animation.TimeInterpolator} that is currently set,
+ to calculate an <em>eased fraction</em>,
+ which is a modified value of the elapsed fraction that takes into account the interpolator that
+ is set (time interpolation is often referred to as <em>easing</em>). The eased fraction
+ is the final value that is used to animate the property.</p>
+
+ <p>Once the eased fraction is calculated, {@link android.animation.ValueAnimator} calls
+ the appropriate {@link android.animation.TypeEvaluator} to calculate the final value of
+ the property that you are animating, based on the eased fraction, the starting value,
+ and ending value of the animation.</p>
+
+ <h3 id="value-animator">Animating with ValueAnimator</h3>
+
+ <p>The {@link android.animation.ValueAnimator} class lets you animate values of some
+ type for the duration of an animation by specifying a set of <code>int</code>,
+ <code>float</code>, or color values to animate over and the duration of the animation.
+ You obtain a {@link android.animation.ValueAnimator} by calling one of its factory
+ methods: {@link android.animation.ValueAnimator#ofInt ofInt()},
+ {@link android.animation.ValueAnimator#ofFloat ofFloat()},
+ or {@link android.animation.ValueAnimator#ofObject ofObject()}. For example:</p>
+
+ <pre>ValueAnimator animation = ValueAnimator.ofFloat(0f, 1f);
+animation.setDuration(1000);
+animation.start();
+</pre>
+
+ <p>In this code, the {@link android.animation.ValueAnimator} starts
+ calculating the values of the animation, between 0 and 1, for
+ a duration of 1000 ms, when the <code>start()</code> method runs.</p>
+
+ <p>You can also specify a custom type to animate by doing the following:</p>
+
+ <pre>ValueAnimator animation = ValueAnimator.ofObject(new MyTypeEvaluator(), startPropertyValue, endPropertyValue);
+animation.setDuration(1000);
+animation.start();
+</pre>
+
+ <p>In this code, the {@link android.animation.ValueAnimator} starts
+ calculating the values of the animation, between <code>startPropertyValue</code> and
+ <code>endPropertyValue</code> using the logic supplied by <code>MyTypeEvaluator</code>
+ for a duration of 1000 ms, when the {@link android.animation.ValueAnimator#start start()}
+ method runs.</p>
+
+ <p>The previous code snippets, however, do not affect an object, because the {@link
+ android.animation.ValueAnimator} does not operate on objects or properties directly. To
+ use the results of a {@link android.animation.ValueAnimator}, you must define listeners
+ in the {@link android.animation.ValueAnimator} to appropriately handle important events
+ during the animation's lifespan, such as frame updates. You can implement the following
+ interfaces to create listeners for {@link android.animation.ValueAnimator}:</p>
+
+ <ul>
+ <li>{@link android.animation.Animator.AnimatorListener}
+
+ <ul>
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationStart
+ onAnimationStart()} - Called when the animation starts</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationEnd
+ onAnimationEnd()} - Called when the animation ends.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationRepeat
+ onAnimationRepeat()} - Called when the animation repeats itself.</li>
+
+ <li>{@link android.animation.Animator.AnimatorListener#onAnimationCancel
+ onAnimationCancel()} - Called when the animation is canceled.</li>
+ </ul>
+ </li>
+
+ <li>{@link android.animation.ValueAnimator.AnimatorUpdateListener}
+
+ <ul>
+ <li>
+ <p>{@link
+ android.animation.ValueAnimator.AnimatorUpdateListener#onAnimationUpdate
+ onAnimationUpdate()} - called on every frame of the animation.
+ Listen to this event to use the calculated values generated by
+ {@link android.animation.ValueAnimator} during an animation. To use the value,
+ query the {@link android.animation.ValueAnimator} object passed into the event
+ to get the current animated value with the
+ {@link android.animation.ValueAnimator#getAnimatedValue getAnimatedValue()} method.</p>
+
+ <p>If you are animating your own custom object (not View objects), this
+ callback must also call the {@link android.view.View#invalidate invalidate()}
+ method to force a redraw of the screen. If you are animating View objects,
+ {@link android.view.View#invalidate invalidate()} is automatically called when
+ a property of the View is changed.</p>
+ </li>
+ </ul>
+
+ <p>You can extend the {@link android.animation.AnimatorListenerAdapter} class
+ instead of implementing the {@link android.animation.Animator.AnimatorListener}
+ interface, if you do not want to implement all of the methods of the {@link
+ android.animation.Animator.AnimatorListener} interface. The {@link
+ android.animation.AnimatorListenerAdapter} class provides empty implementations of the
+ methods that you can choose to override.</p>
+ </li>
+ </ul>
+
+ <p>For example, the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample in the API demos creates an {@link
+ android.animation.AnimatorListenerAdapter} for just the {@link
+ android.animation.Animator.AnimatorListener#onAnimationEnd onAnimationEnd()}
+ callback:</p>
+ <pre>ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+fadeAnim.addListener(new AnimatorListenerAdapter() {
+public void onAnimationEnd(Animator animation) {
+ balls.remove(((ObjectAnimator)animation).getTarget());
+}
+
+</pre>
+
+ <h3 id="object-animator">Animating with ObjectAnimator</h3>
+
+ <p>The {@link android.animation.ObjectAnimator} is a subclass of the {@link
+ android.animation.ValueAnimator} (discussed in the previous section)
+ and combines the timing engine and value computation
+ of {@link android.animation.ValueAnimator} with the ability to animate a named property
+ of a target object. This makes animating any object much easier, as you no longer need
+ to implement the {@link android.animation.ValueAnimator.AnimatorUpdateListener}, because
+ the animated property updates automatically.</p>
+
+ <p>Instantiating an {@link android.animation.ObjectAnimator} is similar to a {@link
+ android.animation.ValueAnimator}, but you also specify the object and that object's
+ property (as a String) that you want to animate:</p>
+ <pre>
+ObjectAnimator anim = ObjectAnimator.ofFloat(foo, "alpha", 0f, 1f);
+anim.setDuration(1000);
+anim.start();
+</pre>
+
+ <p>To have the {@link android.animation.ObjectAnimator} update properties correctly,
+ you must do the following:</p>
+
+ <ul>
+ <li>The object property that you are animating must have a setter function in the
+ form of <code>set<propertyName>()</code>. Because the {@link
+ android.animation.ObjectAnimator} automatically updates the property during
+ animation, it must be able to access the property with this setter method. For
+ example, if the property name is <code>foo</code>, you need to have a
+ <code>setFoo()</code> method. If this setter method does not exist, you have three
+ options:
+
+ <ul>
+ <li>Add the setter method to the class if you have the rights to do so.</li>
+
+ <li>Use a wrapper class that you have rights to change and have that wrapper
+ receive the value with a valid setter method and forward it to the original
+ object.</li>
+
+ <li>Use {@link android.animation.ValueAnimator} instead.</li>
+ </ul>
+ </li>
+
+ <li>If you specify only one value for the <code>values...</code> parameter,
+ in one of the {@link android.animation.ObjectAnimator} factory methods, it is assumed to be
+ the ending value of the animation. Therefore, the object property that you are
+ animating must have a getter function that is used to obtain the starting value of
+ the animation. The getter function must be in the form of
+ <code>get<propertyName>()</code>. For example, if the property name is
+ <code>foo</code>, you need to have a <code>getFoo()</code> method.</li>
+
+ <li>The getter (if needed) and setter methods of the property that you are animating must
+ return the same type as the starting and ending values that you specify to {@link
+ android.animation.ObjectAnimator}. For example, you must have
+ <code>targetObject.setPropName(float)</code> and
+ <code>targetObject.getPropName(float)</code> if you construct the following {@link
+ android.animation.ObjectAnimator}:
+ <pre>ObjectAnimator.ofFloat(targetObject, "propName", 1f)</pre>
+ </li>
+ </ul>
+
+ <h3 id="type-evaluator">Using the TypeEvaluator</h3>
+
+ <p>If you want to animate a type that is unknown to the Android system,
+ you can create your own evaluator by implementing the {@link
+ android.animation.TypeEvaluator} interface. The types that are known by the Android
+ system are <code>int</code>, <code>float</code>, or a color, which are supported by the
+ {@link android.animation.IntEvaluator}, {@link android.animation.FloatEvaluator}, and
+ {@link android.animation.ArgbEvaluator} type evaluators.</p>
+
+ <p>There is only one method to implement in the {@link android.animation.TypeEvaluator}
+ interface, the {@link android.animation.TypeEvaluator#evaluate evaluate()} method.
+ This allows the animator that you are using to return an
+ appropriate value for your animated property at the current point of the animation. The
+ {@link android.animation.FloatEvaluator} class demonstrates how to do this:</p>
+ <pre>
+public class FloatEvaluator implements TypeEvaluator {
+
+ public Object evaluate(float fraction, Object startValue, Object endValue) {
+ float startFloat = ((Number) startValue).floatValue();
+ return startFloat + fraction * (((Number) endValue).floatValue() - startFloat);
+ }
+}
+</pre>
+
+ <p class="note"><strong>Note:</strong> When {@link android.animation.ValueAnimator} (or
+ {@link android.animation.ObjectAnimator}) runs, it calculates a current elapsed
+ fraction of the animation (a value between 0 and 1) and then calculates an eased
+ version of that depending on what interpolator that you are using. The eased fraction
+ is what your {@link android.animation.TypeEvaluator} receives through the <code>fraction</code>
+ parameter, so you do not have to take into account the interpolator
+ when calculating animated values.</p>
+
+ <h3 id="interpolators">Using Interpolators</h3>
+
+ <p>An interpolator define how specific values in an animation are
+ calculated as a function of time. For example, you can specify animations to happen
+ linearly across the whole animation, meaning the animation moves evenly the entire
+ time, or you can specify animations to use non-linear time, for example, using
+ acceleration or deceleration at the beginning or end of the animation.</p>
+
+ <p>Interpolators in the animation system receive a fraction from Animators that represent the elapsed time
+ of the animation. Interpolators modify this fraction to coincide with the type of
+ animation that it aims to provide. The Android system provides a set of common
+ interpolators in the {@link android.view.animation android.view.animation package}. If
+ none of these suit your needs, you can implement the {@link
+ android.animation.TimeInterpolator} interface and create your own.</p>
+
+ <p>As an example, how the default interpolator {@link
+ android.view.animation.AccelerateDecelerateInterpolator} and the {@link
+ android.view.animation.LinearInterpolator} calculate eased fractions are compared below. The {@link
+ android.view.animation.LinearInterpolator} has no effect on the elapsed fraction,
+ because a linear interpolation is calculated the same way as the elapsed fraction. The
+ {@link android.view.animation.AccelerateDecelerateInterpolator} accelerates into the
+ animation and decelerates out of it. The following methods define the logic for these
+ interpolators:</p>
+
+ <p><strong>AccelerateDecelerateInterpolator</strong></p>
+ <pre>public float getInterpolation(float input) {
+ return (float)(Math.cos((input + 1) * Math.PI) / 2.0f) + 0.5f;
+ }</pre>
+
+ <p><strong>LinearInterpolator</strong></p>
+ <pre>public float getInterpolation(float input) {
+ return input;
+ }</pre>
+
+ <p>The following table represents the approximate values that are calculated by these
+ interpolators for an animation that lasts 1000ms:</p>
+
+ <table>
+ <tr>
+ <th>ms elapsed</th>
+
+ <th>Elapsed fraction/Eased fraction (Linear)</th>
+
+ <th>Eased fraction (Accelerate/Decelerate)</th>
+ </tr>
+
+ <tr>
+ <td>0</td>
+
+ <td>0</td>
+
+ <td>0</td>
+ </tr>
+
+ <tr>
+ <td>200</td>
+
+ <td>.2</td>
+
+ <td>.1</td>
+ </tr>
+
+ <tr>
+ <td>400</td>
+
+ <td>.4</td>
+
+ <td>.345</td>
+ </tr>
+
+ <tr>
+ <td>600</td>
+
+ <td>.6</td>
+
+ <td>.8</td>
+ </tr>
+
+ <tr>
+ <td>800</td>
+
+ <td>.8</td>
+
+ <td>.9</td>
+ </tr>
+
+ <tr>
+ <td>1000</td>
+
+ <td>1</td>
+
+ <td>1</td>
+ </tr>
+ </table>
+
+ <p>As the table shows, the {@link android.view.animation.LinearInterpolator} changes
+ the values at the same speed, .2 for every 200ms that passes. The {@link
+ android.view.animation.AccelerateDecelerateInterpolator} changes the values faster than
+ {@link android.view.animation.LinearInterpolator} between 200ms and 600ms and slower
+ between 600ms and 1000ms.</p>
+
+ <h3 id="keyframes">Specifying Keyframes</h3>
+
+ <p>A {@link android.animation.Keyframe} object consists of a time/value pair that lets
+ you define a specific state at a specific time of an animation. Each keyframe can also
+ have its own interpolator to control the behavior of the animation in the interval
+ between the previous keyframe's time and the time of this keyframe.</p>
+
+ <p>To instantiate a {@link android.animation.Keyframe} object, you must use one of the
+ factory methods, {@link android.animation.Keyframe#ofInt ofInt()}, {@link
+ android.animation.Keyframe#ofFloat ofFloat()}, or {@link
+ android.animation.Keyframe#ofObject ofObject()} to obtain the appropriate type of
+ {@link android.animation.Keyframe}. You then call the {@link
+ android.animation.PropertyValuesHolder#ofKeyframe ofKeyframe()} factory method to
+ obtain a {@link android.animation.PropertyValuesHolder} object. Once you have the
+ object, you can obtain an animator by passing in the {@link
+ android.animation.PropertyValuesHolder} object and the object to animate. The following
+ code snippet demonstrates how to do this:</p>
+ <pre>
+ Keyframe kf0 = Keyframe.ofFloat(0f, 0f);
+ Keyframe kf1 = Keyframe.ofFloat(.9999f, 360f);
+ Keyframe kf2 = Keyframe.ofFloat(1f, 0f);
+ PropertyValuesHolder pvhRotation = PropertyValuesHolder.ofKeyframe("rotation", kf0, kf1, kf2);
+ ObjectAnimator rotationAnim = ObjectAnimator.ofPropertyValuesHolder(target, pvhRotation)
+ rotationAnim.setDuration(5000ms);
+
+</pre>For a more complete example on how to use keyframes, see the <a href=
+"{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/MultiPropertyAnimation.html">
+ MultiPropertyAnimation</a> sample in APIDemos.
+
+ <h3 id="choreography">Choreographing multiple animations with Animator Sets</h3>
+
+ <p>In many cases, you want to play an animation that depends on when another animation
+ starts or finishes. The Android system lets you bundle animations together into an
+ {@link android.animation.AnimatorSet}, so that you can specify whether to start animations
+ simultaneously, sequentially, or after a specified delay. You can also nest {@link
+ android.animation.AnimatorSet} objects within each other.</p>
+
+ <p>The following sample code taken from the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample (modified for simplicity) plays the following
+ {@link android.animation.Animator} objects in the following manner:</p>
+
+ <ol>
+ <li>Plays <code>bounceAnim</code>.</li>
+
+ <li>Plays <code>squashAnim1</code>, <code>squashAnim2</code>,
+ <code>stretchAnim1</code>, and <code>stretchAnim2</code> at the same time.</li>
+
+ <li>Plays <code>bounceBackAnim</code>.</li>
+
+ <li>Plays <code>fadeAnim</code>.</li>
+ </ol>
+ <pre>AnimatorSet bouncer = new AnimatorSet();
+bouncer.play(bounceAnim).before(squashAnim1);
+bouncer.play(squashAnim1).with(squashAnim2);
+bouncer.play(squashAnim1).with(stretchAnim1);
+bouncer.play(squashAnim1).with(stretchAnim2);
+bouncer.play(bounceBackAnim).after(stretchAnim2);
+ValueAnimator fadeAnim = ObjectAnimator.ofFloat(newBall, "alpha", 1f, 0f);
+fadeAnim.setDuration(250);
+AnimatorSet animatorSet = new AnimatorSet();
+animatorSet.play(bouncer).before(fadeAnim);
+animatorSet.start();
+</pre>
+
+ <p>For a more complete example on how to use animator sets, see the <a href=
+ "{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/animation/BouncingBalls.html">
+ Bouncing Balls</a> sample in APIDemos.</p>
+
+ <h3 id="declaring-xml">Declaring animations in XML</h3>
+
+ <p>As with <a href="view-animation">view animation</a>, you can declare property animations with
+ XML instead of doing it programmatically. The following Android classes also have XML
+ declaration support with the following XML tags:</p>
+
+ <ul>
+ <li>{@link android.animation.ValueAnimator} - <code><animator></code></li>
+
+ <li>{@link android.animation.ObjectAnimator} - <code><objectAnimator></code></li>
+
+ <li>{@link android.animation.AnimatorSet} - <code><AnimatorSet></code></li>
+ </ul>
+
+ <p>Both <code><animator></code> ({@link android.animation.ValueAnimator}) and
+ <code><objectAnimator></code> ({@link android.animation.ObjectAnimator}) have the
+ following attributes:</p>
+
+ <dl>
+ <dt><code>android:duration</code></dt>
+ <dd>The number of milliseconds that the animation runs.</dd>
+
+ <dt><code>android:valueFrom</code> and <code>android:valueTo</code></dt>
+ <dd>The values being animated
+ between. These are restricted to numbers (<code>float</code> or <code>int</code>) in
+ XML. They can be <code>float</code>, <code>int</code>, or any kind of
+ <code>Object</code> when creating animations programmatically.</dd>
+
+ <dt><code>android:valueType</code></dt>
+ <dd>Set to either <code>"floatType"</code> or <code>"intType"</code>.</dd>
+
+ <dt><code>android:startDelay</code></dt>
+ <dd>The delay, in milliseconds, before the animation begins
+ playing (after calling {@link android.animation.ValueAnimator#start start()}).</dd>
+
+ <dt><code>android:repeatCount</code></dt>
+ <dd>How many times to repeat an animation. Set to
+ <code>"-1"</code> for infinite repeating or to a positive integer. For example, a value of
+ <code>"1"</code> means that the animation is repeated once after the initial run of the
+ animation, so the animation plays a total of two times. The default value is
+ <code>"0"</code>.</dd>
+
+ <dt><code>android:repeatMode</code></dt>
+ <dd>How an animation behaves when it reaches the end of the
+ animation. <code>android:repeatCount</code> must be set to a positive integer or
+ <code>"-1"</code> for this attribute to have an effect. Set to <code>"reverse"</code> to
+ have the animation reverse direction with each iteration or <code>"repeat"</code> to
+ have the animation loop from the beginning each time.</dd>
+ </dl>
+
+ <p>The <code>objectAnimator</code> ({@link android.animation.ObjectAnimator}) element has the
+ additional attribute <code>propertyName</code>, that lets you specify the name of the
+ property being animated. The <code>objectAnimator</code> element does not expose a
+ <code>target</code> attribute, however, so you cannot set the object to animate in the
+ XML declaration. You have to inflate the XML resource by calling
+ {@link android.animation.AnimatorInflater#loadAnimator loadAnimator()} and call
+ {@link android.animation.ObjectAnimator#setTarget setTarget()} to set the target object, before calling
+ {@link android.animation.ObjectAnimator#start start()}.</p>
+
+ <p>The <code>set</code> element ({@link android.animation.AnimatorSet}) exposes a single
+ attribute, <code>ordering</code>. Set this attribute to <code>together</code> (default)
+ to play all the animations in this set at once. Set this attribute to
+ <code>sequentially</code> to play the animations in the order they are declared.</p>
+
+ <p>You can specify nested <code>set</code> tags to further group animations together.
+ The animations that you want to group together should be children of the
+ <code>set</code> tag and can define their own <code>ordering</code> attribute.</p>
+
+ <p>As an example, this XML code creates an {@link android.animation.AnimatorSet} object
+ that animates x and y at the same time (<code>together</code> is the default ordering
+ when nothing is specified), then runs an animation that fades an object out:</p>
+ <pre><set android:ordering="sequentially">
+ <set>
+ <objectAnimator
+ android:propertyName="x"
+ android:duration="500"
+ android:valueTo="400"
+ android:valueType="int"/>
+ <objectAnimator
+ android:propertyName="y"
+ android:duration="500"
+ android:valueTo="300"
+ android:valueType="int" >
+ </set>
+ <objectAnimator
+ android:propertyName="alpha"
+ android:duration="500"
+ android:valueTo="0f"/>
+ </set>
+</pre>
+
+ <p>In order to run this animation, you must inflate the XML resources in your code to
+ an {@link android.animation.AnimatorSet} object, and then set the target objects for all of
+ the animations before starting the animation set. Calling {@link
+ android.animation.AnimatorSet#setTarget setTarget()} sets a single target object for
+ all children of the {@link android.animation.AnimatorSet}.</p>
+
+ <h2 id="view-animation">View Animation</h2>You can use View Animation in any View
+ object to perform tweened animation and frame by frame animation. Tween animation
+ calculates the animation given information such as the start point, end point, size,
+ rotation, and other common aspects of an animation. Frame by frame animation lets you
+ load a series of Drawable resources one after another to create an animation.
+
+ <h3 id="tween-animation">Tween Animation</h3>
+
+ <p>A tween animation can perform a series of simple transformations (position, size,
+ rotation, and transparency) on the contents of a View object. So, if you have a
+ {@link android.widget.TextView} object, you can move, rotate, grow, or shrink the text. If it has a background
+ image, the background image will be transformed along with the text. The {@link
+ android.view.animation animation package} provides all the classes used in a tween
+ animation.</p>
+
+ <p>A sequence of animation instructions defines the tween animation, defined by either
+ XML or Android code. As with defining a layout, an XML file is recommended because it's
+ more readable, reusable, and swappable than hard-coding the animation. In the example
+ below, we use XML. (To learn more about defining an animation in your application code,
+ instead of XML, refer to the {@link android.view.animation.AnimationSet} class and
+ other {@link android.view.animation.Animation} subclasses.)</p>
+
+ <p>The animation instructions define the transformations that you want to occur, when
+ they will occur, and how long they should take to apply. Transformations can be
+ sequential or simultaneous — for example, you can have the contents of a TextView
+ move from left to right, and then rotate 180 degrees, or you can have the text move and
+ rotate simultaneously. Each transformation takes a set of parameters specific for that
+ transformation (starting size and ending size for size change, starting angle and
+ ending angle for rotation, and so on), and also a set of common parameters (for
+ instance, start time and duration). To make several transformations happen
+ simultaneously, give them the same start time; to make them sequential, calculate the
+ start time plus the duration of the preceding transformation.</p>
+
+ <p>The animation XML file belongs in the <code>res/anim/</code> directory of your
+ Android project. The file must have a single root element: this will be either a single
+ <code><alpha></code>, <code><scale></code>, <code><translate></code>,
+ <code><rotate></code>, interpolator element, or <code><set></code> element
+ that holds groups of these elements (which may include another
+ <code><set></code>). By default, all animation instructions are applied
+ simultaneously. To make them occur sequentially, you must specify the
+ <code>startOffset</code> attribute, as shown in the example below.</p>
+
+ <p>The following XML from one of the ApiDemos is used to stretch, then simultaneously
+ spin and rotate a View object.</p>
+ <pre>
+<set android:shareInterpolator="false">
+ <scale
+ android:interpolator="@android:anim/accelerate_decelerate_interpolator"
+ android:fromXScale="1.0"
+ android:toXScale="1.4"
+ android:fromYScale="1.0"
+ android:toYScale="0.6"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:fillAfter="false"
+ android:duration="700" />
+ <set android:interpolator="@android:anim/decelerate_interpolator">
+ <scale
+ android:fromXScale="1.4"
+ android:toXScale="0.0"
+ android:fromYScale="0.6"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:startOffset="700"
+ android:duration="400"
+ android:fillBefore="false" />
+ <rotate
+ android:fromDegrees="0"
+ android:toDegrees="-45"
+ android:toYScale="0.0"
+ android:pivotX="50%"
+ android:pivotY="50%"
+ android:startOffset="700"
+ android:duration="400" />
+ </set>
+</set>
+</pre>
+
+ <p>Screen coordinates (not used in this example) are (0,0) at the upper left hand
+ corner, and increase as you go down and to the right.</p>
+
+ <p>Some values, such as pivotX, can be specified relative to the object itself or
+ relative to the parent. Be sure to use the proper format for what you want ("50" for
+ 50% relative to the parent, or "50%" for 50% relative to itself).</p>
+
+ <p>You can determine how a transformation is applied over time by assigning an {@link
+ android.view.animation.Interpolator}. Android includes several Interpolator subclasses
+ that specify various speed curves: for instance, {@link
+ android.view.animation.AccelerateInterpolator} tells a transformation to start slow and
+ speed up. Each one has an attribute value that can be applied in the XML.</p>
+
+ <p>With this XML saved as <code>hyperspace_jump.xml</code> in the
+ <code>res/anim/</code> directory of the project, the following code will reference
+ it and apply it to an {@link android.widget.ImageView} object from the layout.</p>
+ <pre>
+ImageView spaceshipImage = (ImageView) findViewById(R.id.spaceshipImage);
+Animation hyperspaceJumpAnimation = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
+spaceshipImage.startAnimation(hyperspaceJumpAnimation);
+</pre>
+
+ <p>As an alternative to <code>startAnimation()</code>, you can define a starting time
+ for the animation with <code>{@link android.view.animation.Animation#setStartTime(long)
+ Animation.setStartTime()}</code>, then assign the animation to the View with
+ <code>{@link android.view.View#setAnimation(android.view.animation.Animation)
+ View.setAnimation()}</code>.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
+
+ <p class="note"><strong>Note:</strong> Regardless of how your animation may move or
+ resize, the bounds of the View that holds your animation will not automatically adjust
+ to accommodate it. Even so, the animation will still be drawn beyond the bounds of its
+ View and will not be clipped. However, clipping <em>will occur</em> if the animation
+ exceeds the bounds of the parent View.</p>
+
+ <h3 id="frame-animation">Frame Animation</h3>
+
+ <p>This is a traditional animation in the sense that it is created with a sequence of
+ different images, played in order, like a roll of film. The {@link
+ android.graphics.drawable.AnimationDrawable} class is the basis for frame
+ animations.</p>
+
+ <p>While you can define the frames of an animation in your code, using the {@link
+ android.graphics.drawable.AnimationDrawable} class API, it's more simply accomplished
+ with a single XML file that lists the frames that compose the animation. Like the tween
+ animation above, the XML file for this kind of animation belongs in the
+ <code>res/drawable/</code> directory of your Android project. In this case, the
+ instructions are the order and duration for each frame of the animation.</p>
+
+ <p>The XML file consists of an <code><animation-list></code> element as the root
+ node and a series of child <code><item></code> nodes that each define a frame: a
+ drawable resource for the frame and the frame duration. Here's an example XML file for
+ a frame-by-frame animation:</p>
+ <pre>
+<animation-list xmlns:android="http://schemas.android.com/apk/res/android"
+ android:oneshot="true">
+ <item android:drawable="@drawable/rocket_thrust1" android:duration="200" />
+ <item android:drawable="@drawable/rocket_thrust2" android:duration="200" />
+ <item android:drawable="@drawable/rocket_thrust3" android:duration="200" />
+</animation-list>
+</pre>
+
+ <p>This animation runs for just three frames. By setting the
+ <code>android:oneshot</code> attribute of the list to <var>true</var>, it will cycle
+ just once then stop and hold on the last frame. If it is set <var>false</var> then the
+ animation will loop. With this XML saved as <code>rocket_thrust.xml</code> in the
+ <code>res/drawable/</code> directory of the project, it can be added as the background
+ image to a View and then called to play. Here's an example Activity, in which the
+ animation is added to an {@link android.widget.ImageView} and then animated when the
+ screen is touched:</p>
+ <pre>
+AnimationDrawable rocketAnimation;
+
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ ImageView rocketImage = (ImageView) findViewById(R.id.rocket_image);
+ rocketImage.setBackgroundResource(R.drawable.rocket_thrust);
+ rocketAnimation = (AnimationDrawable) rocketImage.getBackground();
+}
+
+public boolean onTouchEvent(MotionEvent event) {
+ if (event.getAction() == MotionEvent.ACTION_DOWN) {
+ rocketAnimation.start();
+ return true;
+ }
+ return super.onTouchEvent(event);
+}
+</pre>
+
+ <p>It's important to note that the <code>start()</code> method called on the
+ AnimationDrawable cannot be called during the <code>onCreate()</code> method of your
+ Activity, because the AnimationDrawable is not yet fully attached to the window. If you
+ want to play the animation immediately, without requiring interaction, then you might
+ want to call it from the <code>{@link
+ android.app.Activity#onWindowFocusChanged(boolean) onWindowFocusChanged()}</code>
+ method in your Activity, which will get called when Android brings your window into
+ focus.</p>
+
+ <p>For more information on the XML syntax, available tags and attributes, see <a href=
+ "{@docRoot}guide/topics/resources/animation-resource.html">Animation Resources</a>.</p>
\ No newline at end of file
diff --git a/docs/html/guide/topics/manifest/supports-screens-element.jd b/docs/html/guide/topics/manifest/supports-screens-element.jd
index 620d3b2..64a7a58 100644
--- a/docs/html/guide/topics/manifest/supports-screens-element.jd
+++ b/docs/html/guide/topics/manifest/supports-screens-element.jd
@@ -9,6 +9,7 @@
<supports-screens android:<a href="#small">smallScreens</a>=["true" | "false"]
android:<a href="#normal">normalScreens</a>=["true" | "false"]
android:<a href="#large">largeScreens</a>=["true" | "false"]
+ android:<a href="#xlarge">xlargeScreens</a>=["true" | "false"]
android:<a href="#any">anyDensity</a>=["true" | "false"] />
</pre>
</dd>
@@ -31,7 +32,7 @@
The screen density is expressed as dots-per-inch (dpi).</p>
<p>For more information, see
-<a href="{@docRoot}guide/practices/screens_support.html">Multiple Screens Support</a>.</p>
+<a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>.</p>
<dt>attributes:</dt>
@@ -43,8 +44,10 @@
the "normal" (traditional HVGA) screen. An application that does
not support small screens <em>will not be available</em> for
small screen devices, because there is little the platform can do
- to make such an application work on a smaller screen. Applications using
- API Level 4 or higher default this to "true", others are "false".
+ to make such an application work on a smaller screen. If the application has set the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element's
+{@code android:minSdkVersion} or {@code android:targetSdkVersion} attribute to "4" or higher,
+the default value for this is "true", any value less than "4" results in this set to "false".
</dd>
<dt><a name="normal"></a>{@code android:normalScreens}</dt>
@@ -60,15 +63,33 @@
A large screen is defined as a screen that is significantly larger
than a "normal" phone screen, and thus may require some special care
on the application's part to make good use of it. An application that
- does not support large screens will be placed as a "postage stamp" on
- such a screen, so that it retains the dimensions it was originally
- designed for. Applications using API Level 4 or higher default
- to "true", others are "false".
+ does not support large screens (declares this "false")—but does support "normal" or
+"small" screens—will be placed as a "postage stamp" on
+ a large screen, so that it retains the dimensions it was originally
+ designed for. If the application has set the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element's
+{@code android:minSdkVersion} or {@code android:targetSdkVersion} attribute to "4" or higher,
+the default value for this is "true", any value less than "4" results in this set to "false".
+ </dd>
+
+ <dt><a name="xlarge"></a>{@code android:xlargeScreens}</dt>
+ <dd>Indicates whether the application supports extra large screen form-factors.
+ An xlarge screen is defined as a screen that is significantly larger
+ than a "large" screen, such as a tablet (or something larger) and may require special care
+ on the application's part to make good use of it. An application that
+ does not support xlarge screens (declares this "false")—but does support "large",
+"normal", or "small" screens—will be placed as a "postage stamp" on
+ an xlarge screen, so that it retains the dimensions it was originally
+ designed for. If the application has set the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element's
+{@code android:minSdkVersion} or {@code android:targetSdkVersion} attribute to "4" or higher,
+the default value for this is "true", any value less than "4" results in this set to "false".
+ <p>This attribute was introduced in API Level 9.</p>
</dd>
<dt><a name="any"></a>{@code android:anyDensity}</dt>
- <dd>Indicates whether the application can accommodate any screen
- density. Older applications (pre API Level 4) are assumed unable to
+ <dd>Indicates whether the application includes resources to accommodate any screen
+ density. Older applications (before API Level 4) are assumed unable to
accomodate all densities and this is "false" by default. Applications using
API Level 4 or higher are assumed able to and this is "true" by default.
You can explicitly supply your abilities here.
@@ -84,7 +105,8 @@
<dt>see also:</dt>
<dd>
<ul>
- <li><a href="{@docRoot}guide/practices/screens_support.html">Multiple Screens Support</a></li>
+ <li><a href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a></li>
<li>{@link android.util.DisplayMetrics}</li>
</ul>
</dd>
diff --git a/docs/html/guide/topics/ui/actionbar.jd b/docs/html/guide/topics/ui/actionbar.jd
index c17fc3c..376bf6a 100644
--- a/docs/html/guide/topics/ui/actionbar.jd
+++ b/docs/html/guide/topics/ui/actionbar.jd
@@ -425,7 +425,7 @@
<p>If your activity is stopped, you should retain the currently selected tab with the saved state so
that when the user returns to your application, you can open the tab. When it's time to save the
state, you can query the currently selected tab with {@link
-android.app.ActionBar#getSelectedNavigationItem()}. This returns the index position of the selected
+android.app.ActionBar#getSelectedNavigationIndex()}. This returns the index position of the selected
tab.</p>
<p class="caution"><strong>Caution:</strong> It's important that you save
diff --git a/docs/html/guide/tutorials/views/hello-webview.jd b/docs/html/guide/tutorials/views/hello-webview.jd
index c4388ea..a927b04 100644
--- a/docs/html/guide/tutorials/views/hello-webview.jd
+++ b/docs/html/guide/tutorials/views/hello-webview.jd
@@ -12,8 +12,8 @@
<pre>
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
android:orientation="vertical">
<WebView
@@ -69,7 +69,7 @@
<li>Now, in the <code>onCreate()</code> method, set an instance of the <code>HelloWebViewClient</code>
as our WebViewClient:
- <pre>webview.setWebViewClient(new WebViewClientDemo());</pre>
+ <pre>webview.setWebViewClient(new HelloWebViewClient());</pre>
<p>This line should immediately follow the initialization of our WebView object.</p>
<p>What we've done is create a WebViewClient that will load any URL selected in our
diff --git a/docs/html/images/developing/sdk-usb-driver.png b/docs/html/images/developing/sdk-usb-driver.png
new file mode 100644
index 0000000..207d3d7
--- /dev/null
+++ b/docs/html/images/developing/sdk-usb-driver.png
Binary files differ
diff --git a/docs/html/resources/resources-data.js b/docs/html/resources/resources-data.js
index 221406c..11964da 100644
--- a/docs/html/resources/resources-data.js
+++ b/docs/html/resources/resources-data.js
@@ -343,7 +343,27 @@
///////////////////
/// SAMPLE CODE ///
///////////////////
-
+
+ {
+ tags: ['sample'],
+ path: 'samples/AccelerometerPlay/index.html',
+ title: {
+ en: 'Accelerometer Play'
+ },
+ description: {
+ en: ''
+ }
+ },
+ {
+ tags: ['sample'],
+ path: 'samples/AccessibilityService/index.html',
+ title: {
+ en: 'Accessibility Service'
+ },
+ description: {
+ en: 'Illustrates an accessibility service that provides custom feedback for the Clock application which comes by default with Android devices'
+ }
+ },
{
tags: ['sample', 'layout', 'ui'],
path: 'samples/ApiDemos/index.html',
@@ -355,7 +375,7 @@
}
},
{
- tags: ['sample', 'data', 'newfeature', 'accountsync', 'new'],
+ tags: ['sample', 'data', 'newfeature', 'accountsync'],
path: 'samples/BackupRestore/index.html',
title: {
en: 'Backup and Restore'
@@ -395,6 +415,16 @@
}
},
{
+ tags: ['sample', 'ui'],
+ path: 'samples/CubeLiveWallpaper/index.html',
+ title: {
+ en: 'Cube Live Wallpaper'
+ },
+ description: {
+ en: 'An application that demonstrates how to create a live wallpaper and bundle it in an application that users can install on their devices.'
+ }
+ },
+ {
tags: ['sample'],
path: 'samples/Home/index.html',
title: {
@@ -405,6 +435,16 @@
}
},
{
+ tags: ['sample', 'new'],
+ path: 'samples/Honeycomb-Gallery/index.html',
+ title: {
+ en: 'Honeycomb Gallery'
+ },
+ description: {
+ en: 'An image gallery application using Honeycomb-specific APIs.'
+ }
+ },
+ {
tags: ['sample', 'gamedev', 'media'],
path: 'samples/JetBoy/index.html',
title: {
@@ -415,16 +455,6 @@
}
},
{
- tags: ['sample', 'ui', 'newfeature'],
- path: 'samples/CubeLiveWallpaper/index.html',
- title: {
- en: 'Live Wallpaper'
- },
- description: {
- en: 'An application that demonstrates how to create a live wallpaper and bundle it in an application that users can install on their devices.'
- }
- },
- {
tags: ['sample', 'gamedev', 'media'],
path: 'samples/LunarLander/index.html',
title: {
@@ -446,6 +476,16 @@
},
{
tags: ['sample', 'data'],
+ path: 'samples/NFCDemo/index.html',
+ title: {
+ en: 'NFC Demo'
+ },
+ description: {
+ en: 'An application for reading NFC Forum Type 2 Tags using the NFC APIs'
+ }
+ },
+ {
+ tags: ['sample', 'data'],
path: 'samples/NotePad/index.html',
title: {
en: 'Note Pad'
@@ -475,6 +515,16 @@
}
},
{
+ tags: ['sample'],
+ path: 'samples/SipDemo/index.html',
+ title: {
+ en: 'SIP Demo'
+ },
+ description: {
+ en: 'A demo application highlighting how to make internet-based calls with the SIP API.'
+ }
+ },
+ {
tags: ['sample', 'layout', 'ui'],
path: 'samples/Snake/index.html',
title: {
@@ -485,6 +535,16 @@
}
},
{
+ tags: ['sample', 'input'],
+ path: 'samples/SoftKeyboard/index.html',
+ title: {
+ en: 'Soft Keyboard'
+ },
+ description: {
+ en: 'An example of writing an input method for a software keyboard.'
+ }
+ },
+ {
tags: ['sample', 'testing'],
path: 'samples/Spinner/index.html',
title: {
@@ -525,16 +585,6 @@
}
},
{
- tags: ['sample', 'input'],
- path: 'samples/SoftKeyboard/index.html',
- title: {
- en: 'Soft Keyboard'
- },
- description: {
- en: 'An example of writing an input method for a software keyboard.'
- }
- },
- {
tags: ['sample', 'ui'],
path: 'samples/Wiktionary/index.html',
title: {
@@ -555,7 +605,7 @@
}
},
{
- tags: ['sample', 'layout', 'new'],
+ tags: ['sample', 'layout'],
path: 'samples/XmlAdapters/index.html',
title: {
en: 'XML Adapters'
diff --git a/docs/html/resources/samples/images/NfcDemo.png b/docs/html/resources/samples/images/NfcDemo.png
new file mode 100644
index 0000000..c175d12
--- /dev/null
+++ b/docs/html/resources/samples/images/NfcDemo.png
Binary files differ
diff --git a/docs/html/resources/samples/images/hcgallery.png b/docs/html/resources/samples/images/hcgallery.png
new file mode 100644
index 0000000..9a80fd7
--- /dev/null
+++ b/docs/html/resources/samples/images/hcgallery.png
Binary files differ
diff --git a/docs/html/sdk/android-3.0.jd b/docs/html/sdk/android-3.0.jd
new file mode 100644
index 0000000..6896f52
--- /dev/null
+++ b/docs/html/sdk/android-3.0.jd
@@ -0,0 +1,668 @@
+page.title=Android 3.0 Platform
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>In this document</h2>
+<ol>
+ <li><a href="#api">API Overview</a></li>
+ <li><a href="#api-level">API Level</a></li>
+ <li><a href="#apps">Built-in Applications</a></li>
+ <li><a href="#locs">Locales</a></li>
+ <li><a href="#skins">Emulator Skins</a></li>
+</ol>
+
+<h2>Reference</h2>
+<ol>
+<li><a
+href="{@docRoot}sdk/api_diff/honeycomb/changes.html">API
+Differences Report »</a> </li>
+</ol>
+
+<h2>See Also</h2>
+<ol>
+ <li><a href="{@docRoot}sdk/preview/start.html">Getting Started</a></li>
+</ol>
+
+</div>
+</div>
+
+</p>API Level: <b>Honeycomb</b></p>
+
+<p>For developers, the Android 3.0 preview is available as a downloadable component for the
+Android SDK. The downloadable platform includes an Android library and system image, as well as a
+set of emulator skins and more. The downloadable platform includes no external libraries.</p>
+
+
+
+
+<h2 id="#api">API Overview</h2>
+
+<p>The sections below provide a technical overview of what's new for developers in Android 3.0,
+including new features and changes in the framework API since the previous version.</p>
+
+
+
+
+<h3>Fragments</h3>
+
+<p>A fragment is a new framework component that allows you to separate distinct elements of an
+activity into self-contained modules that define their own UI and lifecycle. To create a
+fragment, you must extend the {@link android.app.Fragment} class and implement several lifecycle
+callback methods, similar to an {@link android.app.Activity}. You can then combine multiple
+fragments in a single activity to build a multi-pane UI in which each
+pane manages its own lifecycle and user inputs.</p>
+
+<p>You can also use a fragment without providing a UI and instead use the fragment as a worker
+for the activity, such as to manage the progress of a download that occurs only while the
+activity is running.</p>
+
+<p>Additionally:</p>
+
+<ul>
+ <li>Fragments are self-contained and can be reused in multiple activities</li>
+ <li>Fragments can be added, removed, replaced and animated inside the activity</li>
+ <li>Fragment can be added to a back stack managed by the activity, preserving the state of
+fragments as they are changed and allowing the user to navigate backward through the different
+states</li>
+ <li>By <a
+href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">providing
+alternative resources</a>, you can mix and match fragments, based
+on the screen size and orientation</li>
+ <li>Fragments have direct access to their container activity and can contribute items to the
+activity's Action Bar (discussed next)</li>
+</ul>
+
+<p>To manage the fragments in your activity, you must use the {@link
+android.app.FragmentManager}, which provides several APIs for interacting with fragments, such
+as finding fragments in the activity and popping fragments off the back stack to restore them
+after they've been removed or hidden.</p>
+
+<p>To perform transactions, such as add or remove fragments, you must create a {@link
+android.app.FragmentTransaction}. You can then call methods such as {@link
+android.app.FragmentTransaction#add add()} {@link android.app.FragmentTransaction#remove
+remove()}, {@link android.app.FragmentTransaction#replace replace()}. Once you've applied all
+the changes you want to perform for the transaction, you must call {@link
+android.app.FragmentTransaction#commit commit()} and the system will apply the transaction to
+the activity.</p>
+
+<p>For more information about using fragments in your application, read the <a
+href="{@docRoot}guide/topics/fundamentals/fragments.html">Fragments</a> developer guide.</p>
+
+
+
+
+<h3>Action Bar</h3>
+
+<p>The Action Bar is a replacement for the traditional title bar at the top of the activity
+window. It includes the application logo in the left corner and also replaces the previous Options
+Menu UI with a drop-down list for the menu items. Additionally, the Action Bar allows you
+to:</p></p>
+
+<ul>
+ <li>Include select menu items directly in the Action Bar—as "action
+items"—for quick access to global actions.
+ <p>In your XML declaration for the menu item, include the attribute, {@code
+android:showAsAction} with a value of {@code "ifRoom"}. When there's enough room in the
+Action Bar, the menu item appears directly in the bar. Otherwise, it is placed in the
+overflow menu, revealed by the icon on the right side of the Action Bar.</p></li>
+ <li>Add interactive widgets ("action views"), such as a search box.
+ <p>In your XML, include the attribute, {@code android:actionViewLayout} with a layout
+resource for the action view, or {@code android:actionViewClass} with the class name of the
+widget. Like action items, an action view appears only when there's room for it in the Action
+Bar. If there's not enough room, it is placed in the overflow menu and behaves like a regular
+menu item (for example, an item can provide a {@link android.widget.SearchView} as an action
+view, but when in the overflow menu, selecting the item will activate the search dialog).</p>
+ <p></p></li>
+ <li>Add an action to the application logo when tapped and replace it with a custom logo
+ <p>The application logo is automatically assigned the {@code android.R.id.home} ID,
+which is delivered to your activity's {@link android.app.Activity#onOptionsItemSelected
+onOptionsItemSelected()} callback when tapped. Simply respond to this ID in your callback
+method to perform an action such as go to your application's "home" activity.</p>
+ <p>If your activity does not respond to the icon action, you should hide it by calling {@link
+android.app.ActionBar#setDisplayShowHomeEnabled setDisplayShowHomeEnabled(false)}.</p>
+ <p>By default, this is true, so the icon will visually respond when pressed, even if you don't
+respond. Thus, you should remove the icon if you don't respond to it.</p></li>
+ <li>Add breadcrumbs for navigating backward through fragments</li>
+ <li>Add built in tabs and a drop-down list for navigation</li>
+ <li>Customize the Action Bar themes and custom backgrounds</li>
+</ul>
+
+<p>The Action Bar is standard for all applications that set either the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+android:minSdkVersion}</a> or <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code
+android:targetSdkVersion}</a> to {@code "Honeycomb"}. (The "Honeycomb" API Level is provisional
+and effective only while using the preview SDK—you must change it to the official API
+Level when the final SDK becomes available.)</p>
+
+<p>For more information, read the <a href="{@docRoot}guide/topics/ui/actionbar.html">Action
+Bar</a> developer guide.</p>
+
+
+
+
+<h3>System clipboard</h3>
+
+<p>Applications can now copy and paste data (beyond mere text) to and from the system-wide
+clipboard. Clipped data can be plain text, a URI, or an intent.</p>
+
+<p>By providing the system access to your data in a content provider, the user can copy complex
+content (such as an image or data structure) from your application and paste it into another
+application that supports that type of content.</p>
+
+<p>To start using the clipboard, get the global {@link android.content.ClipboardManager} object
+by calling {@link android.content.Context#getSystemService getSystemService(CLIPBOARD_SERVICE)}.</p>
+
+<p>To create an item to attach to the clipboard, you need to create a new {@link
+android.content.ClipData} object, which holds one or more {@link android.content.ClipData.Item}
+objects, each describing a single entity. To create a {@link android.content.ClipData} object with
+just one {@link android.content.ClipData.Item}, you can use one of the helper methods such as,
+{@link android.content.ClipData#newPlainText newPlainText()}, {@link
+android.content.ClipData#newUri newUri()}, and {@link android.content.ClipData#newIntent
+newIntent()}, which each return a {@link android.content.ClipData} object pre-loaded with the
+appropriate {@link android.content.ClipData.Item}.</p>
+
+<p>To add the {@link android.content.ClipData} to the clipboard, pass it to {@link
+android.content.ClipboardManager#setPrimaryClip setPrimaryClip()} for your instance of {@link
+android.content.ClipboardManager}.</p>
+
+<p>You can then acquire ("paste") a file from the clipboard by calling {@link
+android.content.ClipboardManager#getPrimaryClip()} on the {@link
+android.content.ClipboardManager}. Handling the {@link android.content.ClipData} you receive can
+be more complicated and you need to be sure you can actually handle the data type.</p>
+
+<p>For more information, see the {@link android.content.ClipData} class reference. You can also see
+an example implementation of copy and paste in the <a
+href="{@docRoot}resources/samples/NotePad/index.html">NotePad</a> sample application.</p>
+
+
+
+
+<h3>Drag and drop</h3>
+
+<p>New APIs now facilitate the ability for your application to implement drag and drop
+functionality in the UI.</p>
+
+<p>To drag a {@link android.view.View} in your activity, call {@link android.view.View#startDrag
+startDrag()} on the object, providing a {@link android.content.ClipData} object that represents the
+information to drag, a {@link android.view.View.DragShadowBuilder} to facilitate the "shadow" that
+the user sees while dragging, and an {@link java.lang.Object} that can share information about the
+drag object with views that may receive the object. However, </p>
+
+<p>To accept a drag object (receive the "drop") in a
+{@link android.view.View}, register the view with an {@link android.view.View.OnDragListener} by
+calling {@link android.view.View#setOnDragListener setOnDragListener()}. When a drag event occurs on
+the view, the system calls {@link android.view.View.OnDragListener#onDrag onDrag()} for the {@link
+android.view.View.OnDragListener}, which receives a {@link android.view.DragEvent} describing
+the type of event has occurred (such as "drag started", "drag ended", and "drop"). The receiving
+view can inquire the event type delivered to {@link
+android.view.View#onDragEvent onDragEvent()} by calling {@link
+android.view.DragEvent#getAction getAction()} on the {@link android.view.DragEvent}.</p>
+
+<p>Although a drag event may carry a {@link android.content.ClipData} object, drag and drop does
+not depend on the clipboard. The data being dragged is sent to the system as {@link
+android.content.ClipData} and the system sends it to {@link android.view.View} objects in the
+{@link android.view.DragEvent}. A drag and drop operation should never put the dragged data on the
+clipboard.</p>
+
+
+
+<h3>Multiple-choice selection for ListView and GridView</h3>
+
+<p>New {@link android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL} mode for {@link
+android.widget.AbsListView#setChoiceMode setChoiceMode()} allows for selecting multiple items
+from a {@link android.widget.ListView} and {@link android.widget.GridView}.</p>
+
+<p>To enable multiple-choice selection, call {@link
+android.widget.AbsListView#setChoiceMode setChoiceMode(CHOICE_MODE_MULTIPLE_MODAL)} and register a
+{@link android.widget.AbsListView.MultiChoiceModeListener} with {@link
+android.widget.AbsListView#setMultiChoiceModeListener setMultiChoiceModeListener()}.</p>
+
+<p>When the user performs a long-press on an item, the Action Bar switches to the Multi-choice
+Action Mode. The system notifies the {@link android.widget.AbsListView.MultiChoiceModeListener}
+when items are selected by calling {@link
+android.widget.AbsListView.MultiChoiceModeListener#onItemCheckedStateChanged
+onItemCheckedStateChanged()}.</p>
+
+<p>For an example of multiple-choice selection, see the <a
+href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List15.html">List15.java</a>
+class in the API Demos sample application.</p>
+
+
+
+
+<h3>Content loaders</h3>
+
+<p>New framework APIs facilitate asynchronous loading of data using the {@link
+android.content.Loader} class. You can use it in combination with UI components such as views and
+fragments to dynamically load data from background threads. The {@link
+android.content.CursorLoader} subclass is specially designed to help do so for data queried from
+a {@link android.content.ContentResolver}.</p>
+
+
+
+<h3>Extended app widgets</h3>
+
+<p>App widgets can now be more interactive with scrolling list views, grid views, view flippers, and
+a new 3D stack widget.</p>
+
+<p>Android 3.0 supports several new widget classes for App Widgets, including:</p>
+<ul>
+ <li>{@link android.widget.GridView}</li>
+ <li>{@link android.widget.ListView}</li>
+ <li>{@link android.widget.StackView}</li>
+ <li>{@link android.widget.ViewFlipper}</li>
+ <li>{@link android.widget.AdapterViewFlipper}</li>
+</ul>
+
+<p>You can use the new {@link android.widget.RemoteViewsService} to populate the new remote
+collection views ({@link android.widget.GridView}, {@link android.widget.ListView}, and {@link
+android.widget.StackView}).</p>
+
+<p>You can also use two new {@link android.appwidget.AppWidgetProviderInfo} fields. The {@link
+android.appwidget.AppWidgetProviderInfo#autoAdvanceViewId} field lets you specify the view ID of the
+app widget subview, which is auto-advanced by the app widget’s host. The
+{@link android.appwidget.AppWidgetProviderInfo#previewImage} field specifies a preview of what the
+App Widget looks like and is shown to the user from the widget picker. If this field is not
+supplied, the app widget's icon is used for the preview.</p>
+
+<p>Android also provides a new widget preview tool (WidgetPreview), located in the SDK tools. The
+tool lets you take a screenshot of your app widget, which you can use to populate the customization
+tray.</p>
+
+
+
+
+
+<h3>Extended status bar notifications</h3>
+
+<p>The {@link android.app.Notification} APIs have been extended to support more content-rich status
+bar notifications, plus a new {@link android.app.Notification.Builder} class allows you to easily
+control the notification properties. New features include:</p>
+<ul>
+ <li>Support for a large icon in the notification. This is usually for
+social applications to show the contact photo of the person who is the source of the
+notification or for media apps to show an album thumbnail. Set using {@link
+android.app.Notification.Builder#setLargeIcon setLargeIcon()}.</li>
+ <li>Support for custom layouts in the status bar ticker, using {@link
+android.app.Notification.Builder#setTicker(CharSequence,RemoteViews) setTicker()}.</li>
+ <li>Support for custom notification layouts to include buttons with {@link
+android.app.PendingIntent}s, for more interactive notification widgets
+(such as to control ongoing music in the background).</li>
+</ul>
+
+
+
+
+<h3>New animation framework</h3>
+
+<p>An all new flexible animation framework that allows you to animate the properties of any object
+(View, Drawable, Fragment, Object, anything). It allows you to define many aspects of an animation,
+such as:</p>
+<ul>
+ <li>Duration</li>
+ <li>Repeat amount and behavior</li>
+ <li>Type of time interpolation</li>
+ <li>Animator sets to play animations together, sequentially, or after specified delays</li>
+ <li>Frame refresh delay</li>
+</ul>
+
+ <p>You can define these animation aspects, and others, for an object's int, float, and hexadecimal
+color values, by default. To animate any other type of value, you tell the system how to calculate
+the values for that given type, by implementing the {@link android.animation.TypeEvaluator}
+interface.</p>
+
+<p>There are two animators that you can use to animate values of a property: {@link
+android.animation.ValueAnimator} and {@link android.animation.ObjectAnimator}. The {@link
+android.animation.ValueAnimator} computes the animation values, but is not aware of the specific
+object or property that is animated as a result. It simply performs the calculations, and you must
+listen for the updates and process the data with your own logic. The {@link
+android.animation.ObjectAnimator} is a subclass of {@link android.animation.ValueAnimator} and
+allows you to set the object and property to animate, so you do not have to listen for updates.</p>
+
+<p>For more information, see the <a
+href="{@docRoot}guide/topics/graphics/animation.html">Animation</a> developer guide.</p>
+
+
+
+
+
+<h3>New widgets</h3>
+
+<ul>
+
+<li>{@link android.widget.AdapterViewAnimator}
+<p>Base class for an {@link android.widget.AdapterView} that performs animations when switching
+between its views.</p></li>
+
+<li>{@link android.widget.AdapterViewFlipper}
+<p>Simple {@link android.widget.ViewAnimator} that animates between two or more views that have
+been added to it. Only one child is shown at a time. If requested, it can automatically flip between
+each child at a regular interval.</p></li>
+
+<li>{@link android.widget.CalendarView}
+<p>Allows users to select dates from a calendar and you can configure the range of dates
+available. A user can select a date by tapping on it and can scroll and fling
+the calendar to a desired date.</p></li>
+
+<li>{@link android.widget.ListPopupWindow}
+<p>Anchors itself to a host view and displays a list of choices, such as for a list of
+suggestions when typing into an {@link android.widget.EditText} view.</p></li>
+
+<li>{@link android.widget.NumberPicker}
+<p>Enables the user to select a number from a predefined range. The widget presents an
+input field and up and down buttons for selecting a number. Touching the input field shows a
+scroll wheel that allows the user to scroll through values or touch again to directly edit the
+current value. It also allows you to map from positions to strings, so that
+the corresponding string is displayed instead of the position index.</p></li>
+
+<li>{@link android.widget.PopupMenu}
+<p>Displays a {@link android.view.Menu} in a modal popup window that's anchored to a view. The popup
+appears below the anchor view if there is room, or above it if there is not. If the IME (soft
+keyboard) is visible, the popup does not overlap it until it is touched.</p></li>
+
+<li>{@link android.widget.SearchView}
+<p>Provides a search box that works in conjunction with a search provider (in the same manner as
+the traditional <a href="{@docRoot}guide/topics/search/search-dialog.html">search dialog</a>). It
+also displays recent query suggestions or custom suggestions as configured by the search
+provider. This widget is particularly useful for offering search in the Action Bar.</p></li>
+
+<li>{@link android.widget.StackView}
+<p>A view that displays its children in a 3D stack and allows users to discretely swipe through the
+children.</p></li>
+
+</ul>
+
+
+
+
+
+<h3>Redesigned widgets</h3>
+
+<p>Android 3.0 offers an updated set of UI widgets that developers can use to quickly add new types
+of content to their applications. The new UI widgets are redesigned for use on larger screens such
+as tablets and incorporate the new holographic UI theme. Several new widget types are available,
+including a 3D stack, search box, a date/time picker, number picker, stack, calendar View etc.
+SearchView, PopupMenu, and others. Most of the redesigned widgets can now be used as remote views in
+homescreen widgets. Applications written for earlier versions can inherit the new widget designs and
+themes.</p>
+
+
+
+
+<h3>Holographic themes</h3>
+
+<p>The standard system widgets and overall look have been redesigned for use on larger screens
+such as tablets and incorporate the new holographic UI theme. These style changes are applied
+using the standard <a href="{@docRoot}guide/topics/ui/themes.html">style and theme</a> system.
+Any application that targets the Android 3.0 platform inherit the holographic theme by default.
+However, if your application also applies its own styles, then it will override the holographic
+theme, unless you update your styles to inherit them.</p>
+
+<p>To apply the holographic theme to individual activities or to inherit them in your own theme
+definitions, you can use one of several new {@link android.R.style#Theme_Holo Theme.Holo}
+themes.</p>
+
+
+
+<h3>Bluetooth A2DP and headset APIs</h3>
+
+<p>Android now includes APIs for applications to verify the state of connected Bluetooth A2DP and
+headset profile devices. You can initialize the respective {@link
+android.bluetooth.BluetoothProfile} by calling {@link
+android.bluetooth.BluetoothAdapter#getProfileProxy getProfileProxy()} with either the {@link
+android.bluetooth.BluetoothProfile#A2DP} or {@link android.bluetooth.BluetoothProfile#HEADSET}
+profile constant and a {@link android.bluetooth.BluetoothProfile.ServiceListener} to receive
+callbacks when the client is connected or disconnected.</p>
+
+
+<!--
+<h3>WebKit</h3>
+<h3>JSON (utilities)</h3>
+ -->
+
+
+<h3>Graphics</h3>
+
+<ul>
+ <li><h4>Hardware accelerated 2D graphics</h4>
+
+<p>You can now enable the OpenGL renderer for your application by setting {@code
+android:hardwareAccelerated="true"} in your manifest element's <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>
+element or for individual <a
+href="{@docRoot}guide/topics/manifest/activity-element.html">{@code <activity>}</a>
+elements.</p>
+
+<p>This flag helps applications by making them draw faster. This results in smoother animations,
+smoother scrolling, and overall better performance and response to user interaction.</p></li>
+
+ <li><h4>Renderscript 3D graphics engine</h4>
+
+<p>Renderscript is a runtime 3D framework that provides both an API for building 3D scenes as well
+as a special, platform-independent shader language for maximum performance. Using Renderscript, you
+can accelerate graphics operations and data processing. Renderscript is an ideal way to create
+high-performance 3D effects for applications, wallpapers, carousels, and more.</p></li>
+</ul>
+
+
+
+
+
+<h3>Media</h3>
+
+
+<ul>
+ <li><h4>Camcorder profiles</h4>
+
+<p>New {@link android.media.CamcorderProfile#hasProfile hasProfile()} method and several video
+quality profiles, such as {@link android.media.CamcorderProfile#QUALITY_1080P}, {@link
+android.media.CamcorderProfile#QUALITY_720P}, {@link
+android.media.CamcorderProfile#QUALITY_CIF}, and more, to determine the camcorder quality
+profiles.</p></li>
+
+ <li><h4>Time lapse video mode</h4>
+
+<p>Camcorder APIs now support the ability to record time lapse video. The {@link
+android.media.MediaRecorder#setCaptureRate setCaptureRate()} sets the rate at which frames
+should be captured.</p></li>
+
+ <li><h4>Digital media file transfer</h4>
+
+<p>The platform includes built-in support for Media/Picture Transfer Protocol (MTP/PTP) over USB,
+which lets users easily transfer any type of media files between devices and to a host computer.
+Developers can take advantage of this to create applications that let users create or manage files
+that they may want to transfer across devices.</p></li>
+
+ <li><h4>Digital Media File Transfer</h4>
+
+<p>The platform includes built-in support for Media/Picture Transfer Protocol (MTP/PTP) over USB,
+which lets users easily transfer any type of media files between devices and to a host computer.
+Developers can build on this support, creating applications that let users create or manage rich
+media files that they may want to transfer or share across devices. </p></li>
+
+ <li><h4>Digital rights management (DRM)</h4>
+
+<p>New extensible digital rights management (DRM) framework for checking and enforcing digital
+rights. It's implemented in two architectural layers:</p>
+<ul>
+ <li>A DRM framework API, which is exposed to applications and runs through the Dalvik VM for
+standard applications.</li>
+ <li>A native code DRM manager that implements the framework API and exposes an interface for DRM
+plug-ins to handle rights management and decryption for various DRM schemes.</li>
+</ul>
+
+<p>For application developers, the framework offers an abstract, unified API that simplifies the
+management of protected content. The API hides the complexity of DRM operations and allows a
+consistent operation mode for both protected and unprotected content, and across a variety of DRM
+schemes.</p>
+
+<p>For device manufacturers, content owners, and Internet digital media providers the DRM
+framework?s plugin API provides a means of adding support for a DRM scheme of choice into the
+Android system, for secure enforcement of content protection.</p>
+
+<p>The preview release does not provide any native DRM plug-ins for checking and enforcing digital
+rights. However, device manufacturers may ship DRM plug-ins with their devices.</p>
+
+<p>You can find all of the DRM APIs in the {@link android.drm} package.</p></li>
+
+</ul>
+
+
+
+
+
+
+
+
+<h2 id="api-level">API Level</h2>
+
+<p>The Android 3.0 platform delivers an updated version of
+the framework API. Because this is a preview of the Android 3.0 API, it uses a provisional API
+level of "Honeycomb", instead of an integer identifier, which will be provided when the final SDK
+is made available and all APIs are final.</p>
+
+<p>To use APIs introduced in Android 3.0 in your application, you need compile the application
+against the Android library that is provided in the Android 3.0 preview SDK platform and you must
+declare this API Level in your manifest as <code>android:minSdkVersion="Honeycomb"</code>, in the
+<code><uses-sdk></code> element in the application's manifest.</p>
+
+<p>For more information about using this provisional API Level and setting up your environment
+to use the preview SDK, please see the <a href="{@docRoot}sdk/preview/start.html">Getting
+Started</a> document.</p>
+
+
+
+
+<h2 id="apps">Built-in Applications</h2>
+
+<p>The system image included in the downloadable platform provides these
+built-in applications:</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>Browser</li>
+<li>Calculator</li>
+<li>Camera</li>
+<li>Clock</li>
+<li>Contacts</li>
+<li>Custom Locale</li>
+<li>Dev Tools</li>
+<li>Downloads</li>
+<li>Email</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<ul>
+<li>Gallery</li>
+<li>Music</li>
+<li>Search</li>
+<li>Settings</li>
+<li>Spare Parts (developer app)</li>
+<li>Speech Recorder</li>
+</ul>
+</td>
+</tr>
+</table>
+
+
+<h2 id="locs" style="margin-top:.75em;">Locales</h2>
+
+<p>The system image included in the downloadable SDK platform provides a variety of
+built-in locales. In some cases, region-specific strings are available for the
+locales. In other cases, a default version of the language is used. The
+languages that are available in the Android 3.0 system
+image are listed below (with <em>language</em>_<em>country/region</em> locale
+descriptor).</p>
+
+<table style="border:0;padding-bottom:0;margin-bottom:0;">
+<tr>
+<td style="border:0;padding-bottom:0;margin-bottom:0;">
+<ul>
+<li>Arabic, Egypt (ar_EG)</li>
+<li>Arabic, Israel (ar_IL)</li>
+<li>Bulgarian, Bulgaria (bg_BG)</li>
+<li>Catalan, Spain (ca_ES)</li>
+<li>Czech, Czech Republic (cs_CZ)</li>
+<li>Danish, Denmark(da_DK)</li>
+<li>German, Austria (de_AT)</li>
+<li>German, Switzerland (de_CH)</li>
+<li>German, Germany (de_DE)</li>
+<li>German, Liechtenstein (de_LI)</li>
+<li>Greek, Greece (el_GR)</li>
+<li>English, Australia (en_AU)</li>
+<li>English, Canada (en_CA)</li>
+<li>English, Britain (en_GB)</li>
+<li>English, Ireland (en_IE)</li>
+<li>English, India (en_IN)</li>
+<li>English, New Zealand (en_NZ)</li>
+<li>English, Singapore(en_SG)</li>
+<li>English, US (en_US)</li>
+<li>English, Zimbabwe (en_ZA)</li>
+<li>Spanish (es_ES)</li>
+<li>Spanish, US (es_US)</li>
+<li>Finnish, Finland (fi_FI)</li>
+<li>French, Belgium (fr_BE)</li>
+<li>French, Canada (fr_CA)</li>
+<li>French, Switzerland (fr_CH)</li>
+<li>French, France (fr_FR)</li>
+<li>Hebrew, Israel (he_IL)</li>
+<li>Hindi, India (hi_IN)</li>
+</ul>
+</td>
+<td style="border:0;padding-bottom:0;margin-bottom:0;padding-left:5em;">
+<li>Croatian, Croatia (hr_HR)</li>
+<li>Hungarian, Hungary (hu_HU)</li>
+<li>Indonesian, Indonesia (id_ID)</li>
+<li>Italian, Switzerland (it_CH)</li>
+<li>Italian, Italy (it_IT)</li>
+<li>Japanese (ja_JP)</li>
+<li>Korean (ko_KR)</li>
+<li>Lithuanian, Lithuania (lt_LT)</li>
+<li>Latvian, Latvia (lv_LV)</li>
+<li>Norwegian bokmål, Norway (nb_NO)</li>
+<li>Dutch, Belgium (nl_BE)</li>
+<li>Dutch, Netherlands (nl_NL)</li>
+<li>Polish (pl_PL)</li>
+<li>Portuguese, Brazil (pt_BR)</li>
+<li>Portuguese, Portugal (pt_PT)</li>
+<li>Romanian, Romania (ro_RO)</li>
+<li>Russian (ru_RU)</li></li>
+<li>Slovak, Slovakia (sk_SK)</li>
+<li>Slovenian, Slovenia (sl_SI)</li>
+<li>Serbian (sr_RS)</li>
+<li>Swedish, Sweden (sv_SE)</li>
+<li>Thai, Thailand (th_TH)</li>
+<li>Tagalog, Philippines (tl_PH)</li>
+<li>Turkish, Turkey (tr_TR)</li>
+<li>Ukrainian, Ukraine (uk_UA)</li>
+<li>Vietnamese, Vietnam (vi_VN)</li>
+<li>Chinese, PRC (zh_CN)</li>
+<li>Chinese, Taiwan (zh_TW)</li>
+</td>
+</tr>
+</table>
+
+<p class="note"><strong>Note:</strong> The Android platform may support more
+locales than are included in the SDK system image. All of the supported locales
+are available in the <a href="http://source.android.com/">Android Open Source
+Project</a>.</p>
+
+<h2 id="skins">Emulator Skins</h2>
+
+<p>The downloadable platform includes the following emulator skin:</p>
+
+<ul>
+ <li>
+ WXGA (1280x800, medium density, xlarge screen)
+ </li>
+</ul>
+
+<p>For more information about how to develop an application that displays
+and functions properly on all Android-powered devices, see <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple
+Screens</a>.</p>
\ No newline at end of file
diff --git a/docs/html/sdk/eclipse-adt.jd b/docs/html/sdk/eclipse-adt.jd
index d0fa727..a83ca8e 100644
--- a/docs/html/sdk/eclipse-adt.jd
+++ b/docs/html/sdk/eclipse-adt.jd
@@ -100,6 +100,115 @@
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px"
width="9px" />
+ADT 9.0.0</a> <em>(January 2011)</em>
+ <div class="toggleme">
+
+<dl>
+
+<dt>Dependencies:</dt>
+
+<dd>ADT 9.0.0 is designed for use with SDK Tools r9. If you haven't
+already installed SDK Tools r9 into your SDK, use the Android SDK and AVD Manager to do
+so.</dd>
+
+<dt>General notes:</dt>
+<dd>
+ <ul>
+ <li>"Go To Declaration" hyperlink support: You can jump directly from code references (such as
+ <code>R.id.main</code>) to the corresponding XML declaration, or from XML attributes (such as
+ <code>@string</code>) to the corresponding resource definition, or from manifest XML
+ registrations to activities and services.</li>
+ <li>Improvements were made to name refactoring.</li>
+ <li>AVDs now automatically save their state, so they can restart almost instantly. You can enable this feature when
+ creating an AVD or by editing an AVD with the AVD Manager.</li>
+ <li>Improvements to the Visual Layout Editor:
+ <ul>
+ <li>Support for rendering targets: You can now choose an arbitrary Android platform to
+ render the current page, regardless of the project's minimum platform. This makes it
+ easy to verify the layout and appearance of your activity on different versions of
+ the platform.
+ </li>
+ <li>Improved support for empty and nested layouts: Dragging items over nested and
+ invisible layouts automatically enlarges and highlights these layouts, so that they
+ can receive drops.
+ </li>
+ <li>XML formatting improvements: The editor generates cleaner XML and you can now enable
+ XML auto-formatting in the <strong>Preferences</strong> menu.</li>
+ <li>Improved Outline labels: The Outline tab now displays additional information about each
+ View. Textual Views display a snippet of the actual text. Views with a source
+ (such as ImageView) displays the resource name. Included Views display the name of the View.
+ </li>
+ <li>When you right click a View in the Layout Editor,
+ the context menu now contains <strong>Edit ID...</strong> and <strong>Edit Text...</strong>
+ items. The <strong>Properties...</strong> context menus now list all of the properties and
+ provide a way to edit them
+ (<a href="http://tools.android.com/recent/editidtextandotherpropertiesviamenu">Details</a>).
+ </li>
+ <li>The layout editor now properly handles
+ <a href="{@docRoot}guide/topics/resources/layout-resource.html#include-element"><code><include></code></a>
+ and <a href="{@docRoot}guide/topics/resources/layout-resource.html#merge-element"><code><merge></code></a>
+ tags (<a href="http://tools.android.com/recent/supportforincludeandmerge">Details</a>).</li>
+ <li>"Extract as Include" refactoring: The Layout Editor has a new refactoring that allows
+ you to select one or more views in a layout, and extract it into a separate layout
+ (<a href="http://tools.android.com/recent/extractasincluderefactoring">Details</a>).</li>
+ <li>Improved diagnostics for class loading and rendering errors: Class loading and rendering
+ error messages are more useful and provide better information about the root cause of the
+ error.</li>
+ <li>Improved error handling to prevent drag and reordering operations from adding children
+ into an {@link android.widget.AdapterView}.</li>
+ <li>Outline reordering: Reordering your views in the Outline tab is much easier
+ (<a href="http://tools.android.com/recent/outlineimprovements">Details</a>).</li>
+ <li>Fix for keybinding bug where keyboard shortcuts did not work (Issues
+ <a href="http://code.google.com/p/android/issues/detail?id=13231">13231</a> and
+ <a href="http://code.google.com/p/android/issues/detail?id=13134">13134</a>).</li>
+ <li>Fix for problems with Custom layout attribute menu (Issue
+ <a href="http://code.google.com/p/android/issues/detail?id=13134">13134</a>).</li>
+ <li>Automatic configuration for various view types: Certain views have properties configured
+ by default. For example, the width of an {@link android.widget.EditText} object is set to
+ <code>match_parent</code> when added to a vertical {@link android.widget.LinearLayout}
+ or a default image is added to an {@link android.widget.ImageButton}.</li>
+ <li>Previews during dragging: Dragging from the palette or dragging within the layout editor
+ now shows live previews of the dragged item.</li>
+ <li>Navigation improvements: In the Layout Editor, double-clicking Views jumps to the
+ corresponding XML element. In the Outline view, double-clicking opens the Properties view.</li>
+ <li>The editor has Honeycomb style animation preview support.</li>
+ <li>Improved rendering support for various Views (such as TabHosts and SlidingDrawers) in
+ Honeycomb (Issues <a href="http://code.google.com/p/android/issues/detail?id=3162">3162</a>
+ and <a href="http://code.google.com/p/android/issues/detail?id=13092">13092</a>).</li>
+ <li>Included layouts can be rendered and edited in the context of the layouts that include
+ them. From a layout using an <a href="{@docRoot}guide/topics/resources/layout-resource.html#include-element">
+ <code><include></code></a> tag, double-clicking on the
+ <a href="{@docRoot}guide/topics/resources/layout-resource.html#include-element">
+ <code><include></code></a> element edits the referenced layout in the context of the
+ current layout. Additionally, when editing a layout that is included by other layouts,
+ you can quickly change between context layouts, by right clicking in the editor and choosing
+ <strong>Show included in...</strong>. This feature is only available in Honeycomb.</li>
+ </ul>
+ </li>
+ <li>This release fixes many other bugs, but the most important ones are listed below:
+ <ul>
+ <li>Fixed issue that prevented launching debug builds on productions devices when
+ <code>debuggable=true</code> was not set in the Android manifest.</li>
+ <li>The LogCat view in DDMS properly handles UTF-8 characters.</li>
+ <li>The SDK Manager is more reliable on Windows
+ (<a href="http://tools.android.com/recent/sdkmanagerfixes">Details</a>).</li>
+ <li>A JUnit initialization bug that prevented you from working with JUnit tests was fixed
+ (Issue <a href="http://code.google.com/p/android/issues/detail?id=12411">12411</a>).</li>
+ </ul>
+</li>
+ </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+
+
+
+<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" />
ADT 8.0.1</a> <em>(December 2010)</em>
<div class="toggleme">
@@ -121,7 +230,7 @@
<p>Also see the recent release notes for 8.0.0, below.</p>
</dd>
</dl>
- </div>
+</div>
</div>
diff --git a/docs/html/sdk/ndk/index.jd b/docs/html/sdk/ndk/index.jd
index 8b27f37..2c3fd6a 100644
--- a/docs/html/sdk/ndk/index.jd
+++ b/docs/html/sdk/ndk/index.jd
@@ -59,11 +59,64 @@
}
</style>
+
<div class="toggleable open">
<a href="#"
onclick="return toggleDiv(this)"><img src="{@docRoot}assets/images/triangle-opened.png"
class="toggle-img"
height="9px"
+ width="9px" /> Android NDK, Revision 5b</a> <em>(January 2011)</em>
+
+ <div class="toggleme">
+ <p>This release of the NDK does not include any new features compared to r5. The r5b release addresses the
+ following problems in the r5 release:
+ </p>
+ <ul>
+ <li>The r5 binaries required glibc 2.11, but the r5b binaries are generated with a special
+ toolchain that targets glibc 2.7 or higher instead. The Linux toolchain binaries now run on Ubuntu 8.04 or higher. </li>
+ <li>Fixes a compiler bug in the arm-linux-androideabi-4.4.3 toolchain.
+ The previous binary generated invalid thumb instruction sequences when
+ dealing with signed chars.</li>
+ <li>Adds missing documentation for the
+ "gnustl_static" value for APP_STL, that allows you to link against
+ a static library version of GNU libstdc++. </li>
+ <li>The following <code>ndk-build</code> issues are fixed:
+ <ul>
+ <li>A bug that created inconsistent dependency files when a
+ compilation error occured on Windows. This prevented a proper build after
+ the error was fixed in the source code.</li>
+ <li>A Cygwin-specific bug where using very short paths for
+ the Android NDK installation or the project path led to the
+ generation of invalid dependency files. This made incremental builds
+ impossible.</li>
+ <li>A typo that prevented the cpufeatures library from working correctly
+ with the new NDK toolchain.</li>
+ <li>Builds in Cygwin are faster by avoiding calls to <code>cygpath -m</code>
+ from GNU Make for every source or object file, which caused problems
+ with very large source trees. In case this doesn't work properly, define <code>NDK_USE_CYGPATH=1</code> in your
+ environment to use <code>cygpath -m</code> again.</li>
+ <li>The Cygwin installation now notifies the user of invalid installation paths that contain spaces. Previously, an invalid path
+ would output an error that complained about an incorrect version of GNU Make, even if the right one was installed.
+ </ul>
+ </li>
+ <li>Fixed a typo that prevented the <code>NDK_MODULE_PATH</code> environment variable from working properly when
+ it contained multiple directories separated with a colon. </li>
+ <li>The <code>prebuilt-common.sh</code> script contains fixes to check the compiler for 64-bit
+ generated machine code, instead of relying on the host tag, which
+ allows the 32-bit toolchain to rebuild properly on Snow Leopard. The toolchain rebuild scripts now also support
+ using a 32-bit host toolchain.</li>
+ <li>A missing declaration for <code>INET_ADDRSTRLEN</code> was added to <code><netinet/in.h></code>.</li>
+ <li>Missing declarations for <code>IN6_IS_ADDR_MC_NODELOCAL</code> and <code>IN6_IS_ADDR_MC_GLOBAL</code> were added to <code><netinet/in6.h></code>.</li>
+ <li>'asm' was replaced with '__asm__' in <code><asm/byteorder.h></code> to allow compilation with <code>-std=c99</code>.</li>
+ </ul>
+ </div>
+ </div>
+
+<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" /> Android NDK, Revision 5</a> <em>(December 2010)</em>
<div class="toggleme">
@@ -73,7 +126,7 @@
graphics and window management, assets, and storage. Developers can also implement the
Android application lifecycle in native code with help from the new
{@link android.app.NativeActivity} class. For detailed information describing the changes in this
- release, read the CHANGES.HTML document included in the downloaded NDK package.
+ release, read the <code>CHANGES.HTML</code> document included in the downloaded NDK package.
</p>
<dl>
<dt>General notes:</dt>
diff --git a/docs/html/sdk/oem-usb.jd b/docs/html/sdk/oem-usb.jd
new file mode 100644
index 0000000..14015f5
--- /dev/null
+++ b/docs/html/sdk/oem-usb.jd
@@ -0,0 +1,81 @@
+page.title=OEM USB Drivers
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>See also</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/developing/device.html">Developing on a Device</a></li>
+ <li><a href="{@docRoot}sdk/win-usb.html">Google USB Driver</a></li>
+ </ol>
+</div>
+</div>
+
+<p>If you are developing on Windows and would like to connect an Android-powered device
+ to test your applications, then you need to install the appropriate USB driver. This document
+provides links to the web sites for several device original equipment manufacturers (OEMs),
+where you can download the appropriate USB driver for your device. However, this list is
+not exhaustive for all available Android-powered devices.</p>
+
+<p>If your device is one of the Android Developer Phones (ADP), a Nexus One, or a Nexus S,
+then you should instead use the <a href="{@docRoot}sdk/win-usb.html">Google USB Driver</a>.</p>
+
+<p class="note"><strong>Note:</strong> If you're developing on Mac OS X or Linux, then you probably
+ don't need to install a USB driver. Refer to <a
+ href="{@docRoot}guide/developing/device.html#setting-up">Setting up a Device</a> to start
+ development with a device.</p>
+
+<p>For instructions about how to install the driver on Windows, follow the guide for <a
+ href="{@docRoot}sdk/win-usb.html#InstallingDriver">Installing the USB Driver</a>.</p>
+
+<p class="table-caption"><strong>Table 1.</strong> Links to OEM USB drivers</p>
+<table><tr>
+ <th>OEM</th>
+ <th>Driver URL</th></tr>
+<tr><td>Acer</td> <td><a
+href="http://www.acer.com/worldwide/support/mobile.html">http://www.acer.com/worldwide/support/
+mobile.html</a>
+ </td></tr>
+
+<tr><td>Dell</td> <td>
+ <a href="http://support.dell.com/support/downloads/index.aspx?c=us&cs=19&l=en&s=dhs&~ck=anavml">http://support.dell.com/support/downloads/index.aspx?c=us&cs=19&l=en&s=dhs&~ck=anavml</a> </td></tr>
+
+<tr><td>Foxconn</td> <td><a
+href="http://drivers.cmcs.com.tw/">http://drivers.cmcs.com.tw/</a></td>
+</tr><tr><td>Garmin-Asus</td> <td><a
+href="https://www.garminasus.com/en_US/support/pcsync/">https://www.garminasus.com/en_US/support/
+pcsync/</a></td>
+</tr><tr><td>HTC</td> <td><a href="http://www.htc.com ">http://www.htc.com </a> <br>Click on the
+support tab to select your products/device. Different regions will have different links.</td>
+</tr>
+<tr><td>Huawei</td> <td><a
+href="http://www.huaweidevice.com/worldwide/downloadCenter.do?method=list&flay=software&directoryId=
+20&treeId=0">http://www.huaweidevice.com/worldwide/downloadCenter.do?method=list&flay=software&
+directoryId=20&treeId=0</a></td>
+</tr><tr><td>KT Tech</td> <td><a
+href="http://www.kttech.co.kr/cscenter/download05.asp">http://www.kttech.co.kr/cscenter/download05.
+asp</a> for EV-S100(Take)</td>
+</tr><tr><td>LGE</td> <td><a
+href="http://www.lg.com/us/mobile-phones/mobile-support/mobile-lg-mobile-phone-support.jsp">http://
+www.lg.com/us/mobile-phones/mobile-support/mobile-lg-mobile-phone-support.jsp</a></td>
+</tr><tr><td>Motorola</td> <td><a
+href="http://developer.motorola.com/docstools/USB_Drivers/">http://developer.motorola.com/docstools/
+USB_Drivers/</a></td>
+</tr><tr><td>Pantech</td> <td><a
+href="http://www.isky.co.kr/cs/software/software.sky?fromUrl=index">http://www.isky.co.kr/cs/
+software/software.sky?fromUrl=index</a></td>
+</tr><tr><td>Samsung</td> <td><a
+href="http://www.samsung.com/us/support/downloads">http://www.samsung.com/us/support/downloads</a></
+td>
+</tr><tr><td>Sharp</td> <td><a
+href="http://k-tai.sharp.co.jp/support/">http://k-tai.sharp.co.jp/support/</a></td>
+</tr><tr><td>SK Telesys</td> <td><a
+href="http://www.sk-w.com/service/wDownload/wDownload.jsp">http://www.sk-w.com/service/wDownload/
+wDownload.jsp</a></td></tr><tr>
+<td>Sony Ericsson</td> <td><a
+href="http://developer.sonyericsson.com/wportal/devworld/search-downloads/android">http://developer.
+sonyericsson.com/wportal/devworld/search-downloads/android</a></td></tr><tr>
+<td>ZTE</td> <td><a
+href="http://www.zte.com.cn/cn/products/mobile/services_support/index.jsp">http://www.zte.com.cn/cn/
+products/mobile/services_support/index.jsp</a></td></tr>
+</table>
diff --git a/docs/html/sdk/preview/start.jd b/docs/html/sdk/preview/start.jd
new file mode 100644
index 0000000..7e816c1
--- /dev/null
+++ b/docs/html/sdk/preview/start.jd
@@ -0,0 +1,265 @@
+page.title=Getting Started with the Android 3.0 Preview
+@jd:body
+
+<p>Welcome to Android 3.0!</p>
+
+<p>Android 3.0 is the next major release of the Android platform and is optimized for tablet
+devices. We're offering a preview SDK so you can get a head-start developing
+applications for it or simply optimize your existing application for upcoming
+tablets.</p>
+
+
+<h3>What is the preview SDK?</h3>
+
+<p>The Android 3.0 preview SDK is an early look at the upcoming version of Android 3.0, for
+developers only.</p>
+
+<p>The preview SDK includes:</p>
+<ul>
+ <li>An early Android 3.0 system image for use in the Android emulator</li>
+ <li>An Android 3.0 library with non-final APIs</li>
+ <li>A new WXGA emulator skin for an extra large Android Virtual Device</li>
+ <li>New documentation for Android 3.0, including a complete API reference, new developer guides,
+and an API differences report between Android 3.0 and 2.3.</li>
+</ul>
+
+<div class="note">
+<p><strong>Be aware that:</strong></p>
+<ul>
+ <li>The APIs in the preview SDK are <strong>not final</strong>. Some APIs may change in behavior
+or availability when the final SDK is made available.</li>
+ <li>You <strong>cannot</strong> publish an application that's built against the preview
+SDK—you can only run an application built against the preview SDK on the Android
+emulator.</li>
+ <li>The documentation on <a href="http://developer.android.com">developer.android.com</a>
+does <strong>not</strong> include the Android 3.0 documentation—to read the API reference and
+developer guides for Android 3.0, you must install the Android 3.0 preview documentation from
+the AVD and SDK Manager.</li>
+</ul>
+</div>
+
+
+
+<h3>How do I start?</h3>
+
+<ol>
+ <li><a href="#Setup">Set up the preview SDK</a></li>
+ <li>Then choose your app adventure:
+ <ol type="a">
+ <li><a href="#Optimize">Optimize Your App for Tablets</a>
+ <p>When you have an existing application and you want to maintain compatibility with
+older versions of Android.</p>
+ </li>
+ <li><a href="#Upgrade">Upgrade or Develop a New App for Tablets</a>
+ <p>When you want to upgrade your application to use APIs introduced in Android 3.0 or
+ create an all new application targeted to tablet devices.</p></li>
+ </ol>
+ </li>
+</ol>
+
+
+
+
+<h2 id="Setup">Set Up the Preview SDK</h2>
+
+<p>To start using the Android 3.0 preview SDK, set up your existing Android SDK with the new
+platform:</p>
+<p>(If you don't have an existing SDK, <a href="{@docRoot}sdk/index.html">download it
+now</a>.)</p>
+<ol>
+ <li><a href="{@docRoot}sdk/adding-components.html#launching">Launch the Android SDK and AVD
+Manager</a> and install the following:
+ <ul>
+ <li>SDK Platform Android 3.0 Preview</li>
+ <li>Android SDK Tools, revision 9</li>
+ <li>Documentation for Android 'Honeycomb' Preview</li>
+ <li>Samples for SDK API Honeycomb Preview</li>
+ </ul>
+ </li>
+ <li><a href="{@docRoot}guide/developing/other-ide.html#AVD">Create an AVD</a> for tablets: set
+the target to "Android 3.0 (Preview)" and the skin to "WXGA".</li>
+</ol>
+
+
+<h3>About Emulator Performance</h3>
+
+<p>Because the Android emulator must simulate the ARM instruction set architecture on your
+computer and the WXGA screen is significantly larger than what the emulator
+normally handles, emulator performance is much slower than usual.</p>
+
+<p>We're working hard to resolve the performance issues and it will improve in future releases.
+Unfortunately, the emulator will perform slowly during your trial with the preview SDK. Please
+continue to use the emulator to evaluate your application's appearance and functionality on Android
+3.0.</p>
+
+<p class="note"><strong>Tip:</strong> To improve the startup time for the emulator, enable
+snapshots for the AVD when you create it with the SDK and AVD Manager (there's a checkbox in
+the GUI). Then, start the AVD from the manager and check <b>Launch from snapshot</b> and <b>Save to
+snapshot</b>. This way, when you close the emulator, a snapshot of the AVD state is saved and
+used to quickly relaunch the AVD next time. However, when you choose to save a snapshot, the
+emulator will be slow to close, so you might want to enable <b>Save to
+snapshot</b> only for the first time you launch the AVD.</p>
+
+
+
+<h2 id="Optimize">Optimize Your Application for Tablets</h2>
+
+<p>If you've already developed an application for Android, there are a few things you can do
+to optimize it for a tablet experience, without changing the minimum platform version required (you
+don't need to change the manifest {@code minSdkVersion}).</p>
+
+<p class="note"><strong>Note:</strong> All Android applications are forward-compatible, so
+there's nothing you <em>have to</em> do—if your application is a good citizen of the Android
+APIs, your app should work fine on devices running Android 3.0. However, in order to provide users
+a better experience when running your app on an Android 3.0 tablet, we recommend that you update
+your application to adapt to the new system theme and add optimize your application for larger
+screens.</p>
+
+<p>Here's what you can do to optimize your application for tablets running Android
+3.0:</p>
+
+<ol>
+ <li><b>Test your current application on Android 3.0</b>
+ <ol>
+ <li>Build your application as-is and install it on your WXGA AVD (created above).</li>
+ <li>Perform your usual tests to be sure everything works and looks as expected.</li>
+ </ol>
+ </li>
+
+ <li><b>Apply the new "Holographic" theme to your application</b>
+ <ol>
+ <li>Open your manifest file and update the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element to
+set {@code android:targetSdkVersion} to {@code "Honeycomb"}. For example:
+<pre>
+<manifest ... >
+ <uses-sdk android:minSdkVersion="4"
+ android:targetSdkVersion="Honeycomb" />
+ <application ... >
+ ...
+ <application>
+</manifest>
+</pre>
+ <p class="note"><strong>Note:</strong> The API Level value "Honeycomb" is a provisional API
+Level that is valid only while testing against the preview SDK. You
+<strong>should not</strong> publish your application using this API Level. When the final version of
+the Android 3.0 SDK is made available, you must change this value to the real API Level that will be
+specified for Android 3.0. For more information, read about <a
+href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a>.</p>
+ <p>By targeting the Android 3.0 platform, the system automatically applies the Holographic theme
+to each of your activities, when running on an Android 3.0 device.</p>
+ </li>
+ <li>Continue to build against your application's {@code minSdkVersion}, but install it
+on the Android 3.0 AVD. Perform more testing on your application to be sure that your user interface
+works well with the Holographic theme.
+ <p class="note"><strong>Note:</strong> If you've applied themes to your activities already,
+they will override the Holographic theme that the system applies when you set the {@code
+android:targetSdkVersion} to {@code "Honeycomb"}.
+Once the Android 3.0 APIs are finalized and an official API Level is assigned, you can use
+the <a href="{@docRoot}guide/topics/resources/providing-resources.html#VersionQualifier">system
+version qualifier</a> to provide an alternative theme that's based on the Holographic theme when
+your application is running on Android 3.0.</p>
+ </ol>
+ </li>
+
+ <li><b>Supply alternative layout resources for xlarge screens</b>
+ <p>As discussed in the guide to <a
+href="{@docRoot}guide/practices/screens_support.html">Supporting Multiple Screens</a>, Android
+2.3 and above support the <code>xlarge</code> resource qualifier, which you should use to supply
+alternative layouts for extra large screens.</p>
+ <p>By providing alternative layouts for some of your activities when running on extra large
+screens, you can improve the user experience of your application on a tablet without using any
+new APIs.</p>
+ <p>For example, here are some things to consider when creating a new layout for tables:</p>
+ <ul>
+ <li>Landscape layout: The "normal" orientation for tablets is usually landscape (wide), so
+you should be sure that your activities offer an appropriate layout for such a wide viewing
+area.</li>
+ <li>Button position: Consider whether the position of the most common buttons in your UI are
+easily accessible while holding a tablet with two hands.</li>
+ </ul>
+ </li>
+</ol>
+
+ <p>In general, always be sure that your application follows the <a
+href="{@docRoot}guide/practices/screens_support.html#screen-independence">Best Practices
+for Screen Independence</a>.</p>
+
+
+
+
+<h2 id="Upgrade">Upgrade or Develop a New App for Tablets</h2>
+
+<p>If you want to develop something truly for tablets running Android 3.0, then you need to use new
+APIs available in Android 3.0. This section introduces some of the new features that you
+should use.</p>
+
+<p>The first thing to do when you create a project with the Android 3.0 preview is set the <a
+href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code <uses-sdk>}</a> element to
+use {@code "Honeycomb"} for the {@code android:minSdkVersion}. For example:</p>
+
+<pre>
+<manifest ... >
+ <uses-sdk android:minSdkVersion="Honeycomb" />
+ <application ... >
+ ...
+ <application>
+</manifest>
+</pre>
+
+<p class="note"><strong>Note:</strong> The API Level value "Honeycomb" is a provisional API
+Level that is valid only while building and testing against the preview SDK. You
+<strong>cannot</strong> publish your application using this API Level. When the final version of the
+Android 3.0 SDK is made available, you must change this value to the real API Level that is
+specified for Android 3.0. For more information, read about <a
+href="{@docRoot}guide/appendix/api-levels.html">Android API Levels</a>.</p>
+
+<p>Be sure that the <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">{@code
+<uses-sdk>}</a> element appears <strong>before</strong> the <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>
+element.</p>
+
+<p>By targeting the Android 3.0 platform (and declaring it before <a
+href="{@docRoot}guide/topics/manifest/application-element.html">{@code <application>}</a>),
+the system automatically applies the new Holographic theme to each of your
+activities.</p>
+
+
+
+<h3>Publishing your app for tablets only</h3>
+
+<p>Additionally, you should decide whether your application is for <em>only</em> tablet devices
+(specifically, <em>xlarge</em> devices) or for devices of all sizes that may run Android 3.0.</p>
+
+<p>If your application is <em>only</em> for tablets (<em>xlarge</em> screens; not for mobile
+devices/phones), then you should include the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+<supports-screens>}</a> element in your manifest with all sizes except for xlarge declared
+false. For example:</p>
+
+<pre>
+<manifest ... >
+ <uses-sdk android:minSdkVersion="Honeycomb" />
+ <supports-screens android:smallScreens="false"
+ android:normalScreens="false"
+ android:largeScreens="false"
+ android:xlargeScreens="true" />
+ <application ... >
+ ...
+ <application>
+</manifest>
+</pre>
+
+<p>With this declaration, you indicate that your application does not support any screen size except
+extra large. External services such as Android Market may use this to filter your application
+from devices that do not have an extra large screen.</p>
+
+<p>Otherwise, if you want your application to be available to both small devices (phones) and large
+devices (tablets), do <em>not</em> include the <a
+href="{@docRoot}guide/topics/manifest/supports-screens-element.html">{@code
+<supports-screens>}</a> element.</p>
+
+<div class="special">
+<p>To learn more about some of the new APIs,
+see the <a href="{@docRoot}sdk/android-3.0.html">Android 3.0 Platform</a> document.</p>
+</div>
diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs
index 2780135..226f880 100644
--- a/docs/html/sdk/sdk_toc.cs
+++ b/docs/html/sdk/sdk_toc.cs
@@ -42,11 +42,11 @@
<ul>
<li><a href="<?cs var:toroot ?>sdk/preview/start.html">Getting Started</a> <span class="new">new!</span></li>
<li class="toggle-list">
- <div><a href="<?cs var:toroot ?>sdk/preview/platform.html">
+ <div><a href="<?cs var:toroot ?>sdk/android-3.0.html">
<span class="en">Android 3.0 Platform</span></a> <span class="new">new!</span></div>
<ul>
- <li><a href="<?cs var:toroot ?>sdk/preview/highlights.html">Platform Highlights</a></li>
- <li><a href="<?cs var:toroot ?>sdk/api_diff/honeycomb/changes.html">API Differences Report »</a></li>
+ <li><a href="<?cs var:toroot ?>sdk/api_diff/honeycomb/changes.html">API Differences Report
+»</a></li>
</ul>
</li>
</ul>
@@ -99,8 +99,7 @@
</ul>
<ul>
<li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r8</a> <span class="new">new!</span></li>
- <li><a href="<?cs var:toroot ?>sdk/win-usb.html">USB Driver for
- Windows, r4</a> <span class="new">new!</span>
+ <li><a href="<?cs var:toroot ?>sdk/win-usb.html">Google USB Driver, r4</a> <span class="new">new!</span>
</li>
</ul>
</li>
@@ -156,6 +155,9 @@
<span style="display:none" class="zh-TW"></span>
</h2>
<ul>
+ <li><a href="<?cs var:toroot ?>sdk/oem-usb.html">
+ <span class="en">OEM USB Drivers</span>
+ </a></li>
<li><a href="<?cs var:toroot ?>sdk/requirements.html">SDK System Requirements</a></li>
<!-- <li><a href="<?cs var:toroot ?>sdk/RELEASENOTES.html">SDK Release
Notes</a></li> -->
diff --git a/docs/html/sdk/tools-notes.jd b/docs/html/sdk/tools-notes.jd
index fb8636e..b832628 100644
--- a/docs/html/sdk/tools-notes.jd
+++ b/docs/html/sdk/tools-notes.jd
@@ -15,6 +15,7 @@
href="{@docRoot}sdk/adding-components.html#UpdatingComponents">Updating SDK
Components</a>. </p>
+
<h2 id="notes">Revisions</h2>
<p>The sections below provide notes about successive releases of
@@ -64,6 +65,58 @@
<div class="toggleable opened">
<a href="#" onclick="return toggleDiv(this)">
<img src="{@docRoot}assets/images/triangle-opened.png" class="toggle-img" height="9px" width="9px" />
+SDK Tools, Revision 9</a> <em>(January 2011)</em>
+ <div class="toggleme">
+ <dl>
+<dt>Dependencies:</dt>
+<dd>
+<p>If you are developing in Eclipse with ADT, note that the SDK Tools r9 is
+designed for use with ADT 9.0.0 and later. After installing SDK Tools r9, we
+highly recommend updating your ADT Plugin to 9.0.0.</p>
+
+<p>If you are developing outside Eclipse, you must have <a href="http://ant.apache.org/">Apache
+Ant</a> 1.8 or later.</p>
+
+<dt>Upgrading to SDK Tools r9:</dt>
+<dd>
+<p>If you are upgrading to SDK Tools r9 from SDK Tools r7 or earlier, the default installed location
+for the <code>adb</code> tool has changed from <code><<em>SDK</em>>/tools/adb</code> to
+<code><<em>SDK</em>>/platform-tools/adb</code>. This means that you should
+add the new location to your PATH and modify any custom build scripts to
+reference the new location. Copying the <code>adb</code> executable from the new
+location to the old is not recommended, since subsequent updates to the SDK
+Tools will delete the file.</p>
+</dd>
+
+<dt>General notes:</dt>
+<dd>
+ <ul>
+ <li>The default ProGuard configuration, <code>proguard.cfg</code>, now ignores the following classes:
+ <ul>
+ <li>classes that extend {@link android.preference.Preference}</li>
+ <li>classes that extend {@link android.app.backup.BackupAgentHelper}</li>
+ </ul>
+ </li>
+ <li>Ant lib rules now allow you to override <code>java.encoding</code>, <code>java.source</code>,
+ and <code>java.target</code> properties.</li>
+ <li>The default encoding for the <code>javac</code> Ant task is now UTF-8.</li>
+ <li>The LogCat view in DDMS now properly displays UTF-8 characters.</li>
+ <li>The SDK Manager is more reliable on Windows. For details on the improvements, see the
+ <a href="http://tools.android.com/recent/sdkmanagerfixes">Android Tools Project Site</a>. </li>
+ <li>If you enabled snapshots for an AVD, they are automatically captured. The emulator also now restores to the state when
+ it last closed almost instantly.</li>
+ <li>Fixed the missing JAR file error that prevented <code>draw9patch</code> from running.</li>
+ <li>Fixed the Windows launch scripts <code>hierarchyviewer</code> and <code>ddms</code> to support
+ the new location of <code>adb</code>.</li>
+ </ul>
+</dd>
+</dl>
+</div>
+</div>
+
+<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" />
SDK Tools, Revision 8</a> <em>(December 2010)</em>
<div class="toggleme">
diff --git a/docs/html/sdk/win-usb.jd b/docs/html/sdk/win-usb.jd
index 1f74ffe..ffaec4c 100644
--- a/docs/html/sdk/win-usb.jd
+++ b/docs/html/sdk/win-usb.jd
@@ -1,4 +1,4 @@
-page.title=USB Driver for Windows
+page.title=Google USB Driver
@jd:body
<div id="qv-wrapper">
@@ -6,27 +6,48 @@
<h2>In this document</h2>
<ol>
<li><a href="#notes">Revisions</a></li>
- <li><a href="#WinUsbDriver">Installing the USB Driver for Windows</a></li>
+ <li><a href="#WinUsbDriver">Downloading the Google USB Driver</a></li>
+ <li><a href="#InstallingDriver">Installing the USB Driver</a>
+ <ol>
+ <li><a href="#Win7">Windows 7</a></li>
+ <li><a href="#WinXp">Windows XP</a></li>
+ <li><a href="#WinVista">Windows Vista</a></li>
+ </ol>
+ </li>
</ol>
<h2>See also</h2>
<ol>
- <li><a
- href="{@docRoot}guide/developing/device.html">Developing on a
- Device</a></li>
- <li><a
- href="adding-components.html">Adding SDK Components</a></li>
+ <li><a href="{@docRoot}guide/developing/device.html">Developing on a Device</a></li>
+ <li><a href="{@docRoot}sdk/adding-components.html">Adding SDK Components</a></li>
+ <li><a href="{@docRoot}sdk/oem-usb.html">OEM USB Drivers</a></li>
</ol>
</div>
</div>
-<p>The USB driver for Windows is a downloadable component for the
-Android SDK. If you are developing on Windows and would like to
-connect an Android-powered device to test your applications, then you will need
-to install the USB driver.</p>
+<p>The Google USB driver is a downloadable component for Windows developers, available
+for download from the AVD and SDK Manager.</p>
-<p>This document provides information about the latest version of the
-USB driver and a guide to installing the driver on your development
-computer.</p>
+<p>The Google USB Driver is only for Android Developer Phones (ADP), Nexus One, and Nexus S.
+If you're using a different Android-powered device,
+then you need to get a USB driver from the device OEM. For help finding the appropriate
+driver, see the list of <a href="{@docRoot}sdk/oem-usb.html">OEM USB Drivers</a>.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <p>The Google USB driver for Windows provides support for the following
+Android-powered devices:</p>
+ <ul>
+ <li>ADP1 / T-Mobile G1*</li>
+ <li>ADP2 / Google Ion / T-Mobile myTouch 3G*</li>
+ <li>Verizon Droid*</li>
+ <li>Nexus One</li>
+ <li>Nexus S</li>
+ </ul>
+ <p>* <em>Or similar hardware on other carriers</em></p>
+ <p>Any additional devices will require Windows drivers provided by
+the hardware manufacturer. See <a href="{@docRoot}sdk/oem-usb.html">OEM USB Drivers</a>.</p>
+</div>
+</div>
<p class="note"><strong>Note:</strong>
If you're developing on Mac OS X or Linux, then you do not need to install a
@@ -34,6 +55,12 @@
href="{@docRoot}guide/developing/device.html#setting-up">Setting up a
Device</a> to start development with a device.</p>
+<p>The sections below provide instructions on how to download the USB Driver
+for Windows and install it on your development computer. </p>
+
+
+
+
<h2 id="notes">Revisions</h2>
<p>The sections below provide notes about successive revisions of the USB Driver
@@ -132,77 +159,49 @@
</div>
</div>
-<h2 id="WinUsbDriver">Installing the USB Driver for Windows</h2>
-<div class="sidebox-wrapper">
-<div class="sidebox">
- <p>The USB driver for Windows provides support for the following
-Android-powered
-devices:</p>
- <ul>
- <li>ADP1 / T-Mobile G1*</li>
- <li>ADP2 / Google Ion / T-Mobile myTouch 3G*</li>
- <li>Verizon Droid*</li>
- <li>Nexus One</li>
- <li>Nexus S</li>
- </ul>
- <p>* <em>Or similar hardware on other carriers</em></p>
- <p>Any additional devices will require Windows drivers provided by
-the hardware manufacturer.</p>
+<h2 id="WinUsbDriver">Downloading the Google USB Driver</h2>
+
+<div class="figure" style="width:498px;margin:0">
+ <img src="{@docRoot}images/developing/sdk-usb-driver.png" alt="" />
+ <p class="img-caption"><strong>Figure 1.</strong> The SDK and AVD Manager
+ with the Google USB Driver selected.</p>
</div>
-</div>
-
-
-<p>The sections below provide instructions on how to download the USB Driver
-for Windows and install it on your development computer. </p>
-
-<h3>Downloading the USB Driver for Windows</h3>
<p>The USB Driver for Windows is available for download as an optional SDK
component. You need the driver only if you are developing on Windows and
-want to connect an Android-powered device to your development environment
-over USB. </p>
-
-<p>To install the driver or upgrade your existing driver to the latest
-revision, you must first download the driver to your development computer. </p>
+want to connect an Android-powered device (ADP, Nexus One, or Nexus S) to your
+development environment over USB. </p>
<p>To download the driver, use the Android SDK and AVD Manager tool that is
-included with the Android SDK. If you haven't yet installed the Android SDK, as
-described in <a href="installing.html">Installing the Android SDK</a>, please do
-so before continuing with the driver installation. </p>
+included with the <a href="{@docRoot}sdk/index.html">Android SDK</a>:</p>
+<ol>
+ <li>Launch the SDK and AVD Manager by double-clicking <code>SDK Manager.exe</code>,
+ at the root of your SDK directory.</li>
+ <li>Expand the <em>Third party Add-ons</em> and <em>Google Inc. add-ons</em>.</li>
+ <li>Check <strong>Google Usb Driver package</strong> and click <strong>Install selected</strong>.</li>
+ <li>Proceed to install the package. When done, the driver files are
+downloaded into the <code><sdk>\google-usb_driver\</code> directory.</li>
+</ol>
-<p>When you are ready to download the driver, follow the instructions given in
-<a href="adding-components.html">Adding SDK Components</a> to launch the Android
-SDK and AVD Manager. From the <strong>Available Packages</strong> panel, select
-"Usb Driver Package" and download it to your computer. The driver files are
-downloaded into the <code><sdk>\google-usb_driver\</code> directory.</p>
-<p>After the download, follow the instructions below to install or upgrade the
-driver, based on your needs and Windows operating system version. If you are
-connecting an Android-powered device to your computer for the first time, follow
-the below procedure to "Perform a fresh installation." If you have installed one
-of the older USB drivers and would like to upgrade to the latest version, follow
-the procedure to "Upgrade an existing driver."</p>
-<p>Once you've completed the USB driver installation,
-please see <a
+<h2 id="InstallingDriver">Installing the USB Driver</h2>
+
+<p>Once you've downloaded your USB driver, follow the instructions below to install or upgrade the
+driver, based on your version of Windows and whether you're installing for the first time
+or upgrading an existing driver.</p>
+
+<p class="note"><strong>Tip:</strong> When you finish the USB driver installation,
+see <a
href="{@docRoot}guide/developing/device.html">Developing on a Device</a> for
other important information about using an Android-powered device for
development.</p>
<ol class="nolist">
- <li><strong>Windows Vista:</strong>
- <ol class="nolist">
- <li><a href="#VistaFreshInstall">Perform a fresh installation</a></li>
- <li><a href="#VistaUpgrade">Upgrade an existing driver</a></li>
- </ol>
- </li>
- <li><strong>Windows XP:</strong>
- <ol class="nolist">
- <li><a href="#XPFreshInstall">Perform a fresh installation</a></li>
- <li><a href="#XPUpgrade">Upgrade an existing driver</a></li>
- </ol>
- </li>
+ <li><a href="#Win7">Windows 7</a></li>
+ <li><a href="#WinXp">Windows XP</a></li>
+ <li><a href="#WinVista">Windows Vista</a></li>
</ol>
@@ -213,94 +212,140 @@
driver. Making any other changes to the driver files may break the installation
process.</p>
-<h3 id="VistaFreshInstall">Windows Vista: Perform a fresh installation</h3>
-<p>To install the Android USB driver on Windows Vista for the first time:</p>
+<h3 id="Win7">Windows 7</h3>
+
+<p>To install the Android USB driver on Windows 7 for the first time:</p>
<ol>
- <li>Connect your Android-powered device to your computer's USB port. Windows
- will detect the device and launch the Found New Hardware wizard.</li>
- <li>Select "Locate and install driver software."</li>
- <li>Select "Don't search online."</li>
- <li>Select "I don't have the disk. Show me other options."</li>
- <li>Select "Browse my computer for driver software."</li>
- <li>Click "Browse..." and locate the folder where you copied the
- installation package. As long as you specified the exact location of the
- installation package, you may leave "Include subfolders" checked or
- unchecked—it doesn't matter.</li>
- <li>Click "Next." Vista may prompt you to confirm the privilege elevation
- required for driver installation. Confirm it.</li>
- <li>When Vista asks if you'd like to install the Google ADB Interface device,
- click "Install" to install the driver.</li>
+ <li>Connect your Android-powered device to your computer's USB port.</li>
+ <li>Right-click on <em>Computer</em> from your desktop or Windows Explorer,
+ and select <strong>Manage</strong>.</li>
+ <li>Select <strong>Devices</strong> in the left pane.</li>
+ <li>Locate and expand <em>Other device</em> in the right pane.</li>
+ <li>Right-click the device name (such as <em>Nexus S</em>) and select <strong>Update
+ Driver Software</strong>.
+ This will launch the Hardware Update Wizard.</li>
+ <li>Select <strong>Browse my computer for driver software</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.)</li>
+ <li>Click <strong>Next</strong> to install the driver.</li>
</ol>
-
-<h3 id="VistaUpgrade">Windows Vista: Upgrade an existing driver</h3>
-
-<p>To upgrade an existing Android USB driver on Windows Vista with the new
+<p>Or, to <em>upgrade</em> an existing Android USB driver on Windows 7 with the new
driver:</p>
<ol>
<li>Connect your Android-powered device to your computer's USB port.</li>
- <li>Right-click on "Computer" from your desktop or Windows Explorer,
- and select "Manage."</li>
- <li>Select "Device Manager" in the left pane of the Computer Management
+ <li>Right-click on <em>Computer</em> from your desktop or Windows Explorer,
+ and select <strong>Manage</strong>.</li>
+ <li>Select <strong>Device Manager</strong> in the left pane of the Computer Management
window.</li>
- <li>Locate and expand "ADB Interface" in the right pane.</li>
- <li>Right-click on "HTC Dream Composite ADB Interface", and select "Update
- Driver Software..."</li>
- <li>When Vista starts updating the driver, a prompt will ask how you want to
- search for the driver
- software. Select "Browse my computer for driver software."</li>
- <li>Click "Browse..." and locate the folder where you copied the
- installation package. As long as you specified the exact location of the
- installation package, you may leave "Include subfolders" checked or
- unchecked—it doesn't matter.</li>
- <li>Click "Next." Vista may prompt you to confirm the privilege elevation
- required for driver installation. Confirm it.</li>
- <li>When Vista asks if you'd like to install the Google ADB Interface device,
- click "Install" to install the driver.</li>
+ <li>Locate and expand <em>Android Phone</em> in the right pane.</li>
+ <li>Right-click <em>Android Composite ADB Interface</em> and select <strong>Update
+ Driver</strong>.
+ This will launch the Hardware Update Wizard.</li>
+ <li>Select <strong>Install from a list or specific location</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Select <strong>Search for the best driver in these locations</strong>; un-check
+<strong>Search removable media</strong>; and check <strong>Include this location in the
+search</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.)</li>
+ <li>Click <strong>Next</strong> to upgrade the driver.</li>
</ol>
-<h3 id="XPFreshInstall">Windows XP: Perform a fresh installation</h3>
+
+
+
+<h3 id="WinXp">Windows XP</h3>
<p>To install the Android USB driver on Windows XP for the first time:</p>
<ol>
<li>Connect your Android-powered device to your computer's USB port. Windows
will detect the device and launch the Hardware Update Wizard.</li>
- <li>Select "Install from a list or specific location" and click
- "Next."</li>
- <li>Select "Search for the best driver in these locations"; un-check "Search
- removable media"; and check "Include this location in the search."</li>
- <li>Click "Browse..." and locate the folder where you copied the installation
- package.</li>
- <li>Click "Next" to install the driver.</li>
+ <li>Select <strong>Install from a list or specific location</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Select <strong>Search for the best driver in these locations</strong>; un-check
+<strong>Search
+ removable media</strong>; and check <strong>Include
+this location in the search</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.)</li>
+ <li>Click <strong>Next</strong> to install the driver.</li>
</ol>
-
-<h3 id="XPUpgrade">Windows XP: Upgrade an existing driver</h3>
-
-<p>To upgrade an existing Android USB driver on Windows XP with the new
+<p>Or, to <em>upgrade</em> an existing Android USB driver on Windows XP with the new
driver:</p>
<ol>
<li>Connect your Android-powered device to your computer's USB port.</li>
- <li>Right-click on "My Computer" from your desktop or Windows Explorer,
- and select "Manage."</li>
- <li>Select "Device Manager" in the left pane of the Computer Management
- window.</li>
- <li>Locate and expand "Android Phone" in the right pane.</li>
- <li>Right-click "Android Composite ADB Interface" and select "Update
- Driver..."
+ <li>Right-click on <em>My Computer</em> from your desktop or Windows Explorer,
+ and select <strong>Manage</strong>.</li>
+ <li>Select <strong>Device Manager</strong> in the left pane.</li>
+ <li>Locate and expand <em>Android Phone</em> in the right pane.</li>
+ <li>Right-click <em>Android Composite ADB Interface</em> and select <strong>Update
+ Driver</strong>.
This will launch the Hardware Update Wizard.</li>
- <li>Select "Install from a list or specific location" and click
- "Next."</li>
- <li>Select "Search for the best driver in these locations"; un-check "Search
- removable media"; and check "Include this location in the search."</li>
- <li>Click "Browse..." and locate the folder where you copied the installation
- package.</li>
- <li>Click "Next" to install the driver.</li>
+ <li>Select <strong>Install from a list or specific location</strong> and click
+ <strong>Next</strong>.</li>
+ <li>Select <strong>Search for the best driver in these locations</strong>; un-check <strong>Search
+ removable media</strong>; and check <strong>Include
+this location in the search</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.)</li>
+ <li>Click <strong>Next</strong> to upgrade the driver.</li>
+</ol>
+
+
+
+<h3 id="WinVista">Windows Vista</h3>
+
+<p>To install the Android USB driver on Windows Vista for the first time:</p>
+
+<ol>
+ <li>Connect your Android-powered device to your computer's USB port. Windows
+ will detect the device and launch the Found New Hardware wizard.</li>
+ <li>Select <strong>Locate and install driver software</strong>.</li>
+ <li>Select <strong>Don't search online</strong>.</li>
+ <li>Select <strong>I don't have the disk. Show me other options</strong>.</li>
+ <li>Select <strong>Browse my computer for driver software</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.) As long as you specified the exact
+location of the
+ installation package, you may leave <strong>Include subfolders</strong> checked or
+ unchecked—it doesn't matter.</li>
+ <li>Click <strong>Next</strong>. Vista may prompt you to confirm the privilege elevation
+ required for driver installation. Confirm it.</li>
+ <li>When Vista asks if you'd like to install the Google ADB Interface device,
+ click <strong>Install</strong> to install the driver.</li>
+</ol>
+
+<p>Or, to <em>upgrade</em> an existing Android USB driver on Windows Vista with the new
+driver:</p>
+
+<ol>
+ <li>Connect your Android-powered device to your computer's USB port.</li>
+ <li>Right-click on <em>Computer</em> from your desktop or Windows Explorer,
+ and select <strong>Manage</strong>.</li>
+ <li>Select <strong>Device Manager</strong> in the left pane.</li>
+ <li>Locate and expand <em>ADB Interface</em> in the right pane.</li>
+ <li>Right-click on <em>HTC Dream Composite ADB Interface</em>, and select <strong>Update
+ Driver Software</strong>.</li>
+ <li>When Vista starts updating the driver, a prompt will ask how you want to
+ search for the driver
+ software. Select <strong>Browse my computer for driver software</strong>.</li>
+ <li>Click <strong>Browse</strong> and locate the USB driver folder. (The Google USB
+Driver is located in {@code <sdk>\google-usb_driver\}.) As long as you specified the
+exact location of the
+ installation package, you may leave <strong>Include subfolders</strong> checked or
+ unchecked—it doesn't matter.</li>
+ <li>Click <strong>Next</strong>. Vista might prompt you to confirm the privilege elevation
+ required for driver installation. Confirm it.</li>
+ <li>When Vista asks if you'd like to install the Google ADB Interface device,
+ click <strong>Install</strong> to upgrade the driver.</li>
</ol>
diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp
index 75edac6..ddbd220 100644
--- a/drm/common/IDrmManagerService.cpp
+++ b/drm/common/IDrmManagerService.cpp
@@ -382,7 +382,7 @@
}
data.writeInt32(playbackStatus);
- data.writeInt32(position);
+ data.writeInt64(position);
remote()->transact(SET_PLAYBACK_STATUS, data, &reply);
return reply.readInt32();
@@ -1111,7 +1111,7 @@
}
const status_t status
- = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt32());
+ = setPlaybackStatus(uniqueId, &handle, data.readInt32(), data.readInt64());
reply->writeInt32(status);
delete handle.decryptInfo; handle.decryptInfo = NULL;
diff --git a/graphics/java/android/graphics/Bitmap.java b/graphics/java/android/graphics/Bitmap.java
index e67ceed..2b4a410 100644
--- a/graphics/java/android/graphics/Bitmap.java
+++ b/graphics/java/android/graphics/Bitmap.java
@@ -165,10 +165,12 @@
}
/**
- * Free up the memory associated with this bitmap's pixels, and mark the
- * bitmap as "dead", meaning it will throw an exception if getPixels() or
- * setPixels() is called, and will draw nothing. This operation cannot be
- * reversed, so it should only be called if you are sure there are no
+ * Free the native object associated with this bitmap, and clear the
+ * reference to the pixel data. This will not free the pixel data synchronously;
+ * it simply allows it to be garbage collected if there are no other references.
+ * The bitmap is marked as "dead", meaning it will throw an exception if
+ * getPixels() or setPixels() is called, and will draw nothing. This operation
+ * cannot be reversed, so it should only be called if you are sure there are no
* further uses for the bitmap. This is an advanced call, and normally need
* not be called, since the normal GC process will free up this memory when
* there are no more references to this bitmap.
diff --git a/graphics/java/android/graphics/Canvas.java b/graphics/java/android/graphics/Canvas.java
index 184620b..89e725a 100644
--- a/graphics/java/android/graphics/Canvas.java
+++ b/graphics/java/android/graphics/Canvas.java
@@ -1175,8 +1175,11 @@
nativeDrawBitmapMatrix(mNativeCanvas, bitmap.ni(), matrix.ni(),
paint != null ? paint.mNativePaint : 0);
}
-
- private static void checkRange(int length, int offset, int count) {
+
+ /**
+ * @hide
+ */
+ protected static void checkRange(int length, int offset, int count) {
if ((offset | count) < 0 || offset + count > length) {
throw new ArrayIndexOutOfBoundsException();
}
diff --git a/graphics/java/android/graphics/Region.java b/graphics/java/android/graphics/Region.java
index e540806..27ea0f0 100644
--- a/graphics/java/android/graphics/Region.java
+++ b/graphics/java/android/graphics/Region.java
@@ -287,6 +287,10 @@
region2.mNativeRegion, op.nativeInt);
}
+ public String toString() {
+ return nativeToString(mNativeRegion);
+ }
+
//////////////////////////////////////////////////////////////////////////
public static final Parcelable.Creator<Region> CREATOR
@@ -357,6 +361,8 @@
return mNativeRegion;
}
+ private static native boolean nativeEquals(int native_r1, int native_r2);
+
private static native int nativeConstructor();
private static native void nativeDestructor(int native_region);
@@ -381,5 +387,5 @@
private static native boolean nativeWriteToParcel(int native_region,
Parcel p);
- private static native boolean nativeEquals(int native_r1, int native_r2);
+ private static native String nativeToString(int native_region);
}
diff --git a/graphics/java/android/renderscript/Allocation.java b/graphics/java/android/renderscript/Allocation.java
index 1789891..74cdf80 100644
--- a/graphics/java/android/renderscript/Allocation.java
+++ b/graphics/java/android/renderscript/Allocation.java
@@ -268,22 +268,105 @@
}
}
+ /**
+ * Copy an allocation from an array. This variant is not type
+ * checked which allows an application to fill in structured
+ * data from an array.
+ *
+ * @param d the source data array
+ */
+ public void copyFromUnchecked(int[] d) {
+ mRS.validate();
+ copy1DRangeFromUnchecked(0, mType.getCount(), d);
+ }
+ /**
+ * Copy an allocation from an array. This variant is not type
+ * checked which allows an application to fill in structured
+ * data from an array.
+ *
+ * @param d the source data array
+ */
+ public void copyFromUnchecked(short[] d) {
+ mRS.validate();
+ copy1DRangeFromUnchecked(0, mType.getCount(), d);
+ }
+ /**
+ * Copy an allocation from an array. This variant is not type
+ * checked which allows an application to fill in structured
+ * data from an array.
+ *
+ * @param d the source data array
+ */
+ public void copyFromUnchecked(byte[] d) {
+ mRS.validate();
+ copy1DRangeFromUnchecked(0, mType.getCount(), d);
+ }
+ /**
+ * Copy an allocation from an array. This variant is not type
+ * checked which allows an application to fill in structured
+ * data from an array.
+ *
+ * @param d the source data array
+ */
+ public void copyFromUnchecked(float[] d) {
+ mRS.validate();
+ copy1DRangeFromUnchecked(0, mType.getCount(), d);
+ }
+
+ /**
+ * Copy an allocation from an array. This variant is type
+ * checked and will generate exceptions if the Allocation type
+ * is not a 32 bit integer type.
+ *
+ * @param d the source data array
+ */
public void copyFrom(int[] d) {
mRS.validate();
copy1DRangeFrom(0, mType.getCount(), d);
}
+
+ /**
+ * Copy an allocation from an array. This variant is type
+ * checked and will generate exceptions if the Allocation type
+ * is not a 16 bit integer type.
+ *
+ * @param d the source data array
+ */
public void copyFrom(short[] d) {
mRS.validate();
copy1DRangeFrom(0, mType.getCount(), d);
}
+
+ /**
+ * Copy an allocation from an array. This variant is type
+ * checked and will generate exceptions if the Allocation type
+ * is not a 8 bit integer type.
+ *
+ * @param d the source data array
+ */
public void copyFrom(byte[] d) {
mRS.validate();
copy1DRangeFrom(0, mType.getCount(), d);
}
+
+ /**
+ * Copy an allocation from an array. This variant is type
+ * checked and will generate exceptions if the Allocation type
+ * is not a 32 bit float type.
+ *
+ * @param d the source data array
+ */
public void copyFrom(float[] d) {
mRS.validate();
copy1DRangeFrom(0, mType.getCount(), d);
}
+
+ /**
+ * Copy an allocation from a bitmap. The height, width, and
+ * format of the bitmap must match the existing allocation.
+ *
+ * @param b the source bitmap
+ */
public void copyFrom(Bitmap b) {
mRS.validate();
validateBitmapSize(b);
@@ -369,39 +452,114 @@
mRS.nAllocationGenerateMipmaps(getID());
}
- void copy1DRangeFromUnchecked(int off, int count, int[] d) {
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * not type checked which allows an application to fill in
+ * structured data from an array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, int[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- void copy1DRangeFromUnchecked(int off, int count, short[] d) {
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * not type checked which allows an application to fill in
+ * structured data from an array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, short[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 2, dataSize);
mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * not type checked which allows an application to fill in
+ * structured data from an array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, byte[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length, dataSize);
mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
- void copy1DRangeFromUnchecked(int off, int count, float[] d) {
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * not type checked which allows an application to fill in
+ * structured data from an array.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
+ public void copy1DRangeFromUnchecked(int off, int count, float[] d) {
int dataSize = mType.mElement.getSizeBytes() * count;
data1DChecks(off, count, d.length * 4, dataSize);
mRS.nAllocationData1D(getID(), off, 0, count, d, dataSize);
}
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * type checked and will generate exceptions if the Allocation
+ * type is not a 32 bit integer type.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
public void copy1DRangeFrom(int off, int count, int[] d) {
validateIsInt32();
copy1DRangeFromUnchecked(off, count, d);
}
+
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * type checked and will generate exceptions if the Allocation
+ * type is not a 16 bit integer type.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
public void copy1DRangeFrom(int off, int count, short[] d) {
validateIsInt16();
copy1DRangeFromUnchecked(off, count, d);
}
+
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * type checked and will generate exceptions if the Allocation
+ * type is not a 8 bit integer type.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
public void copy1DRangeFrom(int off, int count, byte[] d) {
validateIsInt8();
copy1DRangeFromUnchecked(off, count, d);
}
+
+ /**
+ * Copy part of an allocation from an array. This variant is
+ * type checked and will generate exceptions if the Allocation
+ * type is not a 32 bit float type.
+ *
+ * @param off The offset of the first element to be copied.
+ * @param count The number of elements to be copied.
+ * @param d the source data array
+ */
public void copy1DRangeFrom(int off, int count, float[] d) {
validateIsFloat32();
copy1DRangeFromUnchecked(off, count, d);
diff --git a/graphics/java/android/renderscript/FieldPacker.java b/graphics/java/android/renderscript/FieldPacker.java
index 2fb3d95..40628bc 100644
--- a/graphics/java/android/renderscript/FieldPacker.java
+++ b/graphics/java/android/renderscript/FieldPacker.java
@@ -233,16 +233,16 @@
addI32(v.w);
}
- public void addU32(Int2 v) {
+ public void addU32(Long2 v) {
addU32(v.x);
addU32(v.y);
}
- public void addU32(Int3 v) {
+ public void addU32(Long3 v) {
addU32(v.x);
addU32(v.y);
addU32(v.z);
}
- public void addU32(Int4 v) {
+ public void addU32(Long4 v) {
addU32(v.x);
addU32(v.y);
addU32(v.z);
diff --git a/graphics/java/android/renderscript/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java
index ff8f093..9445283 100644
--- a/graphics/java/android/renderscript/ScriptC.java
+++ b/graphics/java/android/renderscript/ScriptC.java
@@ -56,6 +56,9 @@
protected ScriptC(RenderScript rs, Resources resources, int resourceID) {
super(0, rs);
int id = internalCreate(rs, resources, resourceID);
+ if (id == 0) {
+ throw new RSRuntimeException("Loading of ScriptC script failed.");
+ }
setID(id);
}
diff --git a/include/media/stagefright/foundation/ADebug.h b/include/media/stagefright/foundation/ADebug.h
index eb5e494..450dcfe 100644
--- a/include/media/stagefright/foundation/ADebug.h
+++ b/include/media/stagefright/foundation/ADebug.h
@@ -75,7 +75,10 @@
#define CHECK_GE(x,y) CHECK_OP(x,y,GE,>=)
#define CHECK_GT(x,y) CHECK_OP(x,y,GT,>)
-#define TRESPASS() LOG_ALWAYS_FATAL("Should not be here.")
+#define TRESPASS() \
+ LOG_ALWAYS_FATAL( \
+ __FILE__ ":" LITERAL_TO_STRING(__LINE__) \
+ " Should not be here.");
} // namespace android
diff --git a/include/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h
index 9d589cf..eb599b5 100644
--- a/include/private/surfaceflinger/SharedBufferStack.h
+++ b/include/private/surfaceflinger/SharedBufferStack.h
@@ -105,7 +105,7 @@
volatile int32_t head; // server's current front buffer
volatile int32_t available; // number of dequeue-able buffers
volatile int32_t queued; // number of buffers waiting for post
- volatile int32_t inUse; // buffer currently in use by SF
+ volatile int32_t reserved1;
volatile status_t status; // surface's status code
// not part of the conditions
@@ -275,7 +275,6 @@
int32_t identity);
ssize_t retireAndLock();
- status_t unlock(int buffer);
void setStatus(status_t status);
status_t reallocateAll();
status_t reallocateAllExcept(int buffer);
@@ -356,12 +355,6 @@
inline const char* name() const { return "BuffersAvailableCondition"; }
};
- struct UnlockUpdate : public UpdateBase {
- const int lockedBuffer;
- inline UnlockUpdate(SharedBufferBase* sbb, int lockedBuffer);
- inline ssize_t operator()();
- };
-
struct RetireUpdate : public UpdateBase {
const int numBuffers;
inline RetireUpdate(SharedBufferBase* sbb, int numBuffers);
diff --git a/include/ui/Input.h b/include/ui/Input.h
index 27f65bc..30b45f7 100644
--- a/include/ui/Input.h
+++ b/include/ui/Input.h
@@ -38,6 +38,15 @@
AKEY_EVENT_FLAG_START_TRACKING = 0x40000000
};
+enum {
+ /*
+ * Indicates that an input device has switches.
+ * This input source flag is hidden from the API because switches are only used by the system
+ * and applications have no way to interact with them.
+ */
+ AINPUT_SOURCE_SWITCH = 0x80000000,
+};
+
/*
* Maximum number of pointers supported per motion event.
* Smallest number of pointers is 1.
diff --git a/keystore/java/android/security/Credentials.java b/keystore/java/android/security/Credentials.java
index ef19579..c650141 100644
--- a/keystore/java/android/security/Credentials.java
+++ b/keystore/java/android/security/Credentials.java
@@ -29,12 +29,8 @@
public class Credentials {
private static final String LOGTAG = "Credentials";
- public static final String UNLOCK_ACTION = "android.credentials.UNLOCK";
-
public static final String INSTALL_ACTION = "android.credentials.INSTALL";
- public static final String SYSTEM_INSTALL_ACTION = "android.credentials.SYSTEM_INSTALL";
-
/** Key prefix for CA certificates. */
public static final String CA_CERTIFICATE = "CACERT_";
@@ -73,7 +69,7 @@
public void unlock(Context context) {
try {
- Intent intent = new Intent(UNLOCK_ACTION);
+ Intent intent = new Intent("com.android.credentials.UNLOCK");
context.startActivity(intent);
} catch (ActivityNotFoundException e) {
Log.w(LOGTAG, e.toString());
@@ -107,12 +103,4 @@
Log.w(LOGTAG, e.toString());
}
}
-
- public void installFromSdCard(Context context) {
- try {
- context.startActivity(createInstallIntent());
- } catch (ActivityNotFoundException e) {
- Log.w(LOGTAG, e.toString());
- }
- }
}
diff --git a/libs/hwui/Android.mk b/libs/hwui/Android.mk
index c49be93..38e0848 100644
--- a/libs/hwui/Android.mk
+++ b/libs/hwui/Android.mk
@@ -23,6 +23,7 @@
Program.cpp \
ProgramCache.cpp \
ResourceCache.cpp \
+ ShapeCache.cpp \
SkiaColorFilter.cpp \
SkiaShader.cpp \
TextureCache.cpp \
diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp
index fde4f96..bffab95 100644
--- a/libs/hwui/Caches.cpp
+++ b/libs/hwui/Caches.cpp
@@ -73,6 +73,10 @@
LOGD(" LayerCache %8d / %8d", layerCache.getSize(), layerCache.getMaxSize());
LOGD(" GradientCache %8d / %8d", gradientCache.getSize(), gradientCache.getMaxSize());
LOGD(" PathCache %8d / %8d", pathCache.getSize(), pathCache.getMaxSize());
+ LOGD(" CircleShapeCache %8d / %8d",
+ circleShapeCache.getSize(), circleShapeCache.getMaxSize());
+ LOGD(" RoundRectShapeCache %8d / %8d",
+ roundRectShapeCache.getSize(), roundRectShapeCache.getMaxSize());
LOGD(" TextDropShadowCache %8d / %8d", dropShadowCache.getSize(),
dropShadowCache.getMaxSize());
for (uint32_t i = 0; i < fontRenderer.getFontRendererCount(); i++) {
diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h
index a11b6bc..aa0ceb7 100644
--- a/libs/hwui/Caches.h
+++ b/libs/hwui/Caches.h
@@ -31,6 +31,7 @@
#include "GradientCache.h"
#include "PatchCache.h"
#include "ProgramCache.h"
+#include "ShapeCache.h"
#include "PathCache.h"
#include "TextDropShadowCache.h"
#include "FboCache.h"
@@ -159,6 +160,8 @@
GradientCache gradientCache;
ProgramCache programCache;
PathCache pathCache;
+ RoundRectShapeCache roundRectShapeCache;
+ CircleShapeCache circleShapeCache;
PatchCache patchCache;
TextDropShadowCache dropShadowCache;
FboCache fboCache;
diff --git a/libs/hwui/Debug.h b/libs/hwui/Debug.h
index 71ec760..6236684 100644
--- a/libs/hwui/Debug.h
+++ b/libs/hwui/Debug.h
@@ -42,8 +42,8 @@
// This flag requires DEBUG_PATCHES to be turned on
#define DEBUG_PATCHES_EMPTY_VERTICES 0
-// Turn on to display debug info about paths
-#define DEBUG_PATHS 0
+// Turn on to display debug info about shapes
+#define DEBUG_SHAPES 0
// Turn on to display debug info about textures
#define DEBUG_TEXTURES 0
diff --git a/libs/hwui/DisplayListRenderer.cpp b/libs/hwui/DisplayListRenderer.cpp
index ade85e5..bdf056c 100644
--- a/libs/hwui/DisplayListRenderer.cpp
+++ b/libs/hwui/DisplayListRenderer.cpp
@@ -100,9 +100,12 @@
"DrawBitmap",
"DrawBitmapMatrix",
"DrawBitmapRect",
+ "DrawBitmapMesh",
"DrawPatch",
"DrawColor",
"DrawRect",
+ "DrawRoundRect",
+ "DrawCircle",
"DrawPath",
"DrawLines",
"DrawText",
@@ -306,6 +309,19 @@
getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
}
break;
+ case DrawBitmapMesh: {
+ int verticesCount = 0;
+ uint32_t colorsCount = 0;
+
+ SkBitmap* bitmap = getBitmap();
+ uint32_t meshWidth = getInt();
+ uint32_t meshHeight = getInt();
+ float* vertices = getFloats(verticesCount);
+ bool hasColors = getInt();
+ int* colors = hasColors ? getInts(colorsCount) : NULL;
+
+ renderer.drawBitmapMesh(bitmap, meshWidth, meshHeight, vertices, colors, getPaint());
+ }
case DrawPatch: {
int32_t* xDivs = NULL;
int32_t* yDivs = NULL;
@@ -332,6 +348,15 @@
renderer.drawRect(getFloat(), getFloat(), getFloat(), getFloat(), getPaint());
}
break;
+ case DrawRoundRect: {
+ renderer.drawRoundRect(getFloat(), getFloat(), getFloat(), getFloat(),
+ getFloat(), getFloat(), getPaint());
+ }
+ break;
+ case DrawCircle: {
+ renderer.drawCircle(getFloat(), getFloat(), getFloat(), getPaint());
+ }
+ break;
case DrawPath: {
renderer.drawPath(getPath(), getPaint());
}
@@ -576,6 +601,22 @@
addPaint(paint);
}
+void DisplayListRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+ float* vertices, int* colors, SkPaint* paint) {
+ addOp(DisplayList::DrawBitmapMesh);
+ addBitmap(bitmap);
+ addInt(meshWidth);
+ addInt(meshHeight);
+ addFloats(vertices, (meshWidth + 1) * (meshHeight + 1) * 2);
+ if (colors) {
+ addInt(1);
+ addInts(colors, (meshWidth + 1) * (meshHeight + 1));
+ } else {
+ addInt(0);
+ }
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
float left, float top, float right, float bottom, SkPaint* paint) {
@@ -601,6 +642,21 @@
addPaint(paint);
}
+void DisplayListRenderer::drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint) {
+ addOp(DisplayList::DrawRoundRect);
+ addBounds(left, top, right, bottom);
+ addPoint(rx, ry);
+ addPaint(paint);
+}
+
+void DisplayListRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+ addOp(DisplayList::DrawCircle);
+ addPoint(x, y);
+ addFloat(radius);
+ addPaint(paint);
+}
+
void DisplayListRenderer::drawPath(SkPath* path, SkPaint* paint) {
addOp(DisplayList::DrawPath);
addPath(path);
diff --git a/libs/hwui/DisplayListRenderer.h b/libs/hwui/DisplayListRenderer.h
index 05864ec..7f9db8a 100644
--- a/libs/hwui/DisplayListRenderer.h
+++ b/libs/hwui/DisplayListRenderer.h
@@ -107,9 +107,12 @@
DrawBitmap,
DrawBitmapMatrix,
DrawBitmapRect,
+ DrawBitmapMesh,
DrawPatch,
DrawColor,
DrawRect,
+ DrawRoundRect,
+ DrawCircle,
DrawPath,
DrawLines,
DrawText,
@@ -265,11 +268,16 @@
void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, SkPaint* paint);
+ void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+ float* vertices, int* colors, SkPaint* paint);
void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
float left, float top, float right, float bottom, SkPaint* paint);
void drawColor(int color, SkXfermode::Mode mode);
void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ void drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint);
+ void drawCircle(float x, float y, float radius, SkPaint* paint);
void drawPath(SkPath* path, SkPaint* paint);
void drawLines(float* points, int count, SkPaint* paint);
void drawText(const char* text, int bytesCount, int count, float x, float y, SkPaint* paint);
diff --git a/libs/hwui/FontRenderer.cpp b/libs/hwui/FontRenderer.cpp
index c080501..c43e40d 100644
--- a/libs/hwui/FontRenderer.cpp
+++ b/libs/hwui/FontRenderer.cpp
@@ -298,8 +298,10 @@
// FontRenderer
///////////////////////////////////////////////////////////////////////////////
+static bool sLogFontRendererCreate = true;
+
FontRenderer::FontRenderer() {
- LOGD("Creating FontRenderer");
+ if (sLogFontRendererCreate) LOGD("Creating FontRenderer");
mGammaTable = NULL;
mInitialized = false;
@@ -317,18 +319,24 @@
char property[PROPERTY_VALUE_MAX];
if (property_get(PROPERTY_TEXT_CACHE_WIDTH, property, NULL) > 0) {
- LOGD(" Setting text cache width to %s pixels", property);
+ if (sLogFontRendererCreate) LOGD(" Setting text cache width to %s pixels", property);
mCacheWidth = atoi(property);
} else {
- LOGD(" Using default text cache width of %i pixels", mCacheWidth);
+ if (sLogFontRendererCreate) {
+ LOGD(" Using default text cache width of %i pixels", mCacheWidth);
+ }
}
if (property_get(PROPERTY_TEXT_CACHE_HEIGHT, property, NULL) > 0) {
- LOGD(" Setting text cache width to %s pixels", property);
+ if (sLogFontRendererCreate) LOGD(" Setting text cache width to %s pixels", property);
mCacheHeight = atoi(property);
} else {
- LOGD(" Using default text cache height of %i pixels", mCacheHeight);
+ if (sLogFontRendererCreate) {
+ LOGD(" Using default text cache height of %i pixels", mCacheHeight);
+ }
}
+
+ sLogFontRendererCreate = false;
}
FontRenderer::~FontRenderer() {
diff --git a/libs/hwui/LayerRenderer.cpp b/libs/hwui/LayerRenderer.cpp
index e6bea78..a167429 100644
--- a/libs/hwui/LayerRenderer.cpp
+++ b/libs/hwui/LayerRenderer.cpp
@@ -29,7 +29,6 @@
void LayerRenderer::prepare(bool opaque) {
LAYER_RENDERER_LOGD("Rendering into layer, fbo = %d", mLayer->fbo);
- glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint*) &mPreviousFbo);
glBindFramebuffer(GL_FRAMEBUFFER, mLayer->fbo);
OpenGLRenderer::prepare(opaque);
@@ -37,11 +36,17 @@
void LayerRenderer::finish() {
OpenGLRenderer::finish();
- glBindFramebuffer(GL_FRAMEBUFFER, mPreviousFbo);
generateMesh();
LAYER_RENDERER_LOGD("Finished rendering into layer, fbo = %d", mLayer->mFbo);
+
+ // No need to unbind our FBO, this will be taken care of by the caller
+ // who will invoke OpenGLRenderer::resume()
+}
+
+GLint LayerRenderer::getTargetFbo() {
+ return mLayer->fbo;
}
///////////////////////////////////////////////////////////////////////////////
diff --git a/libs/hwui/LayerRenderer.h b/libs/hwui/LayerRenderer.h
index f2fb898..1e39847 100644
--- a/libs/hwui/LayerRenderer.h
+++ b/libs/hwui/LayerRenderer.h
@@ -51,6 +51,7 @@
bool hasLayer();
Region* getRegion();
+ GLint getTargetFbo();
static Layer* createLayer(uint32_t width, uint32_t height, bool isOpaque = false);
static bool resizeLayer(Layer* layer, uint32_t width, uint32_t height);
@@ -61,8 +62,6 @@
void generateMesh();
Layer* mLayer;
- GLuint mPreviousFbo;
-
}; // class LayerRenderer
}; // namespace uirenderer
diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp
index 2067acc1..b06bbd0 100644
--- a/libs/hwui/OpenGLRenderer.cpp
+++ b/libs/hwui/OpenGLRenderer.cpp
@@ -200,7 +200,7 @@
glDisable(GL_DITHER);
- glBindFramebuffer(GL_FRAMEBUFFER, 0);
+ glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo());
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
mCaches.blend = true;
@@ -430,18 +430,18 @@
} else {
// Copy the framebuffer into the layer
glBindTexture(GL_TEXTURE_2D, layer->texture);
-
- if (layer->empty) {
- glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
- snapshot->height - bounds.bottom, layer->width, layer->height, 0);
- layer->empty = false;
- } else {
- glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
- snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+ if (!bounds.isEmpty()) {
+ if (layer->empty) {
+ glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, bounds.left,
+ snapshot->height - bounds.bottom, layer->width, layer->height, 0);
+ layer->empty = false;
+ } else {
+ glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, bounds.left,
+ snapshot->height - bounds.bottom, bounds.getWidth(), bounds.getHeight());
+ }
+ // Enqueue the buffer coordinates to clear the corresponding region later
+ mLayers.push(new Rect(bounds));
}
-
- // Enqueue the buffer coordinates to clear the corresponding region later
- mLayers.push(new Rect(bounds));
}
return true;
@@ -565,8 +565,10 @@
resetColorFilter();
}
} else {
- dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
- composeLayerRect(layer, rect, true);
+ if (!rect.isEmpty()) {
+ dirtyLayer(rect.left, rect.top, rect.right, rect.bottom);
+ composeLayerRect(layer, rect, true);
+ }
}
if (fboLayer) {
@@ -1075,6 +1077,61 @@
restore();
}
+void OpenGLRenderer::drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+ float* vertices, int* colors, SkPaint* paint) {
+ // TODO: Do a quickReject
+ if (!vertices || mSnapshot->isIgnored()) {
+ return;
+ }
+
+ glActiveTexture(gTextureUnits[0]);
+ Texture* texture = mCaches.textureCache.get(bitmap);
+ if (!texture) return;
+ const AutoTexture autoCleanup(texture);
+ setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE);
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ // TODO: Support the colors array
+ const uint32_t count = meshWidth * meshHeight * 6;
+ TextureVertex mesh[count];
+
+ TextureVertex* vertex = mesh;
+ for (int32_t y = 0; y < meshHeight; y++) {
+ for (int32_t x = 0; x < meshWidth; x++) {
+ uint32_t i = (y * (meshWidth + 1) + x) * 2;
+
+ float u1 = float(x) / meshWidth;
+ float u2 = float(x + 1) / meshWidth;
+ float v1 = float(y) / meshHeight;
+ float v2 = float(y + 1) / meshHeight;
+
+ int ax = i + (meshWidth + 1) * 2;
+ int ay = ax + 1;
+ int bx = i;
+ int by = bx + 1;
+ int cx = i + 2;
+ int cy = cx + 1;
+ int dx = i + (meshWidth + 1) * 2 + 2;
+ int dy = dx + 1;
+
+ TextureVertex::set(vertex++, vertices[ax], vertices[ay], u1, v2);
+ TextureVertex::set(vertex++, vertices[bx], vertices[by], u1, v1);
+ TextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1);
+
+ TextureVertex::set(vertex++, vertices[ax], vertices[ay], u1, v2);
+ TextureVertex::set(vertex++, vertices[cx], vertices[cy], u2, v1);
+ TextureVertex::set(vertex++, vertices[dx], vertices[dy], u2, v2);
+ }
+ }
+
+ drawTextureMesh(0.0f, 0.0f, 1.0f, 1.0f, texture->id, alpha / 255.0f,
+ mode, texture->blend, &mesh[0].position[0], &mesh[0].texture[0],
+ GL_TRIANGLES, count);
+}
+
void OpenGLRenderer::drawBitmap(SkBitmap* bitmap,
float srcLeft, float srcTop, float srcRight, float srcBottom,
float dstLeft, float dstTop, float dstRight, float dstBottom,
@@ -1303,6 +1360,38 @@
drawColorRect(clip.left, clip.top, clip.right, clip.bottom, color, mode, true);
}
+void OpenGLRenderer::drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ glActiveTexture(gTextureUnits[0]);
+
+ const PathTexture* texture = mCaches.roundRectShapeCache.getRoundRect(
+ right - left, bottom - top, rx, ry, paint);
+ if (!texture) return;
+ const AutoTexture autoCleanup(texture);
+
+ const float x = left + texture->left - texture->offset;
+ const float y = top + texture->top - texture->offset;
+
+ drawPathTexture(texture, x, y, paint);
+}
+
+void OpenGLRenderer::drawCircle(float x, float y, float radius, SkPaint* paint) {
+ if (mSnapshot->isIgnored()) return;
+
+ glActiveTexture(gTextureUnits[0]);
+
+ const PathTexture* texture = mCaches.circleShapeCache.getCircle(radius, paint);
+ if (!texture) return;
+ const AutoTexture autoCleanup(texture);
+
+ const float left = (x - radius) + texture->left - texture->offset;
+ const float top = (y - radius) + texture->top - texture->offset;
+
+ drawPathTexture(texture, left, top, paint);
+}
+
void OpenGLRenderer::drawRect(float left, float top, float right, float bottom, SkPaint* p) {
if (quickReject(left, top, right, bottom)) {
return;
@@ -1451,8 +1540,7 @@
void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) {
if (mSnapshot->isIgnored()) return;
- GLuint textureUnit = 0;
- glActiveTexture(gTextureUnits[textureUnit]);
+ glActiveTexture(gTextureUnits[0]);
const PathTexture* texture = mCaches.pathCache.get(path, paint);
if (!texture) return;
@@ -1461,31 +1549,7 @@
const float x = texture->left - texture->offset;
const float y = texture->top - texture->offset;
- if (quickReject(x, y, x + texture->width, y + texture->height)) {
- return;
- }
-
- int alpha;
- SkXfermode::Mode mode;
- getAlphaAndMode(paint, &alpha, &mode);
-
- setupDraw();
- setupDrawWithTexture(true);
- setupDrawAlpha8Color(paint->getColor(), alpha);
- setupDrawColorFilter();
- setupDrawShader();
- setupDrawBlending(true, mode);
- setupDrawProgram();
- setupDrawModelView(x, y, x + texture->width, y + texture->height);
- setupDrawTexture(texture->id);
- setupDrawPureColorUniforms();
- setupDrawColorFilterUniforms();
- setupDrawShaderUniforms();
- setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
-
- glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
-
- finishDrawTexture();
+ drawPathTexture(texture, x, y, paint);
}
void OpenGLRenderer::drawLayer(Layer* layer, float x, float y, SkPaint* paint) {
@@ -1581,6 +1645,35 @@
// Drawing implementation
///////////////////////////////////////////////////////////////////////////////
+void OpenGLRenderer::drawPathTexture(const PathTexture* texture,
+ float x, float y, SkPaint* paint) {
+ if (quickReject(x, y, x + texture->width, y + texture->height)) {
+ return;
+ }
+
+ int alpha;
+ SkXfermode::Mode mode;
+ getAlphaAndMode(paint, &alpha, &mode);
+
+ setupDraw();
+ setupDrawWithTexture(true);
+ setupDrawAlpha8Color(paint->getColor(), alpha);
+ setupDrawColorFilter();
+ setupDrawShader();
+ setupDrawBlending(true, mode);
+ setupDrawProgram();
+ setupDrawModelView(x, y, x + texture->width, y + texture->height);
+ setupDrawTexture(texture->id);
+ setupDrawPureColorUniforms();
+ setupDrawColorFilterUniforms();
+ setupDrawShaderUniforms();
+ setupDrawMesh(NULL, (GLvoid*) gMeshTextureOffset);
+
+ glDrawArrays(GL_TRIANGLE_STRIP, 0, gMeshCount);
+
+ finishDrawTexture();
+}
+
// Same values used by Skia
#define kStdStrikeThru_Offset (-6.0f / 21.0f)
#define kStdUnderline_Offset (1.0f / 9.0f)
diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h
index 272c5c2..42e93ad 100644
--- a/libs/hwui/OpenGLRenderer.h
+++ b/libs/hwui/OpenGLRenderer.h
@@ -102,11 +102,16 @@
virtual void drawBitmap(SkBitmap* bitmap, float srcLeft, float srcTop,
float srcRight, float srcBottom, float dstLeft, float dstTop,
float dstRight, float dstBottom, SkPaint* paint);
+ virtual void drawBitmapMesh(SkBitmap* bitmap, int meshWidth, int meshHeight,
+ float* vertices, int* colors, SkPaint* paint);
virtual void drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int32_t* yDivs,
const uint32_t* colors, uint32_t width, uint32_t height, int8_t numColors,
float left, float top, float right, float bottom, SkPaint* paint);
virtual void drawColor(int color, SkXfermode::Mode mode);
virtual void drawRect(float left, float top, float right, float bottom, SkPaint* paint);
+ virtual void drawRoundRect(float left, float top, float right, float bottom,
+ float rx, float ry, SkPaint* paint);
+ virtual void drawCircle(float x, float y, float radius, SkPaint* paint);
virtual void drawPath(SkPath* path, SkPaint* paint);
virtual void drawLines(float* points, int count, SkPaint* paint);
virtual void drawText(const char* text, int bytesCount, int count, float x, float y,
@@ -145,14 +150,27 @@
return mSnapshot;
}
+ /**
+ * Returns the region of the current layer.
+ */
virtual Region* getRegion() {
return mSnapshot->region;
}
+ /**
+ * Indicates whether rendering is currently targeted at a layer.
+ */
virtual bool hasLayer() {
return (mSnapshot->flags & Snapshot::kFlagFboTarget) && mSnapshot->region;
}
+ /**
+ * Returns the name of the FBO this renderer is rendering into.
+ */
+ virtual GLint getTargetFbo() {
+ return 0;
+ }
+
private:
/**
* Saves the current state of the renderer as a new snapshot.
@@ -330,6 +348,8 @@
void drawTextDecorations(const char* text, int bytesCount, float length,
float x, float y, SkPaint* paint);
+ void drawPathTexture(const PathTexture* texture, float x, float y, SkPaint* paint);
+
/**
* Resets the texture coordinates stored in mMeshVertices. Setting the values
* back to default is achieved by calling:
diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp
index 999e4ea..11eb953 100644
--- a/libs/hwui/Patch.cpp
+++ b/libs/hwui/Patch.cpp
@@ -167,10 +167,6 @@
float v2 = fmax(0.0f, stepY - 0.5f) / bitmapHeight;
if (stepY > 0.0f) {
- if (i == mYCount - 1 && mYDivs[i] == bitmapHeight) {
- y2 = bottom - top;
- v2 = 1.0f;
- }
generateRow(vertex, y1, y2, v1, v2, stretchX, right - left,
bitmapWidth, quadCount);
}
@@ -222,10 +218,6 @@
float u2 = fmax(0.0f, stepX - 0.5f) / bitmapWidth;
if (stepX > 0.0f) {
- if (i == mXCount - 1 && mXDivs[i] == bitmapWidth) {
- x2 = bitmapWidth;
- u2 = 1.0f;
- }
generateQuad(vertex, x1, y1, x2, y2, u1, v1, u2, v2, quadCount);
}
diff --git a/libs/hwui/PathCache.cpp b/libs/hwui/PathCache.cpp
index 3184598..28c302e 100644
--- a/libs/hwui/PathCache.cpp
+++ b/libs/hwui/PathCache.cpp
@@ -16,11 +16,6 @@
#define LOG_TAG "OpenGLRenderer"
-#include <GLES2/gl2.h>
-
-#include <SkCanvas.h>
-#include <SkRect.h>
-
#include <utils/threads.h>
#include "PathCache.h"
@@ -30,87 +25,11 @@
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
-// Constructors/destructor
+// Path cache
///////////////////////////////////////////////////////////////////////////////
-PathCache::PathCache():
- mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity),
- mSize(0), mMaxSize(MB(DEFAULT_PATH_CACHE_SIZE)) {
- char property[PROPERTY_VALUE_MAX];
- if (property_get(PROPERTY_PATH_CACHE_SIZE, property, NULL) > 0) {
- LOGD(" Setting path cache size to %sMB", property);
- setMaxSize(MB(atof(property)));
- } else {
- LOGD(" Using default path cache size of %.2fMB", DEFAULT_PATH_CACHE_SIZE);
- }
- init();
-}
-
-PathCache::PathCache(uint32_t maxByteSize):
- mCache(GenerationCache<PathCacheEntry, PathTexture*>::kUnlimitedCapacity),
- mSize(0), mMaxSize(maxByteSize) {
- init();
-}
-
-PathCache::~PathCache() {
- mCache.clear();
-}
-
-void PathCache::init() {
- mCache.setOnEntryRemovedListener(this);
-
- GLint maxTextureSize;
- glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
- mMaxTextureSize = maxTextureSize;
-
- mDebugEnabled = readDebugLevel() & kDebugCaches;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Size management
-///////////////////////////////////////////////////////////////////////////////
-
-uint32_t PathCache::getSize() {
- return mSize;
-}
-
-uint32_t PathCache::getMaxSize() {
- return mMaxSize;
-}
-
-void PathCache::setMaxSize(uint32_t maxSize) {
- mMaxSize = maxSize;
- while (mSize > mMaxSize) {
- mCache.removeOldest();
- }
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Callbacks
-///////////////////////////////////////////////////////////////////////////////
-
-void PathCache::operator()(PathCacheEntry& path, PathTexture*& texture) {
- removeTexture(texture);
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// Caching
-///////////////////////////////////////////////////////////////////////////////
-
-void PathCache::removeTexture(PathTexture* texture) {
- if (texture) {
- const uint32_t size = texture->width * texture->height;
- mSize -= size;
-
- PATH_LOGD("PathCache::callback: delete path: name, size, mSize = %d, %d, %d",
- texture->id, size, mSize);
- if (mDebugEnabled) {
- LOGD("Path deleted, size = %d", size);
- }
-
- glDeleteTextures(1, &texture->id);
- delete texture;
- }
+PathCache::PathCache(): ShapeCache<PathCacheEntry>("path",
+ PROPERTY_PATH_CACHE_SIZE, DEFAULT_PATH_CACHE_SIZE) {
}
void PathCache::remove(SkPath* path) {
@@ -159,103 +78,5 @@
return texture;
}
-PathTexture* PathCache::addTexture(const PathCacheEntry& entry,
- const SkPath *path, const SkPaint* paint) {
- const SkRect& bounds = path->getBounds();
-
- const float pathWidth = fmax(bounds.width(), 1.0f);
- const float pathHeight = fmax(bounds.height(), 1.0f);
-
- if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) {
- LOGW("Path too large to be rendered into a texture");
- return NULL;
- }
-
- const float offset = entry.strokeWidth * 1.5f;
- const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5);
- const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);
-
- const uint32_t size = width * height;
- // Don't even try to cache a bitmap that's bigger than the cache
- if (size < mMaxSize) {
- while (mSize + size > mMaxSize) {
- mCache.removeOldest();
- }
- }
-
- PathTexture* texture = new PathTexture;
- texture->left = bounds.fLeft;
- texture->top = bounds.fTop;
- texture->offset = offset;
- texture->width = width;
- texture->height = height;
- texture->generation = path->getGenerationID();
-
- SkBitmap bitmap;
- bitmap.setConfig(SkBitmap::kA8_Config, width, height);
- bitmap.allocPixels();
- bitmap.eraseColor(0);
-
- SkPaint pathPaint(*paint);
-
- // Make sure the paint is opaque, color, alpha, filter, etc.
- // will be applied later when compositing the alpha8 texture
- pathPaint.setColor(0xff000000);
- pathPaint.setAlpha(255);
- pathPaint.setColorFilter(NULL);
- pathPaint.setMaskFilter(NULL);
- pathPaint.setShader(NULL);
- 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, pathPaint);
-
- generateTexture(bitmap, texture);
-
- if (size < mMaxSize) {
- mSize += size;
- PATH_LOGD("PathCache::get: create path: name, size, mSize = %d, %d, %d",
- texture->id, size, mSize);
- if (mDebugEnabled) {
- LOGD("Path created, size = %d", size);
- }
- mCache.put(entry, texture);
- } else {
- texture->cleanup = true;
- }
-
- return texture;
-}
-
-void PathCache::clear() {
- mCache.clear();
-}
-
-void PathCache::generateTexture(SkBitmap& bitmap, Texture* texture) {
- SkAutoLockPixels alp(bitmap);
- if (!bitmap.readyToDraw()) {
- LOGE("Cannot generate texture from bitmap");
- return;
- }
-
- glGenTextures(1, &texture->id);
-
- glBindTexture(GL_TEXTURE_2D, texture->id);
- // Textures are Alpha8
- glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
-
- texture->blend = true;
- glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
- GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
-
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
- glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
-}
-
}; // namespace uirenderer
}; // namespace android
diff --git a/libs/hwui/PathCache.h b/libs/hwui/PathCache.h
index ae2e55d..dc67e16 100644
--- a/libs/hwui/PathCache.h
+++ b/libs/hwui/PathCache.h
@@ -17,123 +17,54 @@
#ifndef ANDROID_HWUI_PATH_CACHE_H
#define ANDROID_HWUI_PATH_CACHE_H
-#include <SkBitmap.h>
-#include <SkPaint.h>
-#include <SkPath.h>
-
#include <utils/Vector.h>
#include "Debug.h"
-#include "Texture.h"
+#include "ShapeCache.h"
+
#include "utils/Compare.h"
-#include "utils/GenerationCache.h"
namespace android {
namespace uirenderer {
///////////////////////////////////////////////////////////////////////////////
-// Defines
-///////////////////////////////////////////////////////////////////////////////
-
-// Debug
-#if DEBUG_PATHS
- #define PATH_LOGD(...) LOGD(__VA_ARGS__)
-#else
- #define PATH_LOGD(...)
-#endif
-
-///////////////////////////////////////////////////////////////////////////////
// Classes
///////////////////////////////////////////////////////////////////////////////
-/**
- * Describe a path in the path cache.
- */
-struct PathCacheEntry {
- PathCacheEntry() {
+struct PathCacheEntry: public ShapeCacheEntry {
+ PathCacheEntry(SkPath* path, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapePath, paint) {
+ this->path = path;
+ }
+
+ PathCacheEntry(): ShapeCacheEntry() {
path = NULL;
- join = SkPaint::kDefault_Join;
- cap = SkPaint::kDefault_Cap;
- style = SkPaint::kFill_Style;
- miter = 4.0f;
- strokeWidth = 1.0f;
}
PathCacheEntry(const PathCacheEntry& entry):
- path(entry.path), join(entry.join), cap(entry.cap),
- style(entry.style), miter(entry.miter),
- strokeWidth(entry.strokeWidth) {
+ ShapeCacheEntry(entry) {
+ path = entry.path;
}
- PathCacheEntry(SkPath* path, SkPaint* paint) {
- this->path = path;
- join = paint->getStrokeJoin();
- cap = paint->getStrokeCap();
- miter = paint->getStrokeMiter();
- strokeWidth = paint->getStrokeWidth();
- style = paint->getStyle();
- }
-
- SkPath* path;
- SkPaint::Join join;
- SkPaint::Cap cap;
- SkPaint::Style style;
- float miter;
- float strokeWidth;
-
- bool operator<(const PathCacheEntry& rhs) const {
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const PathCacheEntry& rhs = (const PathCacheEntry&) r;
LTE_INT(path) {
- LTE_INT(join) {
- LTE_INT(cap) {
- LTE_INT(style) {
- LTE_FLOAT(miter) {
- LTE_FLOAT(strokeWidth) return false;
- }
- }
- }
- }
+ return false;
}
return false;
}
-}; // struct PathCacheEntry
-/**
- * Alpha texture used to represent a path.
- */
-struct PathTexture: public Texture {
- PathTexture(): Texture() {
- }
-
- /**
- * Left coordinate of the path bounds.
- */
- float left;
- /**
- * Top coordinate of the path bounds.
- */
- float top;
- /**
- * Offset to draw the path at the correct origin.
- */
- float offset;
-}; // struct PathTexture
+ SkPath* path;
+}; // PathCacheEntry
/**
* A simple LRU path cache. The cache has a maximum size expressed in bytes.
* Any texture added to the cache causing the cache to grow beyond the maximum
* allowed size will also cause the oldest texture to be kicked out.
*/
-class PathCache: public OnEntryRemoved<PathCacheEntry, PathTexture*> {
+class PathCache: public ShapeCache<PathCacheEntry> {
public:
PathCache();
- PathCache(uint32_t maxByteSize);
- ~PathCache();
-
- /**
- * Used as a callback when an entry is removed from the cache.
- * Do not invoke directly.
- */
- void operator()(PathCacheEntry& path, PathTexture*& texture);
/**
* Returns the texture associated with the specified path. If the texture
@@ -141,10 +72,6 @@
*/
PathTexture* get(SkPath* path, SkPaint* paint);
/**
- * Clears the cache. This causes all textures to be deleted.
- */
- void clear();
- /**
* Removes an entry.
*/
void remove(SkPath* path);
@@ -158,39 +85,7 @@
*/
void clearGarbage();
- /**
- * Sets the maximum size of the cache in bytes.
- */
- void setMaxSize(uint32_t maxSize);
- /**
- * Returns the maximum size of the cache in bytes.
- */
- uint32_t getMaxSize();
- /**
- * Returns the current size of the cache in bytes.
- */
- uint32_t getSize();
-
private:
- /**
- * Generates the texture from a bitmap into the specified texture structure.
- */
- void generateTexture(SkBitmap& bitmap, Texture* texture);
-
- void removeTexture(PathTexture* texture);
-
- PathTexture* addTexture(const PathCacheEntry& entry, const SkPath *path, const SkPaint* paint);
-
- void init();
-
- GenerationCache<PathCacheEntry, PathTexture*> mCache;
-
- uint32_t mSize;
- uint32_t mMaxSize;
- GLuint mMaxTextureSize;
-
- bool mDebugEnabled;
-
Vector<SkPath*> mGarbage;
mutable Mutex mLock;
}; // class PathCache
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index 6a0d7ea..2f230b5 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -48,6 +48,7 @@
#define PROPERTY_LAYER_CACHE_SIZE "ro.hwui.layer_cache_size"
#define PROPERTY_GRADIENT_CACHE_SIZE "ro.hwui.gradient_cache_size"
#define PROPERTY_PATH_CACHE_SIZE "ro.hwui.path_cache_size"
+#define PROPERTY_SHAPE_CACHE_SIZE "ro.hwui.shape_cache_size"
#define PROPERTY_DROP_SHADOW_CACHE_SIZE "ro.hwui.drop_shadow_cache_size"
#define PROPERTY_FBO_CACHE_SIZE "ro.hwui.fbo_cache_size"
@@ -66,6 +67,7 @@
#define DEFAULT_TEXTURE_CACHE_SIZE 20.0f
#define DEFAULT_LAYER_CACHE_SIZE 8.0f
#define DEFAULT_PATH_CACHE_SIZE 4.0f
+#define DEFAULT_SHAPE_CACHE_SIZE 1.0f
#define DEFAULT_PATCH_CACHE_SIZE 512
#define DEFAULT_GRADIENT_CACHE_SIZE 0.5f
#define DEFAULT_DROP_SHADOW_CACHE_SIZE 2.0f
diff --git a/libs/hwui/ShapeCache.cpp b/libs/hwui/ShapeCache.cpp
new file mode 100644
index 0000000..b78eecb
--- /dev/null
+++ b/libs/hwui/ShapeCache.cpp
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define LOG_TAG "OpenGLRenderer"
+
+#include "ShapeCache.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Rounded rects
+///////////////////////////////////////////////////////////////////////////////
+
+RoundRectShapeCache::RoundRectShapeCache(): ShapeCache<RoundRectShapeCacheEntry>(
+ "round rect", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
+}
+
+PathTexture* RoundRectShapeCache::getRoundRect(float width, float height,
+ float rx, float ry, SkPaint* paint) {
+ RoundRectShapeCacheEntry entry(width, height, rx, ry, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ SkRect r;
+ r.set(0.0f, 0.0f, width, height);
+ path.addRoundRect(r, rx, ry, SkPath::kCW_Direction);
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Circles
+///////////////////////////////////////////////////////////////////////////////
+
+CircleShapeCache::CircleShapeCache(): ShapeCache<CircleShapeCacheEntry>(
+ "circle", PROPERTY_SHAPE_CACHE_SIZE, DEFAULT_SHAPE_CACHE_SIZE) {
+}
+
+PathTexture* CircleShapeCache::getCircle(float radius, SkPaint* paint) {
+ CircleShapeCacheEntry entry(radius, paint);
+ PathTexture* texture = get(entry);
+
+ if (!texture) {
+ SkPath path;
+ path.addCircle(radius, radius, radius, SkPath::kCW_Direction);
+
+ texture = addTexture(entry, &path, paint);
+ }
+
+ return texture;
+}
+
+}; // namespace uirenderer
+}; // namespace android
diff --git a/libs/hwui/ShapeCache.h b/libs/hwui/ShapeCache.h
new file mode 100644
index 0000000..c8bcfc2
--- /dev/null
+++ b/libs/hwui/ShapeCache.h
@@ -0,0 +1,492 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_HWUI_SHAPE_CACHE_H
+#define ANDROID_HWUI_SHAPE_CACHE_H
+
+#include <GLES2/gl2.h>
+
+#include <SkBitmap.h>
+#include <SkCanvas.h>
+#include <SkPaint.h>
+#include <SkPath.h>
+#include <SkRect.h>
+
+#include "Debug.h"
+#include "Properties.h"
+#include "Texture.h"
+#include "utils/Compare.h"
+#include "utils/GenerationCache.h"
+
+namespace android {
+namespace uirenderer {
+
+///////////////////////////////////////////////////////////////////////////////
+// Defines
+///////////////////////////////////////////////////////////////////////////////
+
+// Debug
+#if DEBUG_SHAPES
+ #define SHAPE_LOGD(...) LOGD(__VA_ARGS__)
+#else
+ #define SHAPE_LOGD(...)
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// Classes
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Alpha texture used to represent a path.
+ */
+struct PathTexture: public Texture {
+ PathTexture(): Texture() {
+ }
+
+ /**
+ * Left coordinate of the path bounds.
+ */
+ float left;
+ /**
+ * Top coordinate of the path bounds.
+ */
+ float top;
+ /**
+ * Offset to draw the path at the correct origin.
+ */
+ float offset;
+}; // struct PathTexture
+
+/**
+ * Describe a shape in the shape cache.
+ */
+struct ShapeCacheEntry {
+ enum ShapeType {
+ kShapeNone,
+ kShapeRoundRect,
+ kShapeCircle,
+ kShapeOval,
+ kShapeArc,
+ kShapePath
+ };
+
+ ShapeCacheEntry() {
+ shapeType = kShapeNone;
+ join = SkPaint::kDefault_Join;
+ cap = SkPaint::kDefault_Cap;
+ style = SkPaint::kFill_Style;
+ miter = 4.0f;
+ strokeWidth = 1.0f;
+ }
+
+ ShapeCacheEntry(const ShapeCacheEntry& entry):
+ shapeType(entry.shapeType), join(entry.join), cap(entry.cap),
+ style(entry.style), miter(entry.miter),
+ strokeWidth(entry.strokeWidth) {
+ }
+
+ ShapeCacheEntry(ShapeType type, SkPaint* paint) {
+ shapeType = type;
+ join = paint->getStrokeJoin();
+ cap = paint->getStrokeCap();
+ float v = paint->getStrokeMiter();
+ miter = *(uint32_t*) &v;
+ v = paint->getStrokeWidth();
+ strokeWidth = *(uint32_t*) &v;
+ style = paint->getStyle();
+ }
+
+ virtual ~ShapeCacheEntry() {
+ }
+
+ // shapeType must be checked in subclasses operator<
+ ShapeType shapeType;
+ SkPaint::Join join;
+ SkPaint::Cap cap;
+ SkPaint::Style style;
+ uint32_t miter;
+ uint32_t strokeWidth;
+
+ bool operator<(const ShapeCacheEntry& rhs) const {
+ LTE_INT(shapeType) {
+ LTE_INT(join) {
+ LTE_INT(cap) {
+ LTE_INT(style) {
+ LTE_INT(miter) {
+ LTE_INT(strokeWidth) {
+ return lessThan(rhs);
+ }
+ }
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+protected:
+ virtual bool lessThan(const ShapeCacheEntry& rhs) const {
+ return false;
+ }
+}; // struct ShapeCacheEntry
+
+
+struct RoundRectShapeCacheEntry: public ShapeCacheEntry {
+ RoundRectShapeCacheEntry(float width, float height, float rx, float ry, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeRoundRect, paint) {
+ mWidth = *(uint32_t*) &width;
+ mHeight = *(uint32_t*) &height;
+ mRx = *(uint32_t*) ℞
+ mRy = *(uint32_t*) &ry;
+ }
+
+ RoundRectShapeCacheEntry(): ShapeCacheEntry() {
+ mWidth = 0;
+ mHeight = 0;
+ mRx = 0;
+ mRy = 0;
+ }
+
+ RoundRectShapeCacheEntry(const RoundRectShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mWidth = entry.mWidth;
+ mHeight = entry.mHeight;
+ mRx = entry.mRx;
+ mRy = entry.mRy;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const RoundRectShapeCacheEntry& rhs = (const RoundRectShapeCacheEntry&) r;
+ LTE_INT(mWidth) {
+ LTE_INT(mHeight) {
+ LTE_INT(mRx) {
+ LTE_INT(mRy) {
+ return false;
+ }
+ }
+ }
+ }
+ return false;
+ }
+
+private:
+ uint32_t mWidth;
+ uint32_t mHeight;
+ uint32_t mRx;
+ uint32_t mRy;
+}; // RoundRectShapeCacheEntry
+
+struct CircleShapeCacheEntry: public ShapeCacheEntry {
+ CircleShapeCacheEntry(float radius, SkPaint* paint):
+ ShapeCacheEntry(ShapeCacheEntry::kShapeCircle, paint) {
+ mRadius = *(uint32_t*) &radius;
+ }
+
+ CircleShapeCacheEntry(): ShapeCacheEntry() {
+ mRadius = 0;
+ }
+
+ CircleShapeCacheEntry(const CircleShapeCacheEntry& entry):
+ ShapeCacheEntry(entry) {
+ mRadius = entry.mRadius;
+ }
+
+ bool lessThan(const ShapeCacheEntry& r) const {
+ const CircleShapeCacheEntry& rhs = (const CircleShapeCacheEntry&) r;
+ LTE_INT(mRadius) {
+ return false;
+ }
+ return false;
+ }
+
+private:
+ uint32_t mRadius;
+}; // CircleShapeCacheEntry
+
+/**
+ * A simple LRU shape cache. The cache has a maximum size expressed in bytes.
+ * Any texture added to the cache causing the cache to grow beyond the maximum
+ * allowed size will also cause the oldest texture to be kicked out.
+ */
+template<typename Entry>
+class ShapeCache: public OnEntryRemoved<Entry, PathTexture*> {
+public:
+ ShapeCache(const char* name, const char* propertyName, float defaultSize);
+ ~ShapeCache();
+
+ /**
+ * Used as a callback when an entry is removed from the cache.
+ * Do not invoke directly.
+ */
+ void operator()(Entry& path, PathTexture*& texture);
+
+ /**
+ * Clears the cache. This causes all textures to be deleted.
+ */
+ void clear();
+
+ /**
+ * Sets the maximum size of the cache in bytes.
+ */
+ void setMaxSize(uint32_t maxSize);
+ /**
+ * Returns the maximum size of the cache in bytes.
+ */
+ uint32_t getMaxSize();
+ /**
+ * Returns the current size of the cache in bytes.
+ */
+ uint32_t getSize();
+
+protected:
+ PathTexture* addTexture(const Entry& entry, const SkPath *path, const SkPaint* paint);
+
+ PathTexture* get(Entry entry) {
+ return mCache.get(entry);
+ }
+
+ void removeTexture(PathTexture* texture);
+
+ GenerationCache<Entry, PathTexture*> mCache;
+ uint32_t mSize;
+ uint32_t mMaxSize;
+ GLuint mMaxTextureSize;
+
+ char* mName;
+ bool mDebugEnabled;
+
+private:
+ /**
+ * Generates the texture from a bitmap into the specified texture structure.
+ */
+ void generateTexture(SkBitmap& bitmap, Texture* texture);
+
+ void init();
+}; // class ShapeCache
+
+class RoundRectShapeCache: public ShapeCache<RoundRectShapeCacheEntry> {
+public:
+ RoundRectShapeCache();
+
+ PathTexture* getRoundRect(float width, float height, float rx, float ry, SkPaint* paint);
+}; // class RoundRectShapeCache
+
+class CircleShapeCache: public ShapeCache<CircleShapeCacheEntry> {
+public:
+ CircleShapeCache();
+
+ PathTexture* getCircle(float radius, SkPaint* paint);
+}; // class RoundRectShapeCache
+
+
+///////////////////////////////////////////////////////////////////////////////
+// Constructors/destructor
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+ShapeCache<Entry>::ShapeCache(const char* name, const char* propertyName, float defaultSize):
+ mCache(GenerationCache<ShapeCacheEntry, PathTexture*>::kUnlimitedCapacity),
+ mSize(0), mMaxSize(MB(defaultSize)) {
+ char property[PROPERTY_VALUE_MAX];
+ if (property_get(propertyName, property, NULL) > 0) {
+ LOGD(" Setting %s cache size to %sMB", name, property);
+ setMaxSize(MB(atof(property)));
+ } else {
+ LOGD(" Using default %s cache size of %.2fMB", name, defaultSize);
+ }
+
+ size_t len = strlen(name);
+ mName = new char[len + 1];
+ strcpy(mName, name);
+ mName[len] = '\0';
+
+ init();
+}
+
+template<class Entry>
+ShapeCache<Entry>::~ShapeCache() {
+ mCache.clear();
+ delete[] mName;
+}
+
+template<class Entry>
+void ShapeCache<Entry>::init() {
+ mCache.setOnEntryRemovedListener(this);
+
+ GLint maxTextureSize;
+ glGetIntegerv(GL_MAX_TEXTURE_SIZE, &maxTextureSize);
+ mMaxTextureSize = maxTextureSize;
+
+ mDebugEnabled = readDebugLevel() & kDebugCaches;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Size management
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+uint32_t ShapeCache<Entry>::getSize() {
+ return mSize;
+}
+
+template<class Entry>
+uint32_t ShapeCache<Entry>::getMaxSize() {
+ return mMaxSize;
+}
+
+template<class Entry>
+void ShapeCache<Entry>::setMaxSize(uint32_t maxSize) {
+ mMaxSize = maxSize;
+ while (mSize > mMaxSize) {
+ mCache.removeOldest();
+ }
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Callbacks
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+void ShapeCache<Entry>::operator()(Entry& path, PathTexture*& texture) {
+ removeTexture(texture);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+// Caching
+///////////////////////////////////////////////////////////////////////////////
+
+template<class Entry>
+void ShapeCache<Entry>::removeTexture(PathTexture* texture) {
+ if (texture) {
+ const uint32_t size = texture->width * texture->height;
+ mSize -= size;
+
+ SHAPE_LOGD("ShapeCache::callback: delete %s: name, size, mSize = %d, %d, %d",
+ mName, texture->id, size, mSize);
+ if (mDebugEnabled) {
+ LOGD("Shape %s deleted, size = %d", mName, size);
+ }
+
+ glDeleteTextures(1, &texture->id);
+ delete texture;
+ }
+}
+
+template<class Entry>
+PathTexture* ShapeCache<Entry>::addTexture(const Entry& entry, const SkPath *path,
+ const SkPaint* paint) {
+ const SkRect& bounds = path->getBounds();
+
+ const float pathWidth = fmax(bounds.width(), 1.0f);
+ const float pathHeight = fmax(bounds.height(), 1.0f);
+
+ if (pathWidth > mMaxTextureSize || pathHeight > mMaxTextureSize) {
+ LOGW("Shape %s too large to be rendered into a texture", mName);
+ return NULL;
+ }
+
+ const float offset = paint->getStrokeWidth() * 1.5f;
+ const uint32_t width = uint32_t(pathWidth + offset * 2.0 + 0.5);
+ const uint32_t height = uint32_t(pathHeight + offset * 2.0 + 0.5);
+
+ const uint32_t size = width * height;
+ // Don't even try to cache a bitmap that's bigger than the cache
+ if (size < mMaxSize) {
+ while (mSize + size > mMaxSize) {
+ mCache.removeOldest();
+ }
+ }
+
+ PathTexture* texture = new PathTexture;
+ texture->left = bounds.fLeft;
+ texture->top = bounds.fTop;
+ texture->offset = offset;
+ texture->width = width;
+ texture->height = height;
+ texture->generation = path->getGenerationID();
+
+ SkBitmap bitmap;
+ bitmap.setConfig(SkBitmap::kA8_Config, width, height);
+ bitmap.allocPixels();
+ bitmap.eraseColor(0);
+
+ SkPaint pathPaint(*paint);
+
+ // Make sure the paint is opaque, color, alpha, filter, etc.
+ // will be applied later when compositing the alpha8 texture
+ pathPaint.setColor(0xff000000);
+ pathPaint.setAlpha(255);
+ pathPaint.setColorFilter(NULL);
+ pathPaint.setMaskFilter(NULL);
+ pathPaint.setShader(NULL);
+ 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, pathPaint);
+
+ generateTexture(bitmap, texture);
+
+ if (size < mMaxSize) {
+ mSize += size;
+ SHAPE_LOGD("ShapeCache::get: create %s: name, size, mSize = %d, %d, %d",
+ mName, texture->id, size, mSize);
+ if (mDebugEnabled) {
+ LOGD("Shape %s created, size = %d", mName, size);
+ }
+ mCache.put(entry, texture);
+ } else {
+ texture->cleanup = true;
+ }
+
+ return texture;
+}
+
+template<class Entry>
+void ShapeCache<Entry>::clear() {
+ mCache.clear();
+}
+
+template<class Entry>
+void ShapeCache<Entry>::generateTexture(SkBitmap& bitmap, Texture* texture) {
+ SkAutoLockPixels alp(bitmap);
+ if (!bitmap.readyToDraw()) {
+ LOGE("Cannot generate texture from bitmap");
+ return;
+ }
+
+ glGenTextures(1, &texture->id);
+
+ glBindTexture(GL_TEXTURE_2D, texture->id);
+ // Textures are Alpha8
+ glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
+
+ texture->blend = true;
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, texture->width, texture->height, 0,
+ GL_ALPHA, GL_UNSIGNED_BYTE, bitmap.getPixels());
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
+}
+
+}; // namespace uirenderer
+}; // namespace android
+
+#endif // ANDROID_HWUI_SHAPE_CACHE_H
diff --git a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
index b02f85d..b6f2b2a6 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/fp_mad.rs
@@ -102,8 +102,7 @@
start();
// Do ~100 M ops
- int ct;
- for (ct=0; ct < 1000 * 100; ct++) {
+ for (int ct=0; ct < 1000 * 100; ct++) {
for (int i=0; i < (1000); i++) {
data_f1[i] = clamp(data_f1[i], -1.f, 1.f);
}
@@ -114,7 +113,7 @@
start();
// Do ~100 M ops
- for (ct=0; ct < 1000 * 100; ct++) {
+ for (int ct=0; ct < 1000 * 100; ct++) {
for (int i=0; i < (1000); i++) {
if (data_f1[i] < -1.f) data_f1[i] = -1.f;
if (data_f1[i] > -1.f) data_f1[i] = 1.f;
@@ -130,8 +129,7 @@
float total = 0;
// Do ~100 M ops
- int ct;
- for (ct=0; ct < 1000 * 100 /4; ct++) {
+ for (int ct=0; ct < 1000 * 100 /4; ct++) {
for (int i=0; i < (1000); i++) {
data_f4[i] = clamp(data_f4[i], -1.f, 1.f);
}
diff --git a/libs/rs/java/tests/src/com/android/rs/test/math.rs b/libs/rs/java/tests/src/com/android/rs/test/math.rs
index 5b1ad15..02993fe 100644
--- a/libs/rs/java/tests/src/com/android/rs/test/math.rs
+++ b/libs/rs/java/tests/src/com/android/rs/test/math.rs
@@ -7,45 +7,162 @@
volatile float3 f3;
volatile float4 f4;
-#define TEST_F(fnc, var) \
- rsDebug("Testing " #fnc, 0); \
- var##1 = fnc(var##1); \
- var##2 = fnc(var##2); \
- var##3 = fnc(var##3); \
- var##4 = fnc(var##4);
+volatile int i1;
+volatile int2 i2;
+volatile int3 i3;
+volatile int4 i4;
-#define TEST_FP(fnc, var) \
+#define TEST_FN_FUNC_FN(fnc) \
rsDebug("Testing " #fnc, 0); \
- var##1 = fnc(var##1, (float*) &f1); \
- var##2 = fnc(var##2, (float2*) &f2); \
- var##3 = fnc(var##3, (float3*) &f3); \
- var##4 = fnc(var##4, (float4*) &f4);
+ f1 = fnc(f1); \
+ f2 = fnc(f2); \
+ f3 = fnc(f3); \
+ f4 = fnc(f4);
-#define TEST_F2(fnc, var) \
+#define TEST_FN_FUNC_FN_PFN(fnc) \
rsDebug("Testing " #fnc, 0); \
- var##1 = fnc(var##1, var##1); \
- var##2 = fnc(var##2, var##2); \
- var##3 = fnc(var##3, var##3); \
- var##4 = fnc(var##4, var##4);
+ f1 = fnc(f1, (float*) &f1); \
+ f2 = fnc(f2, (float2*) &f2); \
+ f3 = fnc(f3, (float3*) &f3); \
+ f4 = fnc(f4, (float4*) &f4);
-static bool test_math(uint32_t index) {
+#define TEST_FN_FUNC_FN_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1); \
+ f2 = fnc(f2, f2); \
+ f3 = fnc(f3, f3); \
+ f4 = fnc(f4, f4);
+
+#define TEST_FN_FUNC_FN_F(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1); \
+ f2 = fnc(f2, f1); \
+ f3 = fnc(f3, f1); \
+ f4 = fnc(f4, f1);
+
+#define TEST_FN_FUNC_FN_IN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, i1); \
+ f2 = fnc(f2, i2); \
+ f3 = fnc(f3, i3); \
+ f4 = fnc(f4, i4);
+
+#define TEST_FN_FUNC_FN_I(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, i1); \
+ f2 = fnc(f2, i1); \
+ f3 = fnc(f3, i1); \
+ f4 = fnc(f4, i1);
+
+#define TEST_FN_FUNC_FN_FN_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1, f1); \
+ f2 = fnc(f2, f2, f2); \
+ f3 = fnc(f3, f3, f3); \
+ f4 = fnc(f4, f4, f4);
+
+#define TEST_FN_FUNC_FN_PIN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, (int*) &i1); \
+ f2 = fnc(f2, (int2*) &i2); \
+ f3 = fnc(f3, (int3*) &i3); \
+ f4 = fnc(f4, (int4*) &i4);
+
+#define TEST_FN_FUNC_FN_FN_PIN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ f1 = fnc(f1, f1, (int*) &i1); \
+ f2 = fnc(f2, f2, (int2*) &i2); \
+ f3 = fnc(f3, f3, (int3*) &i3); \
+ f4 = fnc(f4, f4, (int4*) &i4);
+
+#define TEST_IN_FUNC_FN(fnc) \
+ rsDebug("Testing " #fnc, 0); \
+ i1 = fnc(f1); \
+ i2 = fnc(f2); \
+ i3 = fnc(f3); \
+ i4 = fnc(f4);
+
+
+static bool test_fp_math(uint32_t index) {
bool failed = false;
start();
- TEST_F(cos, f);
- TEST_FP(modf, f);
- TEST_F2(pow, f);
- TEST_F(sin, f);
- TEST_F(sqrt, f);
-
+ TEST_FN_FUNC_FN(acos);
+ TEST_FN_FUNC_FN(acosh);
+ TEST_FN_FUNC_FN(acospi);
+ TEST_FN_FUNC_FN(asin);
+ TEST_FN_FUNC_FN(asinh);
+ TEST_FN_FUNC_FN(asinpi);
+ TEST_FN_FUNC_FN(atan);
+ TEST_FN_FUNC_FN_FN(atan2);
+ TEST_FN_FUNC_FN(atanh);
+ TEST_FN_FUNC_FN(atanpi);
+ TEST_FN_FUNC_FN_FN(atan2pi);
+ TEST_FN_FUNC_FN(cbrt);
+ TEST_FN_FUNC_FN(ceil);
+ TEST_FN_FUNC_FN_FN(copysign);
+ TEST_FN_FUNC_FN(cos);
+ TEST_FN_FUNC_FN(cosh);
+ TEST_FN_FUNC_FN(cospi);
+ TEST_FN_FUNC_FN(erfc);
+ TEST_FN_FUNC_FN(erf);
+ TEST_FN_FUNC_FN(exp);
+ TEST_FN_FUNC_FN(exp2);
+ TEST_FN_FUNC_FN(exp10);
+ TEST_FN_FUNC_FN(expm1);
+ TEST_FN_FUNC_FN(fabs);
+ TEST_FN_FUNC_FN_FN(fdim);
+ TEST_FN_FUNC_FN(floor);
+ TEST_FN_FUNC_FN_FN_FN(fma);
+ TEST_FN_FUNC_FN_FN(fmax);
+ TEST_FN_FUNC_FN_F(fmax);
+ TEST_FN_FUNC_FN_FN(fmin);
+ TEST_FN_FUNC_FN_F(fmin);
+ TEST_FN_FUNC_FN_FN(fmod);
+ TEST_FN_FUNC_FN_PFN(fract);
+ TEST_FN_FUNC_FN_PIN(frexp);
+ TEST_FN_FUNC_FN_FN(hypot);
+ TEST_IN_FUNC_FN(ilogb);
+ TEST_FN_FUNC_FN_IN(ldexp);
+ TEST_FN_FUNC_FN_I(ldexp);
+ TEST_FN_FUNC_FN(lgamma);
+ TEST_FN_FUNC_FN_PIN(lgamma);
+ TEST_FN_FUNC_FN(log);
+ TEST_FN_FUNC_FN(log2);
+ TEST_FN_FUNC_FN(log10);
+ TEST_FN_FUNC_FN(log1p);
+ TEST_FN_FUNC_FN(logb);
+ TEST_FN_FUNC_FN_FN_FN(mad);
+ TEST_FN_FUNC_FN_PFN(modf);
+ // nan
+ TEST_FN_FUNC_FN_FN(nextafter);
+ TEST_FN_FUNC_FN_FN(pow);
+ TEST_FN_FUNC_FN_IN(pown);
+ TEST_FN_FUNC_FN_FN(powr);
+ TEST_FN_FUNC_FN_FN(remainder);
+ TEST_FN_FUNC_FN_FN_PIN(remquo);
+ TEST_FN_FUNC_FN(rint);
+ TEST_FN_FUNC_FN_IN(rootn);
+ TEST_FN_FUNC_FN(round);
+ TEST_FN_FUNC_FN(rsqrt);
+ TEST_FN_FUNC_FN(sin);
+ TEST_FN_FUNC_FN_PFN(sincos);
+ TEST_FN_FUNC_FN(sinh);
+ TEST_FN_FUNC_FN(sinpi);
+ TEST_FN_FUNC_FN(sqrt);
+ TEST_FN_FUNC_FN(tan);
+ TEST_FN_FUNC_FN(tanh);
+ TEST_FN_FUNC_FN(tanpi);
+ TEST_FN_FUNC_FN(tgamma);
+ TEST_FN_FUNC_FN(trunc);
float time = end(index);
if (failed) {
- rsDebug("test_math FAILED", time);
+ rsDebug("test_fp_math FAILED", time);
}
else {
- rsDebug("test_math PASSED", time);
+ rsDebug("test_fp_math PASSED", time);
}
return failed;
@@ -53,7 +170,7 @@
void math_test(uint32_t index, int test_num) {
bool failed = false;
- failed |= test_math(index);
+ failed |= test_fp_math(index);
if (failed) {
rsSendToClientBlocking(RS_MSG_TEST_FAILED);
diff --git a/libs/rs/rsContext.cpp b/libs/rs/rsContext.cpp
index 2e0c491..3acb624 100644
--- a/libs/rs/rsContext.cpp
+++ b/libs/rs/rsContext.cpp
@@ -253,7 +253,11 @@
LOGV("%p, deinitEGL", this);
if (mEGL.mContext != EGL_NO_CONTEXT) {
- eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, mEGL.mContext);
+ eglMakeCurrent(mEGL.mDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
+ eglDestroySurface(mEGL.mDisplay, mEGL.mSurfaceDefault);
+ if (mEGL.mSurface != EGL_NO_SURFACE) {
+ eglDestroySurface(mEGL.mDisplay, mEGL.mSurface);
+ }
eglDestroyContext(mEGL.mDisplay, mEGL.mContext);
checkEglError("eglDestroyContext");
}
@@ -1035,9 +1039,7 @@
}
void rsi_ContextDestroyWorker(Context *rsc) {
- LOGE("rsi_ContextDestroyWorker 1");
rsc->destroyWorkerThreadResources();;
- LOGE("rsi_ContextDestroyWorker 2");
}
}
diff --git a/libs/rs/rsScriptC.cpp b/libs/rs/rsScriptC.cpp
index 9f730bf..eecfa16 100644
--- a/libs/rs/rsScriptC.cpp
+++ b/libs/rs/rsScriptC.cpp
@@ -467,7 +467,7 @@
extern unsigned rs_runtime_lib_bc_size;
#endif
-void ScriptCState::runCompiler(Context *rsc,
+bool ScriptCState::runCompiler(Context *rsc,
ScriptC *s,
const char *resName,
const char *cacheDir) {
@@ -475,14 +475,17 @@
s->mEnviroment.mIsThreadable = true;
- bccRegisterSymbolCallback(s->mBccScript, symbolLookup, s);
+ if (bccRegisterSymbolCallback(s->mBccScript, symbolLookup, s) != 0) {
+ LOGE("bcc: FAILS to register symbol callback");
+ return false;
+ }
if (bccReadBC(s->mBccScript,
resName,
s->mEnviroment.mScriptText,
s->mEnviroment.mScriptTextLength, 0) != 0) {
LOGE("bcc: FAILS to read bitcode");
- // Handle Fatal Error
+ return false;
}
#if 1
@@ -493,14 +496,14 @@
/*"1" means skip buffer here, and let libbcc decide*/,
0) != 0) {
LOGE("bcc: FAILS to link bitcode");
- // Handle Fatal Error
+ return false;
}
#endif
char *cachePath = genCacheFileName(cacheDir, resName, ".oBCC");
if (bccPrepareExecutable(s->mBccScript, cachePath, 0) != 0) {
LOGE("bcc: FAILS to prepare executable");
- // Handle Fatal Error
+ return false;
}
free(cachePath);
@@ -547,7 +550,7 @@
continue;
}
LOGE("Invalid version pragma value: %s\n", values[i]);
- // Handle Fatal Error
+ return false;
}
if (!strcmp(keys[i], "stateVertex")) {
@@ -559,7 +562,7 @@
continue;
}
LOGE("Unrecognized value %s passed to stateVertex", values[i]);
- // Handle Fatal Error
+ return false;
}
if (!strcmp(keys[i], "stateRaster")) {
@@ -571,7 +574,7 @@
continue;
}
LOGE("Unrecognized value %s passed to stateRaster", values[i]);
- // Handle Fatal Error
+ return false;
}
if (!strcmp(keys[i], "stateFragment")) {
@@ -583,7 +586,7 @@
continue;
}
LOGE("Unrecognized value %s passed to stateFragment", values[i]);
- // Handle Fatal Error
+ return false;
}
if (!strcmp(keys[i], "stateStore")) {
@@ -595,9 +598,10 @@
continue;
}
LOGE("Unrecognized value %s passed to stateStore", values[i]);
- // Handle Fatal Error
+ return false;
}
}
+ return true;
}
namespace android {
@@ -630,7 +634,11 @@
ss->mScript.clear();
s->incUserRef();
- ss->runCompiler(rsc, s.get(), resName, cacheDir);
+ if (!ss->runCompiler(rsc, s.get(), resName, cacheDir)) {
+ // Error during compile, destroy s and return null.
+ s->zeroUserRef();
+ return NULL;
+ }
ss->clear(rsc);
return s.get();
}
diff --git a/libs/rs/rsScriptC.h b/libs/rs/rsScriptC.h
index 483481e8..612e38a 100644
--- a/libs/rs/rsScriptC.h
+++ b/libs/rs/rsScriptC.h
@@ -81,7 +81,7 @@
void init(Context *rsc);
void clear(Context *rsc);
- void runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
+ bool runCompiler(Context *rsc, ScriptC *s, const char *resName, const char *cacheDir);
struct SymbolTable_t {
const char * mName;
diff --git a/libs/rs/rsScriptC_LibCL.cpp b/libs/rs/rsScriptC_LibCL.cpp
index 28c558d..02d33b7 100644
--- a/libs/rs/rsScriptC_LibCL.cpp
+++ b/libs/rs/rsScriptC_LibCL.cpp
@@ -24,26 +24,6 @@
using namespace android::renderscript;
-static float SC_acospi(float v) {
- return acosf(v)/ M_PI;
-}
-
-static float SC_asinpi(float v) {
- return asinf(v) / M_PI;
-}
-
-static float SC_atanpi(float v) {
- return atanf(v) / M_PI;
-}
-
-static float SC_atan2pi(float y, float x) {
- return atan2f(y, x) / M_PI;
-}
-
-static float SC_cospi(float v) {
- return cosf(v * M_PI);
-}
-
static float SC_exp10(float v) {
return pow(10.f, v);
}
@@ -58,6 +38,10 @@
return log10(v) / log10(2.f);
}
+static float SC_mad(float v1, float v2, float v3) {
+ return v1 * v2 + v3;
+}
+
static float SC_pown(float v, int p) {
return powf(v, (float)p);
}
@@ -79,14 +63,6 @@
return sinf(v);
}
-static float SC_sinpi(float v) {
- return sinf(v * M_PI);
-}
-
-static float SC_tanpi(float v) {
- return tanf(v * M_PI);
-}
-
//////////////////////////////////////////////////////////////////////////////
// Integer
//////////////////////////////////////////////////////////////////////////////
@@ -182,20 +158,16 @@
// OpenCL math
{ "_Z4acosf", (void *)&acosf, true },
{ "_Z5acoshf", (void *)&acoshf, true },
- { "_Z6acospif", (void *)&SC_acospi, true },
{ "_Z4asinf", (void *)&asinf, true },
{ "_Z5asinhf", (void *)&asinhf, true },
- { "_Z6asinpif", (void *)&SC_asinpi, true },
{ "_Z4atanf", (void *)&atanf, true },
{ "_Z5atan2ff", (void *)&atan2f, true },
- { "_Z6atanpif", (void *)&SC_atanpi, true },
- { "_Z7atan2piff", (void *)&SC_atan2pi, true },
+ { "_Z5atanhf", (void *)&atanhf, true },
{ "_Z4cbrtf", (void *)&cbrtf, true },
{ "_Z4ceilf", (void *)&ceilf, true },
{ "_Z8copysignff", (void *)©signf, true },
{ "_Z3cosf", (void *)&cosf, true },
{ "_Z4coshf", (void *)&coshf, true },
- { "_Z5cospif", (void *)&SC_cospi, true },
{ "_Z4erfcf", (void *)&erfcf, true },
{ "_Z3erff", (void *)&erff, true },
{ "_Z3expf", (void *)&expf, true },
@@ -215,33 +187,30 @@
{ "_Z5ilogbf", (void *)&ilogbf, true },
{ "_Z5ldexpfi", (void *)&ldexpf, true },
{ "_Z6lgammaf", (void *)&lgammaf, true },
+ { "_Z6lgammafPi", (void *)&lgammaf_r, true },
{ "_Z3logf", (void *)&logf, true },
{ "_Z4log2f", (void *)&SC_log2, true },
{ "_Z5log10f", (void *)&log10f, true },
{ "_Z5log1pf", (void *)&log1pf, true },
- //{ "logb", (void *)&, true },
- //{ "mad", (void *)&, true },
+ { "_Z4logbf", (void *)&logbf, true },
+ { "_Z3madfff", (void *)&SC_mad, true },
{ "_Z4modffPf", (void *)&modff, true },
//{ "nan", (void *)&, true },
{ "_Z9nextafterff", (void *)&nextafterf, true },
{ "_Z3powff", (void *)&powf, true },
- { "_Z4pownfi", (void *)&SC_pown, true },
- { "_Z4powrff", (void *)&SC_powr, true },
{ "_Z9remainderff", (void *)&remainderf, true },
- { "remquo", (void *)&remquof, true },
+ { "_Z6remquoffPi", (void *)&remquof, true },
{ "_Z4rintf", (void *)&rintf, true },
{ "_Z5rootnfi", (void *)&SC_rootn, true },
{ "_Z5roundf", (void *)&roundf, true },
{ "_Z5rsqrtf", (void *)&SC_rsqrt, true },
{ "_Z3sinf", (void *)&sinf, true },
- { "sincos", (void *)&SC_sincos, true },
+ { "_Z6sincosfPf", (void *)&SC_sincos, true },
{ "_Z4sinhf", (void *)&sinhf, true },
- { "_Z5sinpif", (void *)&SC_sinpi, true },
{ "_Z4sqrtf", (void *)&sqrtf, true },
{ "_Z3tanf", (void *)&tanf, true },
{ "_Z4tanhf", (void *)&tanhf, true },
- { "_Z5tanpif", (void *)&SC_tanpi, true },
- //{ "tgamma", (void *)&, true },
+ { "_Z6tgammaf", (void *)&lgammaf, true }, // FIXME!!! NEEDS TO USE tgammaf
{ "_Z5truncf", (void *)&truncf, true },
// OpenCL Int
diff --git a/libs/rs/scriptc/rs_cl.rsh b/libs/rs/scriptc/rs_cl.rsh
index ab8270f40..3c0496d 100644
--- a/libs/rs/scriptc/rs_cl.rsh
+++ b/libs/rs/scriptc/rs_cl.rsh
@@ -8,27 +8,31 @@
#endif
// Conversions
-#define CVT_FUNC_2(typeout, typein) \
-_RS_STATIC typeout##2 __attribute__((overloadable)) convert_##typeout##2(typein##2 v) { \
- typeout##2 r = {(typeout)v.x, (typeout)v.y}; \
- return r; \
-} \
-_RS_STATIC typeout##3 __attribute__((overloadable)) convert_##typeout##3(typein##3 v) { \
- typeout##3 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z}; \
- return r; \
-} \
-_RS_STATIC typeout##4 __attribute__((overloadable)) convert_##typeout##4(typein##4 v) { \
- typeout##4 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z, (typeout)v.w}; \
- return r; \
+#define CVT_FUNC_2(typeout, typein) \
+_RS_STATIC typeout##2 __attribute__((overloadable)) \
+ convert_##typeout##2(typein##2 v) { \
+ typeout##2 r = {(typeout)v.x, (typeout)v.y}; \
+ return r; \
+} \
+_RS_STATIC typeout##3 __attribute__((overloadable)) \
+ convert_##typeout##3(typein##3 v) { \
+ typeout##3 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z}; \
+ return r; \
+} \
+_RS_STATIC typeout##4 __attribute__((overloadable)) \
+ convert_##typeout##4(typein##4 v) { \
+ typeout##4 r = {(typeout)v.x, (typeout)v.y, (typeout)v.z, \
+ (typeout)v.w}; \
+ return r; \
}
-#define CVT_FUNC(type) CVT_FUNC_2(type, uchar) \
- CVT_FUNC_2(type, char) \
- CVT_FUNC_2(type, ushort) \
- CVT_FUNC_2(type, short) \
- CVT_FUNC_2(type, uint) \
- CVT_FUNC_2(type, int) \
- CVT_FUNC_2(type, float)
+#define CVT_FUNC(type) CVT_FUNC_2(type, uchar) \
+ CVT_FUNC_2(type, char) \
+ CVT_FUNC_2(type, ushort) \
+ CVT_FUNC_2(type, short) \
+ CVT_FUNC_2(type, uint) \
+ CVT_FUNC_2(type, int) \
+ CVT_FUNC_2(type, float)
CVT_FUNC(char)
CVT_FUNC(uchar)
@@ -38,341 +42,444 @@
CVT_FUNC(uint)
CVT_FUNC(float)
-
-
// Float ops, 6.11.2
-#define DEF_FUNC_1(fnc) \
+#define FN_FUNC_FN(fnc) \
_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v) { \
- float2 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- return r; \
-} \
+ float2 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ return r; \
+} \
_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v) { \
- float3 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- return r; \
-} \
+ float3 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ return r; \
+} \
_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v) { \
- float4 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- r.w = fnc(v.w); \
- return r; \
+ float4 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ r.w = fnc(v.w); \
+ return r; \
}
-#define DEF_FUNC_1_RI(fnc) \
-_RS_STATIC int2 __attribute__((overloadable)) fnc(float2 v) { \
- int2 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- return r; \
-} \
-_RS_STATIC int3 __attribute__((overloadable)) fnc(float3 v) { \
- int3 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- return r; \
-} \
-_RS_STATIC int4 __attribute__((overloadable)) fnc(float4 v) { \
- int4 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- r.w = fnc(v.w); \
- return r; \
+#define IN_FUNC_FN(fnc) \
+_RS_STATIC int2 __attribute__((overloadable)) fnc(float2 v) { \
+ int2 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ return r; \
+} \
+_RS_STATIC int3 __attribute__((overloadable)) fnc(float3 v) { \
+ int3 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ return r; \
+} \
+_RS_STATIC int4 __attribute__((overloadable)) fnc(float4 v) { \
+ int4 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ r.w = fnc(v.w); \
+ return r; \
}
-#define DEF_FUNC_2(fnc) \
+#define FN_FUNC_FN_FN(fnc) \
_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 v2) { \
- float2 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- return r; \
-} \
+ float2 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ return r; \
+} \
_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 v2) { \
- float3 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- r.z = fnc(v1.z, v2.z); \
- return r; \
-} \
+ float3 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ return r; \
+} \
_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 v2) { \
- float4 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- r.z = fnc(v1.z, v2.z); \
- r.w = fnc(v1.w, v2.w); \
- return r; \
+ float4 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ r.w = fnc(v1.w, v2.w); \
+ return r; \
}
-#define DEF_FUNC_2F(fnc) \
-_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
- float2 r; \
- r.x = fnc(v1.x, v2); \
- r.y = fnc(v1.y, v2); \
- return r; \
-} \
-_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
- float3 r; \
- r.x = fnc(v1.x, v2); \
- r.y = fnc(v1.y, v2); \
- r.z = fnc(v1.z, v2); \
- return r; \
-} \
-_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
- float4 r; \
- r.x = fnc(v1.x, v2); \
- r.y = fnc(v1.y, v2); \
- r.z = fnc(v1.z, v2); \
- r.w = fnc(v1.w, v2); \
- return r; \
+#define FN_FUNC_FN_F(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float v2) { \
+ float2 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float v2) { \
+ float3 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ r.z = fnc(v1.z, v2); \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float v2) { \
+ float4 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ r.z = fnc(v1.z, v2); \
+ r.w = fnc(v1.w, v2); \
+ return r; \
}
-#define DEF_FUNC_2P(fnc) \
-_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, float2 *v2) { \
- float2 r; \
- float q; \
- r.x = fnc(v1.x, &q); \
- v2->x = q; \
- r.y = fnc(v1.y, &q); \
- v2->y = q; \
- return r; \
-} \
-_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, float3 *v2) { \
- float3 r; \
- float q; \
- r.x = fnc(v1.x, &q); \
- v2->x = q; \
- r.y = fnc(v1.y, &q); \
- v2->y = q; \
- r.z = fnc(v1.z, &q); \
- v2->z = q; \
- return r; \
-} \
-_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, float4 *v2) { \
- float4 r; \
- float q; \
- r.x = fnc(v1.x, &q); \
- v2->x = q; \
- r.y = fnc(v1.y, &q); \
- v2->y = q; \
- r.z = fnc(v1.z, &q); \
- v2->z = q; \
- r.w = fnc(v1.w, &q); \
- v2->w = q; \
- return r; \
+#define FN_FUNC_FN_IN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int2 v2) { \
+ float2 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int3 v2) { \
+ float3 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int4 v2) { \
+ float4 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ r.w = fnc(v1.w, v2.w); \
+ return r; \
}
+#define FN_FUNC_FN_I(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int v2) { \
+ float2 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int v2) { \
+ float3 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ r.z = fnc(v1.z, v2); \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int v2) { \
+ float4 r; \
+ r.x = fnc(v1.x, v2); \
+ r.y = fnc(v1.y, v2); \
+ r.z = fnc(v1.z, v2); \
+ r.w = fnc(v1.w, v2); \
+ return r; \
+}
+
+#define FN_FUNC_FN_PFN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) \
+ fnc(float2 v1, float2 *v2) { \
+ float2 r; \
+ float t[2]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) \
+ fnc(float3 v1, float3 *v2) { \
+ float3 r; \
+ float t[3]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ r.z = fnc(v1.z, &t[2]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ v2->z = t[2]; \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) \
+ fnc(float4 v1, float4 *v2) { \
+ float4 r; \
+ float t[4]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ r.z = fnc(v1.z, &t[2]); \
+ r.w = fnc(v1.w, &t[3]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ v2->z = t[2]; \
+ v2->w = t[3]; \
+ return r; \
+}
+
+#define FN_FUNC_FN_PIN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) fnc(float2 v1, int2 *v2) { \
+ float2 r; \
+ int t[2]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) fnc(float3 v1, int3 *v2) { \
+ float3 r; \
+ int t[3]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ r.z = fnc(v1.z, &t[2]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ v2->z = t[2]; \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) fnc(float4 v1, int4 *v2) { \
+ float4 r; \
+ int t[4]; \
+ r.x = fnc(v1.x, &t[0]); \
+ r.y = fnc(v1.y, &t[1]); \
+ r.z = fnc(v1.z, &t[2]); \
+ r.w = fnc(v1.w, &t[3]); \
+ v2->x = t[0]; \
+ v2->y = t[1]; \
+ v2->z = t[2]; \
+ v2->w = t[3]; \
+ return r; \
+}
+
+#define FN_FUNC_FN_FN_FN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) \
+ fnc(float2 v1, float2 v2, float2 v3) { \
+ float2 r; \
+ r.x = fnc(v1.x, v2.x, v3.x); \
+ r.y = fnc(v1.y, v2.y, v3.y); \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) \
+ fnc(float3 v1, float3 v2, float3 v3) { \
+ float3 r; \
+ r.x = fnc(v1.x, v2.x, v3.x); \
+ r.y = fnc(v1.y, v2.y, v3.y); \
+ r.z = fnc(v1.z, v2.z, v3.z); \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) \
+ fnc(float4 v1, float4 v2, float4 v3) { \
+ float4 r; \
+ r.x = fnc(v1.x, v2.x, v3.x); \
+ r.y = fnc(v1.y, v2.y, v3.y); \
+ r.z = fnc(v1.z, v2.z, v3.z); \
+ r.w = fnc(v1.w, v2.w, v3.w); \
+ return r; \
+}
+
+#define FN_FUNC_FN_FN_PIN(fnc) \
+_RS_STATIC float2 __attribute__((overloadable)) \
+ fnc(float2 v1, float2 v2, int2 *v3) { \
+ float2 r; \
+ int t[2]; \
+ r.x = fnc(v1.x, v2.x, &t[0]); \
+ r.y = fnc(v1.y, v2.y, &t[1]); \
+ v3->x = t[0]; \
+ v3->y = t[1]; \
+ return r; \
+} \
+_RS_STATIC float3 __attribute__((overloadable)) \
+ fnc(float3 v1, float3 v2, int3 *v3) { \
+ float3 r; \
+ int t[3]; \
+ r.x = fnc(v1.x, v2.x, &t[0]); \
+ r.y = fnc(v1.y, v2.y, &t[1]); \
+ r.z = fnc(v1.z, v2.z, &t[2]); \
+ v3->x = t[0]; \
+ v3->y = t[1]; \
+ v3->z = t[2]; \
+ return r; \
+} \
+_RS_STATIC float4 __attribute__((overloadable)) \
+ fnc(float4 v1, float4 v2, int4 *v3) { \
+ float4 r; \
+ int t[4]; \
+ r.x = fnc(v1.x, v2.x, &t[0]); \
+ r.y = fnc(v1.y, v2.y, &t[1]); \
+ r.z = fnc(v1.z, v2.z, &t[2]); \
+ r.w = fnc(v1.w, v2.w, &t[3]); \
+ v3->x = t[0]; \
+ v3->y = t[1]; \
+ v3->z = t[2]; \
+ v3->w = t[3]; \
+ return r; \
+}
+
+
extern float __attribute__((overloadable)) acos(float);
-DEF_FUNC_1(acos)
+FN_FUNC_FN(acos)
extern float __attribute__((overloadable)) acosh(float);
-DEF_FUNC_1(acosh)
+FN_FUNC_FN(acosh)
_RS_STATIC float __attribute__((overloadable)) acospi(float v) {
return acos(v) / M_PI;
}
-DEF_FUNC_1(acospi)
+FN_FUNC_FN(acospi)
extern float __attribute__((overloadable)) asin(float);
-DEF_FUNC_1(asin)
+FN_FUNC_FN(asin)
extern float __attribute__((overloadable)) asinh(float);
-DEF_FUNC_1(asinh)
+FN_FUNC_FN(asinh)
_RS_STATIC float __attribute__((overloadable)) asinpi(float v) {
return asin(v) / M_PI;
}
-DEF_FUNC_1(asinpi)
+FN_FUNC_FN(asinpi)
extern float __attribute__((overloadable)) atan(float);
-DEF_FUNC_1(atan)
+FN_FUNC_FN(atan)
extern float __attribute__((overloadable)) atan2(float, float);
-DEF_FUNC_2(atan2)
+FN_FUNC_FN_FN(atan2)
extern float __attribute__((overloadable)) atanh(float);
-DEF_FUNC_1(atanh)
+FN_FUNC_FN(atanh)
_RS_STATIC float __attribute__((overloadable)) atanpi(float v) {
return atan(v) / M_PI;
}
-DEF_FUNC_1(atanpi)
+FN_FUNC_FN(atanpi)
_RS_STATIC float __attribute__((overloadable)) atan2pi(float y, float x) {
return atan2(y, x) / M_PI;
}
-DEF_FUNC_2(atan2pi)
+FN_FUNC_FN_FN(atan2pi)
extern float __attribute__((overloadable)) cbrt(float);
-DEF_FUNC_1(cbrt)
+FN_FUNC_FN(cbrt)
extern float __attribute__((overloadable)) ceil(float);
-DEF_FUNC_1(ceil)
+FN_FUNC_FN(ceil)
extern float __attribute__((overloadable)) copysign(float, float);
-DEF_FUNC_2(copysign)
+FN_FUNC_FN_FN(copysign)
extern float __attribute__((overloadable)) cos(float);
-DEF_FUNC_1(cos)
+FN_FUNC_FN(cos)
extern float __attribute__((overloadable)) cosh(float);
-DEF_FUNC_1(cosh)
+FN_FUNC_FN(cosh)
_RS_STATIC float __attribute__((overloadable)) cospi(float v) {
return cos(v * M_PI);
}
-DEF_FUNC_1(cospi)
+FN_FUNC_FN(cospi)
extern float __attribute__((overloadable)) erfc(float);
-DEF_FUNC_1(erfc)
+FN_FUNC_FN(erfc)
extern float __attribute__((overloadable)) erf(float);
-DEF_FUNC_1(erf)
+FN_FUNC_FN(erf)
extern float __attribute__((overloadable)) exp(float);
-DEF_FUNC_1(exp)
+FN_FUNC_FN(exp)
extern float __attribute__((overloadable)) exp2(float);
-DEF_FUNC_1(exp2)
+FN_FUNC_FN(exp2)
extern float __attribute__((overloadable)) pow(float, float);
_RS_STATIC float __attribute__((overloadable)) exp10(float v) {
return pow(10.f, v);
}
-DEF_FUNC_1(exp10)
+FN_FUNC_FN(exp10)
extern float __attribute__((overloadable)) expm1(float);
-DEF_FUNC_1(expm1)
+FN_FUNC_FN(expm1)
extern float __attribute__((overloadable)) fabs(float);
-DEF_FUNC_1(fabs)
+FN_FUNC_FN(fabs)
extern float __attribute__((overloadable)) fdim(float, float);
-DEF_FUNC_2(fdim)
+FN_FUNC_FN_FN(fdim)
extern float __attribute__((overloadable)) floor(float);
-DEF_FUNC_1(floor)
+FN_FUNC_FN(floor)
extern float __attribute__((overloadable)) fma(float, float, float);
-extern float2 __attribute__((overloadable)) fma(float2, float2, float2);
-extern float3 __attribute__((overloadable)) fma(float3, float3, float3);
-extern float4 __attribute__((overloadable)) fma(float4, float4, float4);
+FN_FUNC_FN_FN_FN(fma)
extern float __attribute__((overloadable)) fmax(float, float);
-DEF_FUNC_2(fmax);
-DEF_FUNC_2F(fmax);
+FN_FUNC_FN_FN(fmax);
+FN_FUNC_FN_F(fmax);
extern float __attribute__((overloadable)) fmin(float, float);
-DEF_FUNC_2(fmin);
-DEF_FUNC_2F(fmin);
+FN_FUNC_FN_FN(fmin);
+FN_FUNC_FN_F(fmin);
extern float __attribute__((overloadable)) fmod(float, float);
-DEF_FUNC_2(fmod)
+FN_FUNC_FN_FN(fmod)
_RS_STATIC float __attribute__((overloadable)) fract(float v, float *iptr) {
int i = (int)floor(v);
iptr[0] = i;
return fmin(v - i, 0x1.fffffep-1f);
}
-_RS_STATIC float2 __attribute__((overloadable)) fract(float2 v, float2 *iptr) {
- float t[2];
- float2 r;
- r.x = fract(v.x, &t[0]);
- r.y = fract(v.y, &t[1]);
- iptr[0] = t[0];
- iptr[1] = t[1];
- return r;
-}
-_RS_STATIC float3 __attribute__((overloadable)) fract(float3 v, float3 *iptr) {
- float t[3];
- float3 r;
- r.x = fract(v.x, &t[0]);
- r.y = fract(v.y, &t[1]);
- r.z = fract(v.z, &t[2]);
- iptr[0] = t[0];
- iptr[1] = t[1];
- iptr[2] = t[2];
- return r;
-}
-_RS_STATIC float4 __attribute__((overloadable)) fract(float4 v, float4 *iptr) {
- float t[4];
- float4 r;
- r.x = fract(v.x, &t[0]);
- r.y = fract(v.y, &t[1]);
- r.z = fract(v.z, &t[2]);
- r.w = fract(v.w, &t[3]);
- iptr[0] = t[0];
- iptr[1] = t[1];
- iptr[2] = t[2];
- iptr[3] = t[3];
- return r;
-}
+FN_FUNC_FN_PFN(fract)
-extern float __attribute__((overloadable)) frexp(float, float *);
-extern float2 __attribute__((overloadable)) frexp(float2, float2 *);
-extern float3 __attribute__((overloadable)) frexp(float3, float3 *);
-extern float4 __attribute__((overloadable)) frexp(float4, float4 *);
+extern float __attribute__((overloadable)) frexp(float, int *);
+FN_FUNC_FN_PIN(frexp)
extern float __attribute__((overloadable)) hypot(float, float);
-DEF_FUNC_2(hypot)
+FN_FUNC_FN_FN(hypot)
extern int __attribute__((overloadable)) ilogb(float);
-DEF_FUNC_1_RI(ilogb)
+IN_FUNC_FN(ilogb)
extern float __attribute__((overloadable)) ldexp(float, int);
-extern float2 __attribute__((overloadable)) ldexp(float2, int2);
-extern float3 __attribute__((overloadable)) ldexp(float3, int3);
-extern float4 __attribute__((overloadable)) ldexp(float4, int4);
-extern float2 __attribute__((overloadable)) ldexp(float2, int);
-extern float3 __attribute__((overloadable)) ldexp(float3, int);
-extern float4 __attribute__((overloadable)) ldexp(float4, int);
+FN_FUNC_FN_IN(ldexp)
+FN_FUNC_FN_I(ldexp)
extern float __attribute__((overloadable)) lgamma(float);
-DEF_FUNC_1(lgamma)
-extern float __attribute__((overloadable)) lgamma(float, float *);
-extern float2 __attribute__((overloadable)) lgamma(float2, float2 *);
-extern float3 __attribute__((overloadable)) lgamma(float3, float3 *);
-extern float4 __attribute__((overloadable)) lgamma(float4, float4 *);
+FN_FUNC_FN(lgamma)
+extern float __attribute__((overloadable)) lgamma(float, int*);
+FN_FUNC_FN_PIN(lgamma)
extern float __attribute__((overloadable)) log(float);
-DEF_FUNC_1(log)
+FN_FUNC_FN(log)
extern float __attribute__((overloadable)) log10(float);
-DEF_FUNC_1(log10)
+FN_FUNC_FN(log10)
_RS_STATIC float __attribute__((overloadable)) log2(float v) {
return log10(v) / log10(2.f);
}
-DEF_FUNC_1(log2)
+FN_FUNC_FN(log2)
extern float __attribute__((overloadable)) log1p(float);
-DEF_FUNC_1(log1p)
+FN_FUNC_FN(log1p)
extern float __attribute__((overloadable)) logb(float);
-DEF_FUNC_1(logb)
+FN_FUNC_FN(logb)
extern float __attribute__((overloadable)) mad(float, float, float);
-extern float2 __attribute__((overloadable)) mad(float2, float2, float2);
-extern float3 __attribute__((overloadable)) mad(float3, float3, float3);
-extern float4 __attribute__((overloadable)) mad(float4, float4, float4);
+FN_FUNC_FN_FN_FN(mad)
extern float __attribute__((overloadable)) modf(float, float *);
-DEF_FUNC_2P(modf);
+FN_FUNC_FN_PFN(modf);
//extern float __attribute__((overloadable)) nan(uint);
extern float __attribute__((overloadable)) nextafter(float, float);
-DEF_FUNC_2(nextafter)
+FN_FUNC_FN_FN(nextafter)
-DEF_FUNC_2(pow)
+FN_FUNC_FN_FN(pow)
_RS_STATIC float __attribute__((overloadable)) pown(float v, int p) {
return pow(v, (float)p);
@@ -401,15 +508,13 @@
}
extern float __attribute__((overloadable)) remainder(float, float);
-DEF_FUNC_2(remainder)
+FN_FUNC_FN_FN(remainder)
extern float __attribute__((overloadable)) remquo(float, float, int *);
-extern float2 __attribute__((overloadable)) remquo(float2, float2, int2 *);
-extern float3 __attribute__((overloadable)) remquo(float3, float3, int3 *);
-extern float4 __attribute__((overloadable)) remquo(float4, float4, int4 *);
+FN_FUNC_FN_FN_PIN(remquo)
extern float __attribute__((overloadable)) rint(float);
-DEF_FUNC_1(rint)
+FN_FUNC_FN(rint)
_RS_STATIC float __attribute__((overloadable)) rootn(float v, int r) {
return pow(v, 1.f / r);
@@ -428,16 +533,16 @@
}
extern float __attribute__((overloadable)) round(float);
-DEF_FUNC_1(round)
+FN_FUNC_FN(round)
extern float __attribute__((overloadable)) sqrt(float);
_RS_STATIC float __attribute__((overloadable)) rsqrt(float v) {
return 1.f / sqrt(v);
}
-DEF_FUNC_1(rsqrt)
+FN_FUNC_FN(rsqrt)
extern float __attribute__((overloadable)) sin(float);
-DEF_FUNC_1(sin)
+FN_FUNC_FN(sin)
_RS_STATIC float __attribute__((overloadable)) sincos(float v, float *cosptr) {
*cosptr = cos(v);
@@ -457,114 +562,118 @@
}
extern float __attribute__((overloadable)) sinh(float);
-DEF_FUNC_1(sinh)
+FN_FUNC_FN(sinh)
_RS_STATIC float __attribute__((overloadable)) sinpi(float v) {
return sin(v * M_PI);
}
-DEF_FUNC_1(sinpi)
+FN_FUNC_FN(sinpi)
-DEF_FUNC_1(sqrt)
+FN_FUNC_FN(sqrt)
extern float __attribute__((overloadable)) tan(float);
-DEF_FUNC_1(tan)
+FN_FUNC_FN(tan)
extern float __attribute__((overloadable)) tanh(float);
-DEF_FUNC_1(tanh)
+FN_FUNC_FN(tanh)
_RS_STATIC float __attribute__((overloadable)) tanpi(float v) {
return tan(v * M_PI);
}
-DEF_FUNC_1(tanpi)
+FN_FUNC_FN(tanpi)
extern float __attribute__((overloadable)) tgamma(float);
-DEF_FUNC_1(tgamma)
+FN_FUNC_FN(tgamma)
extern float __attribute__((overloadable)) trunc(float);
-DEF_FUNC_1(trunc)
+FN_FUNC_FN(trunc)
// Int ops (partial), 6.11.3
-#define DEF_RIFUNC_1(typeout, typein, fnc) \
-extern typeout __attribute__((overloadable)) fnc(typein); \
+#define XN_FUNC_YN(typeout, fnc, typein) \
+extern typeout __attribute__((overloadable)) fnc(typein); \
_RS_STATIC typeout##2 __attribute__((overloadable)) fnc(typein##2 v) { \
- typeout##2 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- return r; \
-} \
+ typeout##2 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ return r; \
+} \
_RS_STATIC typeout##3 __attribute__((overloadable)) fnc(typein##3 v) { \
- typeout##3 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- return r; \
-} \
+ typeout##3 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ return r; \
+} \
_RS_STATIC typeout##4 __attribute__((overloadable)) fnc(typein##4 v) { \
- typeout##4 r; \
- r.x = fnc(v.x); \
- r.y = fnc(v.y); \
- r.z = fnc(v.z); \
- r.w = fnc(v.w); \
- return r; \
+ typeout##4 r; \
+ r.x = fnc(v.x); \
+ r.y = fnc(v.y); \
+ r.z = fnc(v.z); \
+ r.w = fnc(v.w); \
+ return r; \
}
-#define DEF_UIFUNC_1(fnc) \
-DEF_RIFUNC_1(uchar, char, fnc) \
-DEF_RIFUNC_1(ushort, short, fnc) \
-DEF_RIFUNC_1(uint, int, fnc)
+#define UIN_FUNC_IN(fnc) \
+XN_FUNC_YN(uchar, fnc, char) \
+XN_FUNC_YN(ushort, fnc, short) \
+XN_FUNC_YN(uint, fnc, int)
-#define DEF_IFUNC_1(fnc) \
-DEF_RIFUNC_1(uchar, uchar, fnc) \
-DEF_RIFUNC_1(char, char, fnc) \
-DEF_RIFUNC_1(ushort, ushort, fnc) \
-DEF_RIFUNC_1(short, short, fnc) \
-DEF_RIFUNC_1(uint, uint, fnc) \
-DEF_RIFUNC_1(int, int, fnc)
+#define IN_FUNC_IN(fnc) \
+XN_FUNC_YN(uchar, fnc, uchar) \
+XN_FUNC_YN(char, fnc, char) \
+XN_FUNC_YN(ushort, fnc, ushort) \
+XN_FUNC_YN(short, fnc, short) \
+XN_FUNC_YN(uint, fnc, uint) \
+XN_FUNC_YN(int, fnc, int)
-#define DEF_RIFUNC_2(type, fnc, body) \
-_RS_STATIC type __attribute__((overloadable)) fnc(type v1, type v2) { \
- return body; \
-} \
-_RS_STATIC type##2 __attribute__((overloadable)) fnc(type##2 v1, type##2 v2) { \
- type##2 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- return r; \
-} \
-_RS_STATIC type##3 __attribute__((overloadable)) fnc(type##3 v1, type##3 v2) { \
- type##3 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- r.z = fnc(v1.z, v2.z); \
- return r; \
-} \
-_RS_STATIC type##4 __attribute__((overloadable)) fnc(type##4 v1, type##4 v2) { \
- type##4 r; \
- r.x = fnc(v1.x, v2.x); \
- r.y = fnc(v1.y, v2.y); \
- r.z = fnc(v1.z, v2.z); \
- r.w = fnc(v1.w, v2.w); \
- return r; \
-} \
+#define XN_FUNC_XN_XN_BODY(type, fnc, body) \
+_RS_STATIC type __attribute__((overloadable)) \
+ fnc(type v1, type v2) { \
+ return body; \
+} \
+_RS_STATIC type##2 __attribute__((overloadable)) \
+ fnc(type##2 v1, type##2 v2) { \
+ type##2 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ return r; \
+} \
+_RS_STATIC type##3 __attribute__((overloadable)) \
+ fnc(type##3 v1, type##3 v2) { \
+ type##3 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ return r; \
+} \
+_RS_STATIC type##4 __attribute__((overloadable)) \
+ fnc(type##4 v1, type##4 v2) { \
+ type##4 r; \
+ r.x = fnc(v1.x, v2.x); \
+ r.y = fnc(v1.y, v2.y); \
+ r.z = fnc(v1.z, v2.z); \
+ r.w = fnc(v1.w, v2.w); \
+ return r; \
+}
-#define DEF_IFUNC_2(fnc, body) \
-DEF_RIFUNC_2(uchar, fnc, body) \
-DEF_RIFUNC_2(char, fnc, body) \
-DEF_RIFUNC_2(ushort, fnc, body) \
-DEF_RIFUNC_2(short, fnc, body) \
-DEF_RIFUNC_2(uint, fnc, body) \
-DEF_RIFUNC_2(int, fnc, body) \
-DEF_RIFUNC_2(float, fnc, body)
+#define IN_FUNC_IN_IN_BODY(fnc, body) \
+XN_FUNC_XN_XN_BODY(uchar, fnc, body) \
+XN_FUNC_XN_XN_BODY(char, fnc, body) \
+XN_FUNC_XN_XN_BODY(ushort, fnc, body) \
+XN_FUNC_XN_XN_BODY(short, fnc, body) \
+XN_FUNC_XN_XN_BODY(uint, fnc, body) \
+XN_FUNC_XN_XN_BODY(int, fnc, body) \
+XN_FUNC_XN_XN_BODY(float, fnc, body)
-DEF_UIFUNC_1(abs)
-DEF_IFUNC_1(clz)
+UIN_FUNC_IN(abs)
+IN_FUNC_IN(clz)
-DEF_IFUNC_2(min, (v1 < v2 ? v1 : v2))
-DEF_FUNC_2F(min)
+IN_FUNC_IN_IN_BODY(min, (v1 < v2 ? v1 : v2))
+FN_FUNC_FN_F(min)
-DEF_IFUNC_2(max, (v1 > v2 ? v1 : v2))
-DEF_FUNC_2F(max)
+IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2))
+FN_FUNC_FN_F(max)
// 6.11.4
@@ -617,7 +726,7 @@
_RS_STATIC float __attribute__((overloadable)) degrees(float radians) {
return radians * (180.f / M_PI);
}
-DEF_FUNC_1(degrees)
+FN_FUNC_FN(degrees)
_RS_STATIC float __attribute__((overloadable)) mix(float start, float stop, float amount) {
return start + (stop - start) * amount;
@@ -644,7 +753,7 @@
_RS_STATIC float __attribute__((overloadable)) radians(float degrees) {
return degrees * (M_PI / 180.f);
}
-DEF_FUNC_1(radians)
+FN_FUNC_FN(radians)
_RS_STATIC float __attribute__((overloadable)) step(float edge, float v) {
return (v < edge) ? 0.f : 1.f;
@@ -705,7 +814,7 @@
if (v < 0) return -1.f;
return v;
}
-DEF_FUNC_1(sign)
+FN_FUNC_FN(sign)
// 6.11.5
_RS_STATIC float3 __attribute__((overloadable)) cross(float3 lhs, float3 rhs) {
@@ -779,15 +888,21 @@
#undef CVT_FUNC
#undef CVT_FUNC_2
-#undef DEF_FUNC_1
-#undef DEF_FUNC_1_RI
-#undef DEF_FUNC_2
-#undef DEF_FUNC_2F
-#undef DEF_RIFUNC_1
-#undef DEF_UIFUNC_1
-#undef DEF_IFUNC_1
-#undef DEF_RIFUNC_2
-#undef DEF_IFUNC_2
+#undef FN_FUNC_FN
+#undef IN_FUNC_FN
+#undef FN_FUNC_FN_FN
+#undef FN_FUNC_FN_F
+#undef FN_FUNC_FN_IN
+#undef FN_FUNC_FN_I
+#undef FN_FUNC_FN_PFN
+#undef FN_FUNC_FN_PIN
+#undef FN_FUNC_FN_FN_FN
+#undef FN_FUNC_FN_FN_PIN
+#undef XN_FUNC_YN
+#undef UIN_FUNC_IN
+#undef IN_FUNC_IN
+#undef XN_FUNC_XN_XN_BODY
+#undef IN_FUNC_IN_IN_BODY
#undef _RS_STATIC
#endif
diff --git a/libs/rs/scriptc/rs_types.rsh b/libs/rs/scriptc/rs_types.rsh
index 0f8717f..a010096 100644
--- a/libs/rs/scriptc/rs_types.rsh
+++ b/libs/rs/scriptc/rs_types.rsh
@@ -3,12 +3,7 @@
#define M_PI 3.14159265358979323846264338327950288f /* pi */
-//#include "external/clang/lib/Headers/stdbool.h"
-#define bool _Bool
-#define true 1
-#define false 0
-#define __bool_true_false_are_defined 1
-
+#include "stdbool.h"
typedef char int8_t;
typedef short int16_t;
typedef int int32_t;
diff --git a/libs/surfaceflinger_client/SharedBufferStack.cpp b/libs/surfaceflinger_client/SharedBufferStack.cpp
index af11f97..7505d53 100644
--- a/libs/surfaceflinger_client/SharedBufferStack.cpp
+++ b/libs/surfaceflinger_client/SharedBufferStack.cpp
@@ -58,7 +58,6 @@
void SharedBufferStack::init(int32_t i)
{
- inUse = -2;
status = NO_ERROR;
identity = i;
}
@@ -199,9 +198,9 @@
SharedBufferStack& stack( *mSharedStack );
snprintf(buffer, SIZE,
"%s[ head=%2d, available=%2d, queued=%2d ] "
- "reallocMask=%08x, inUse=%2d, identity=%d, status=%d",
+ "reallocMask=%08x, identity=%d, status=%d",
prefix, stack.head, stack.available, stack.queued,
- stack.reallocMask, stack.inUse, stack.identity, stack.status);
+ stack.reallocMask, stack.identity, stack.status);
result.append(buffer);
result.append("\n");
return result;
@@ -302,22 +301,6 @@
return NO_ERROR;
}
-SharedBufferServer::UnlockUpdate::UnlockUpdate(
- SharedBufferBase* sbb, int lockedBuffer)
- : UpdateBase(sbb), lockedBuffer(lockedBuffer) {
-}
-ssize_t SharedBufferServer::UnlockUpdate::operator()() {
- if (stack.inUse != lockedBuffer) {
- LOGE("unlocking %d, but currently locked buffer is %d "
- "(identity=%d, token=%d)",
- lockedBuffer, stack.inUse,
- stack.identity, stack.token);
- return BAD_VALUE;
- }
- android_atomic_write(-1, &stack.inUse);
- return NO_ERROR;
-}
-
SharedBufferServer::RetireUpdate::RetireUpdate(
SharedBufferBase* sbb, int numBuffers)
: UpdateBase(sbb), numBuffers(numBuffers) {
@@ -327,9 +310,6 @@
if (uint32_t(head) >= SharedBufferStack::NUM_BUFFER_MAX)
return BAD_VALUE;
- // Preventively lock the current buffer before updating queued.
- android_atomic_write(stack.headBuf, &stack.inUse);
-
// Decrement the number of queued buffers
int32_t queued;
do {
@@ -345,7 +325,6 @@
head = (head + 1) % numBuffers;
const int8_t headBuf = stack.index[head];
stack.headBuf = headBuf;
- android_atomic_write(headBuf, &stack.inUse);
// head is only modified here, so we don't need to use cmpxchg
android_atomic_write(head, &stack.head);
@@ -546,13 +525,6 @@
return buf;
}
-status_t SharedBufferServer::unlock(int buf)
-{
- UnlockUpdate update(this, buf);
- status_t err = updateCondition( update );
- return err;
-}
-
void SharedBufferServer::setStatus(status_t status)
{
if (status < NO_ERROR) {
@@ -694,12 +666,6 @@
stack.head = 0;
stack.headBuf = 0;
- // If one of the buffers is in use it must be the head buffer, which we are
- // renaming to buffer 0.
- if (stack.inUse > 0) {
- stack.inUse = 0;
- }
-
// Free the buffers from the end of the list that are no longer needed.
for (int i = newNumBuffers; i < mNumBuffers; i++) {
mBufferList.remove(i);
diff --git a/libs/ui/EGLUtils.cpp b/libs/ui/EGLUtils.cpp
index 1663313..f24a71d 100644
--- a/libs/ui/EGLUtils.cpp
+++ b/libs/ui/EGLUtils.cpp
@@ -66,12 +66,6 @@
if (outConfig == NULL)
return BAD_VALUE;
- int err;
- PixelFormatInfo fbFormatInfo;
- if ((err = getPixelFormatInfo(PixelFormat(format), &fbFormatInfo)) < 0) {
- return err;
- }
-
// Get all the "potential match" configs...
if (eglGetConfigs(dpy, NULL, 0, &numConfigs) == EGL_FALSE)
return BAD_VALUE;
@@ -81,23 +75,14 @@
free(configs);
return BAD_VALUE;
}
-
- const int fbSzA = fbFormatInfo.getSize(PixelFormatInfo::INDEX_ALPHA);
- const int fbSzR = fbFormatInfo.getSize(PixelFormatInfo::INDEX_RED);
- const int fbSzG = fbFormatInfo.getSize(PixelFormatInfo::INDEX_GREEN);
- const int fbSzB = fbFormatInfo.getSize(PixelFormatInfo::INDEX_BLUE);
int i;
EGLConfig config = NULL;
for (i=0 ; i<n ; i++) {
- EGLint r,g,b,a;
- EGLConfig curr = configs[i];
- eglGetConfigAttrib(dpy, curr, EGL_RED_SIZE, &r);
- eglGetConfigAttrib(dpy, curr, EGL_GREEN_SIZE, &g);
- eglGetConfigAttrib(dpy, curr, EGL_BLUE_SIZE, &b);
- eglGetConfigAttrib(dpy, curr, EGL_ALPHA_SIZE, &a);
- if (fbSzA == a && fbSzR == r && fbSzG == g && fbSzB == b) {
- config = curr;
+ EGLint nativeVisualId = 0;
+ eglGetConfigAttrib(dpy, configs[i], EGL_NATIVE_VISUAL_ID, &nativeVisualId);
+ if (nativeVisualId>0 && format == nativeVisualId) {
+ config = configs[i];
break;
}
}
diff --git a/libs/ui/GraphicBufferAllocator.cpp b/libs/ui/GraphicBufferAllocator.cpp
index ce84683..33ef1fc 100644
--- a/libs/ui/GraphicBufferAllocator.cpp
+++ b/libs/ui/GraphicBufferAllocator.cpp
@@ -61,7 +61,7 @@
const size_t c = list.size();
for (size_t i=0 ; i<c ; i++) {
const alloc_rec_t& rec(list.valueAt(i));
- snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %2d | 0x%08x\n",
+ snprintf(buffer, SIZE, "%10p: %7.2f KiB | %4u (%4u) x %4u | %8X | 0x%08x\n",
list.keyAt(i), rec.size/1024.0f,
rec.w, rec.s, rec.h, rec.format, rec.usage);
result.append(buffer);
diff --git a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
index c3862e2..122ad4e 100755
--- a/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
+++ b/media/java/android/media/videoeditor/MediaArtistNativeHelper.java
@@ -1814,9 +1814,10 @@
private void onProgressUpdate(int taskId, int progress) {
if (mProcessingState == PROCESSING_EXPORT) {
if (mExportProgressListener != null) {
- if ((progress % 2) == 0) {
- mProgressToApp++;
- mExportProgressListener.onProgress(mVideoEditor, mOutputFilename, mProgressToApp);
+ if (mProgressToApp < progress) {
+ mExportProgressListener.onProgress(mVideoEditor, mOutputFilename, progress);
+ /* record previous progress */
+ mProgressToApp = progress;
}
}
}
diff --git a/media/java/android/media/videoeditor/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java
index b03588f..1c02878 100755
--- a/media/java/android/media/videoeditor/MediaImageItem.java
+++ b/media/java/android/media/videoeditor/MediaImageItem.java
@@ -93,29 +93,28 @@
*
* @throws IOException
*/
- public MediaImageItem(VideoEditor editor, String mediaItemId,
- String filename, long durationMs,
- int renderingMode) throws IOException {
+ public MediaImageItem(VideoEditor editor, String mediaItemId, String filename, long durationMs,
+ int renderingMode) throws IOException {
super(editor, mediaItemId, filename, renderingMode);
mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
mVideoEditor = ((VideoEditorImpl)editor);
try {
- final Properties properties =
- mMANativeHelper.getMediaProperties(filename);
+ final Properties properties = mMANativeHelper.getMediaProperties(filename);
switch (mMANativeHelper.getFileType(properties.fileType)) {
case MediaProperties.FILE_JPEG:
+ case MediaProperties.FILE_PNG: {
break;
- case MediaProperties.FILE_PNG:
- break;
+ }
- default:
- throw new IllegalArgumentException("Unsupported Input File Type");
+ default: {
+ throw new IllegalArgumentException("Unsupported Input File Type");
+ }
}
} catch (Exception e) {
- throw new IllegalArgumentException("Unsupported file or file not found");
+ throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
}
/**
@@ -130,13 +129,13 @@
mDurationMs = durationMs;
mDecodedFilename = String.format(mMANativeHelper.getProjectPath() +
"/" + "decoded" + getId()+ ".rgb");
- final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
- final DataOutputStream dos = new DataOutputStream(fl);
+
try {
mAspectRatio = mMANativeHelper.getAspectRatio(mWidth, mHeight);
} catch(IllegalArgumentException e) {
throw new IllegalArgumentException ("Null width and height");
}
+
mGeneratedClipHeight = 0;
mGeneratedClipWidth = 0;
@@ -146,9 +145,12 @@
*/
final Pair<Integer, Integer>[] resolutions =
MediaProperties.getSupportedResolutions(mAspectRatio);
+
/**
* Get the highest resolution
*/
+ final FileOutputStream fl = new FileOutputStream(mDecodedFilename);
+ final DataOutputStream dos = new DataOutputStream(fl);
final Pair<Integer, Integer> maxResolution = resolutions[resolutions.length - 1];
if (mHeight > maxResolution.second) {
/**
@@ -171,16 +173,16 @@
int mNewHeight = 0;
if ((mScaledWidth % 2 ) != 0) {
mNewWidth = mScaledWidth - 1;
- }
- else {
+ } else {
mNewWidth = mScaledWidth;
}
+
if ((mScaledHeight % 2 ) != 0) {
mNewHeight = mScaledHeight - 1;
- }
- else {
+ } else {
mNewHeight = mScaledHeight;
}
+
final int [] framingBuffer = new int[mNewWidth];
final ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
IntBuffer intBuffer;
@@ -195,6 +197,7 @@
dos.write(array);
tmp += 1;
}
+
mScaledWidth = mNewWidth;
mScaledHeight = mNewHeight;
scaledImage.recycle();
@@ -204,10 +207,11 @@
+ "/" + "scaled" + getId()+ ".JPG");
if (!((new File(mScaledFilename)).exists())) {
super.mRegenerateClip = true;
- FileOutputStream f1 = new FileOutputStream(mScaledFilename);
+ final FileOutputStream f1 = new FileOutputStream(mScaledFilename);
scaledImage.compress(Bitmap.CompressFormat.JPEG, 50,f1);
f1.close();
}
+
mScaledWidth = scaledImage.getWidth();
mScaledHeight = scaledImage.getHeight();
@@ -215,17 +219,17 @@
int mNewheight = 0;
if ((mScaledWidth % 2 ) != 0) {
mNewWidth = mScaledWidth - 1;
- }
- else {
+ } else {
mNewWidth = mScaledWidth;
}
+
if ((mScaledHeight % 2 ) != 0) {
mNewheight = mScaledHeight - 1;
- }
- else {
+ } else {
mNewheight = mScaledHeight;
}
- Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
+
+ final Bitmap imageBitmap = BitmapFactory.decodeFile(mScaledFilename);
final int [] framingBuffer = new int[mNewWidth];
ByteBuffer byteBuffer = ByteBuffer.allocate(framingBuffer.length * 4);
IntBuffer intBuffer;
@@ -240,10 +244,12 @@
dos.write(array);
tmp += 1;
}
+
mScaledWidth = mNewWidth;
mScaledHeight = mNewheight;
imageBitmap.recycle();
}
+
fl.close();
System.gc();
}
@@ -286,7 +292,7 @@
/**
* @return The file name of image which is decoded and stored
- * in rgb format
+ * in RGB format
*/
String getDecodedImageFileName() {
return mDecodedFilename;
@@ -447,7 +453,7 @@
* Check if the effect overlaps with the end transition
*/
if (effect.getStartTime() + effect.getDuration() >
- mDurationMs - transitionDurationMs) {
+ mDurationMs - transitionDurationMs) {
mEndTransition.invalidate();
break;
}
@@ -464,7 +470,7 @@
* Check if the overlay overlaps with the end transition
*/
if (overlay.getStartTime() + overlay.getDuration() >
- mDurationMs - transitionDurationMs) {
+ mDurationMs - transitionDurationMs) {
mEndTransition.invalidate();
break;
}
@@ -648,23 +654,24 @@
for (int i = 0; i < thumbnailCount; i++) {
thumbnailArray[i] = thumbnail;
}
+
return thumbnailArray;
-
-
- }
- else {
+ } else {
if (startMs > endMs) {
throw new IllegalArgumentException("Start time is greater than end time");
}
+
if (endMs > mDurationMs) {
throw new IllegalArgumentException("End time is greater than file duration");
}
+
if (startMs == endMs) {
Bitmap[] bitmap = new Bitmap[1];
bitmap[0] = mMANativeHelper.getPixels(getGeneratedImageClip(),
width, height,startMs);
return bitmap;
}
+
return mMANativeHelper.getPixelsList(getGeneratedImageClip(), width,
height,startMs,endMs,thumbnailCount);
}
@@ -704,31 +711,51 @@
*/
if (mBeginTransition != null) {
final long transitionDurationMs = mBeginTransition.getDuration();
+ final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs, 0,
+ transitionDurationMs);
+ final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs, 0,
+ transitionDurationMs);
/**
- * If the start time has changed and if the old or the new item
- * overlaps with the begin transition, invalidate the transition.
+ * Invalidate transition if:
+ *
+ * 1. New item overlaps the transition, the old one did not
+ * 2. New item does not overlap the transition, the old one did
+ * 3. New and old item overlap the transition if begin or end
+ * time changed
*/
- if (((oldStartTimeMs != newStartTimeMs)
- || (oldDurationMs != newDurationMs) )&&
- (isOverlapping(oldStartTimeMs, oldDurationMs, 0, transitionDurationMs) ||
- isOverlapping(newStartTimeMs, newDurationMs, 0,
- transitionDurationMs))) {
+ if (newOverlap != oldOverlap) { // Overlap has changed
mBeginTransition.invalidate();
+ } else if (newOverlap) { // Both old and new overlap
+ if ((oldStartTimeMs != newStartTimeMs) ||
+ !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
+ newStartTimeMs + newDurationMs > transitionDurationMs)) {
+ mBeginTransition.invalidate();
+ }
}
}
if (mEndTransition != null) {
final long transitionDurationMs = mEndTransition.getDuration();
+ final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+ mDurationMs - transitionDurationMs, transitionDurationMs);
+ final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+ mDurationMs - transitionDurationMs, transitionDurationMs);
/**
- * If the start time + duration has changed and if the old or the new
- * item overlaps the end transition, invalidate the transition
+ * Invalidate transition if:
+ *
+ * 1. New item overlaps the transition, the old one did not
+ * 2. New item does not overlap the transition, the old one did
+ * 3. New and old item overlap the transition if begin or end
+ * time changed
*/
- if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
- (isOverlapping(oldStartTimeMs, oldDurationMs,
- mDurationMs - transitionDurationMs, transitionDurationMs) ||
- isOverlapping(newStartTimeMs, newDurationMs,
- mDurationMs - transitionDurationMs, transitionDurationMs))) {
+ if (newOverlap != oldOverlap) { // Overlap has changed
mEndTransition.invalidate();
+ } else if (newOverlap) { // Both old and new overlap
+ if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
+ ((oldStartTimeMs > mDurationMs - transitionDurationMs) ||
+ newStartTimeMs > mDurationMs - transitionDurationMs)) {
+ mEndTransition.invalidate();
+ }
}
}
}
@@ -743,10 +770,12 @@
setGeneratedImageClip(null);
setRegenerateClip(true);
}
+
if (mScaledFilename != null) {
new File(mScaledFilename).delete();
mScaledFilename = null;
}
+
if (mDecodedFilename != null) {
new File(mDecodedFilename).delete();
mDecodedFilename = null;
diff --git a/media/java/android/media/videoeditor/MediaVideoItem.java b/media/java/android/media/videoeditor/MediaVideoItem.java
index 772b360..2981b41 100755
--- a/media/java/android/media/videoeditor/MediaVideoItem.java
+++ b/media/java/android/media/videoeditor/MediaVideoItem.java
@@ -78,12 +78,9 @@
*
* @throws IOException if the file cannot be opened for reading
*/
- public MediaVideoItem(VideoEditor editor, String mediaItemId,
- String filename,
- int renderingMode)
- throws IOException {
- this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE,
- 100, false, null);
+ public MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
+ int renderingMode) throws IOException {
+ this(editor, mediaItemId, filename, renderingMode, 0, END_OF_FILE, 100, false, null);
}
/**
@@ -105,20 +102,22 @@
* @throws IOException if the file cannot be opened for reading
*/
MediaVideoItem(VideoEditor editor, String mediaItemId, String filename,
- int renderingMode,
- long beginMs, long endMs, int volumePercent, boolean muted,
+ int renderingMode, long beginMs, long endMs, int volumePercent, boolean muted,
String audioWaveformFilename) throws IOException {
super(editor, mediaItemId, filename, renderingMode);
+
if (editor instanceof VideoEditorImpl) {
mMANativeHelper = ((VideoEditorImpl)editor).getNativeContext();
mVideoEditor = ((VideoEditorImpl)editor);
}
- Properties properties = null;
+
+ final Properties properties;
try {
properties = mMANativeHelper.getMediaProperties(filename);
} catch ( Exception e) {
- throw new IllegalArgumentException("Unsupported file or file not found");
+ throw new IllegalArgumentException("Unsupported file or file not found: " + filename);
}
+
switch (mMANativeHelper.getFileType(properties.fileType)) {
case MediaProperties.FILE_3GP:
break;
@@ -163,8 +162,7 @@
mMuted = muted;
mAudioWaveformFilename = audioWaveformFilename;
if (audioWaveformFilename != null) {
- mWaveformData =
- new SoftReference<WaveformData>(
+ mWaveformData = new SoftReference<WaveformData>(
new WaveformData(audioWaveformFilename));
} else {
mWaveformData = null;
@@ -190,9 +188,11 @@
if (beginMs > mDurationMs) {
throw new IllegalArgumentException("setExtractBoundaries: Invalid start time");
}
+
if (endMs > mDurationMs) {
throw new IllegalArgumentException("setExtractBoundaries: Invalid end time");
}
+
if ((endMs != -1) && (beginMs >= endMs) ) {
throw new IllegalArgumentException("setExtractBoundaries: Start time is greater than end time");
}
@@ -255,18 +255,18 @@
*/
@Override
public Bitmap getThumbnail(int width, int height, long timeMs) {
- if (timeMs > mDurationMs)
- {
+ if (timeMs > mDurationMs) {
throw new IllegalArgumentException("Time Exceeds duration");
}
- if (timeMs < 0)
- {
+
+ if (timeMs < 0) {
throw new IllegalArgumentException("Invalid Time duration");
}
- if ((width <=0) || (height <= 0))
- {
+
+ if ((width <=0) || (height <= 0)) {
throw new IllegalArgumentException("Invalid Dimensions");
}
+
return mMANativeHelper.getPixels(super.getFilename(),
width, height,timeMs);
}
@@ -280,18 +280,21 @@
if (startMs > endMs) {
throw new IllegalArgumentException("Start time is greater than end time");
}
+
if (endMs > mDurationMs) {
throw new IllegalArgumentException("End time is greater than file duration");
}
+
if ((height <= 0) || (width <= 0)) {
throw new IllegalArgumentException("Invalid dimension");
}
+
if (startMs == endMs) {
- Bitmap[] bitmap = new Bitmap[1];
- bitmap[0] = mMANativeHelper.getPixels(super.getFilename(),
- width, height,startMs);
+ final Bitmap[] bitmap = new Bitmap[1];
+ bitmap[0] = mMANativeHelper.getPixels(super.getFilename(), width, height,startMs);
return bitmap;
}
+
return mMANativeHelper.getPixelsList(super.getFilename(), width,
height,startMs,endMs,thumbnailCount);
}
@@ -324,40 +327,58 @@
* {@inheritDoc}
*/
@Override
- void invalidateTransitions(long oldStartTimeMs, long oldDurationMs,
- long newStartTimeMs,
+ void invalidateTransitions(long oldStartTimeMs, long oldDurationMs, long newStartTimeMs,
long newDurationMs) {
/**
* Check if the item overlaps with the beginning and end transitions
*/
if (mBeginTransition != null) {
final long transitionDurationMs = mBeginTransition.getDuration();
+ final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+ mBeginBoundaryTimeMs, transitionDurationMs);
+ final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+ mBeginBoundaryTimeMs, transitionDurationMs);
/**
- * If the start time has changed and if the old or the new item
- * overlaps with the begin transition, invalidate the transition.
+ * Invalidate transition if:
+ *
+ * 1. New item overlaps the transition, the old one did not
+ * 2. New item does not overlap the transition, the old one did
+ * 3. New and old item overlap the transition if begin or end
+ * time changed
*/
- if (((oldStartTimeMs != newStartTimeMs)
- || (oldDurationMs != newDurationMs) )&&
- (isOverlapping(oldStartTimeMs, oldDurationMs,
- mBeginBoundaryTimeMs, transitionDurationMs) ||
- isOverlapping(newStartTimeMs, newDurationMs,
- mBeginBoundaryTimeMs, transitionDurationMs))) {
+ if (newOverlap != oldOverlap) { // Overlap has changed
mBeginTransition.invalidate();
+ } else if (newOverlap) { // Both old and new overlap
+ if ((oldStartTimeMs != newStartTimeMs) ||
+ !(oldStartTimeMs + oldDurationMs > transitionDurationMs &&
+ newStartTimeMs + newDurationMs > transitionDurationMs)) {
+ mBeginTransition.invalidate();
+ }
}
}
if (mEndTransition != null) {
final long transitionDurationMs = mEndTransition.getDuration();
+ final boolean oldOverlap = isOverlapping(oldStartTimeMs, oldDurationMs,
+ mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
+ final boolean newOverlap = isOverlapping(newStartTimeMs, newDurationMs,
+ mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs);
/**
- * If the start time + duration has changed and if the old or the new
- * item overlaps the end transition, invalidate the transition
+ * Invalidate transition if:
+ *
+ * 1. New item overlaps the transition, the old one did not
+ * 2. New item does not overlap the transition, the old one did
+ * 3. New and old item overlap the transition if begin or end
+ * time changed
*/
- if (oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs &&
- (isOverlapping(oldStartTimeMs, oldDurationMs,
- mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs) ||
- isOverlapping(newStartTimeMs, newDurationMs,
- mEndBoundaryTimeMs - transitionDurationMs, transitionDurationMs))) {
+ if (newOverlap != oldOverlap) { // Overlap has changed
mEndTransition.invalidate();
+ } else if (newOverlap) { // Both old and new overlap
+ if ((oldStartTimeMs + oldDurationMs != newStartTimeMs + newDurationMs) ||
+ ((oldStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs) ||
+ newStartTimeMs > mEndBoundaryTimeMs - transitionDurationMs)) {
+ mEndTransition.invalidate();
+ }
}
}
}
@@ -434,7 +455,7 @@
throw new IllegalArgumentException("requested time not correct");
}
- Surface surface = surfaceHolder.getSurface();
+ final Surface surface = surfaceHolder.getSurface();
if (surface == null) {
throw new RuntimeException("Surface could not be retrieved from Surface holder");
}
@@ -442,8 +463,7 @@
if (mFilename != null) {
return mMANativeHelper.renderMediaItemPreviewFrame(surface,
mFilename,timeMs,mWidth,mHeight);
- }
- else {
+ } else {
return 0;
}
}
@@ -462,7 +482,7 @@
* Audio track
*/
public void extractAudioWaveform(ExtractAudioWaveformProgressListener listener)
- throws IOException {
+ throws IOException {
int frameDuration = 0;
int sampleCount = 0;
final String projectPath = mMANativeHelper.getProjectPath();
@@ -481,19 +501,17 @@
* Logic to get frame duration = (no. of frames per sample * 1000)/
* sampling frequency
*/
- if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+ if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AMRNB ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRNB*1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRNB;
- }
- else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+ } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AMRWB ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AMRWB * 1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
sampleCount = MediaProperties.SAMPLES_PER_FRAME_AMRWB;
- }
- else if ( mMANativeHelper.getAudioCodecType(mAudioType) ==
+ } else if (mMANativeHelper.getAudioCodecType(mAudioType) ==
MediaProperties.ACODEC_AAC_LC ) {
frameDuration = (MediaProperties.SAMPLES_PER_FRAME_AAC * 1000)/
MediaProperties.DEFAULT_SAMPLING_FREQUENCY;
@@ -682,5 +700,4 @@
return clipSettings;
}
-
}
diff --git a/media/java/android/media/videoeditor/VideoEditorImpl.java b/media/java/android/media/videoeditor/VideoEditorImpl.java
index 71c2624..885daf2 100755
--- a/media/java/android/media/videoeditor/VideoEditorImpl.java
+++ b/media/java/android/media/videoeditor/VideoEditorImpl.java
@@ -1776,7 +1776,7 @@
*/
int height = 480;
int width = 854;
- switch (getAspectRatio()) {
+ switch (mI.getAspectRatio()) {
case MediaProperties.ASPECT_RATIO_3_2:
width = 720;
break;
diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk
index 27c41be..0a01fb2 100755
--- a/media/jni/mediaeditor/Android.mk
+++ b/media/jni/mediaeditor/Android.mk
@@ -85,6 +85,6 @@
# to add this library to the prelink map and set this to true.
LOCAL_PRELINK_MODULE := false
-LOCAL_MODULE_TAGS := eng development
+LOCAL_MODULE_TAGS := optional
include $(BUILD_SHARED_LIBRARY)
diff --git a/media/jni/mediaeditor/VideoEditorLogging.h b/media/jni/mediaeditor/VideoEditorLogging.h
index ca8c047..c13f6ff 100755
--- a/media/jni/mediaeditor/VideoEditorLogging.h
+++ b/media/jni/mediaeditor/VideoEditorLogging.h
@@ -21,12 +21,13 @@
#define VIDEOEDIT_LOG_INDENTATION (3)
+#define VIDEOEDIT_LOG_ERROR __android_log_print
+#define VIDEOEDIT_LOG_EXCEPTION __android_log_print
+
#ifdef VIDEOEDIT_LOGGING_ENABLED
#define VIDEOEDIT_LOG_ALLOCATION __android_log_print
#define VIDEOEDIT_LOG_API __android_log_print
-#define VIDEOEDIT_LOG_ERROR __android_log_print
-#define VIDEOEDIT_LOG_EXCEPTION __android_log_print
#define VIDEOEDIT_LOG_FUNCTION __android_log_print
#define VIDEOEDIT_LOG_RESULT(x,y, ...) LOGI(y, __VA_ARGS__ )
#define VIDEOEDIT_LOG_SETTING __android_log_print
@@ -40,8 +41,6 @@
#define VIDEOEDIT_LOG_ALLOCATION (void)
#define VIDEOEDIT_LOG_API (void)
-#define VIDEOEDIT_LOG_ERROR (void)
-#define VIDEOEDIT_LOG_EXCEPTION (void)
#define VIDEOEDIT_LOG_FUNCTION (void)
#define VIDEOEDIT_LOG_RESULT (void)
#define VIDEOEDIT_LOG_SETTING (void)
diff --git a/media/jni/mediaeditor/VideoEditorMain.cpp b/media/jni/mediaeditor/VideoEditorMain.cpp
index e66e4b9..643f698 100755
--- a/media/jni/mediaeditor/VideoEditorMain.cpp
+++ b/media/jni/mediaeditor/VideoEditorMain.cpp
@@ -437,7 +437,7 @@
VideoEditor_renderPreviewFrameStr frameStr;
M4OSA_Context tnContext = M4OSA_NULL;
const char* pMessage = NULL;
- M4VIFI_ImagePlane *yuvPlane;
+ M4VIFI_ImagePlane *yuvPlane = NULL;
VIDEOEDIT_LOG_FUNCTION(ANDROID_LOG_INFO,
"VIDEO_EDITOR", "surfaceWidth = %d",surfaceWidth);
@@ -1179,7 +1179,7 @@
}
/** Remove the alpha channel */
- for (int i = 0, j = 0; i < frameSize_argb; i++) {
+ for (size_t i = 0, j = 0; i < frameSize_argb; i++) {
if ((i % 4) == 0) continue;
pFramingCtx->FramingRgb->pac_data[j] = pTmpData[i];
j++;
@@ -2729,7 +2729,7 @@
} M4AM_Buffer;
-M4OSA_UInt8 logLookUp[256]{
+M4OSA_UInt8 logLookUp[256] = {
0,120,137,146,154,159,163,167,171,173,176,178,181,182,184,186,188,189,190,192,193,
194,195,196,198,199,199,200,201,202,203,204,205,205,206,207,207,208,209,209,210,
211,211,212,212,213,213,214,215,215,216,216,216,217,217,218,218,219,219,220,220,
@@ -2788,7 +2788,7 @@
err = M4OSA_fileReadOpen (&inputFileHandle, pInputFileURL, M4OSA_kFileRead);
if (inputFileHandle == M4OSA_NULL) {
VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
- "M4MA_generateAudioGraphFile: Cannot open input file 0x%x", err);
+ "M4MA_generateAudioGraphFile: Cannot open input file 0x%lx", err);
return err;
}
@@ -2822,7 +2822,7 @@
bufferIn.m_bufferSize = samplesCountInBytes*sizeof(M4OSA_UInt16);
} else {
VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR",
- "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%x",\
+ "M4MA_generateAudioGraphFile: Malloc failed for bufferIn.m_dataAddress 0x%lx",
M4ERR_ALLOC);
return M4ERR_ALLOC;
}
@@ -2862,7 +2862,7 @@
if (err != M4NO_ERROR) {
// if out value of bytes-read is 0, break
if ( numBytesToRead == 0) {
- VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%x",\
+ VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "numBytesToRead 0x%lx",
numBytesToRead);
break; /* stop if file is empty or EOF */
}
@@ -2914,7 +2914,7 @@
} while (numBytesToRead != 0);
- VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%x", volumeValuesCount);
+ VIDEOEDIT_LOG_ERROR(ANDROID_LOG_INFO, "VIDEO_EDITOR", "loop 0x%lx", volumeValuesCount);
/* if some error occured in fwrite */
if (numBytesToRead != 0) {
diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp
index 153b2a6..65df68c 100644
--- a/media/libmediaplayerservice/StagefrightRecorder.cpp
+++ b/media/libmediaplayerservice/StagefrightRecorder.cpp
@@ -1295,12 +1295,6 @@
status_t err = OK;
sp<MediaWriter> writer = new MPEG4Writer(outputFd);
- // Add audio source first if it exists
- if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
- err = setupAudioEncoder(writer);
- if (err != OK) return err;
- *totalBitRate += mAudioBitRate;
- }
if (mVideoSource == VIDEO_SOURCE_DEFAULT
|| mVideoSource == VIDEO_SOURCE_CAMERA) {
@@ -1332,6 +1326,15 @@
*totalBitRate += videoBitRate;
}
+ // Audio source is added at the end if it exists.
+ // This help make sure that the "recoding" sound is suppressed for
+ // camcorder applications in the recorded files.
+ if (!mCaptureTimeLapse && (mAudioSource != AUDIO_SOURCE_LIST_END)) {
+ err = setupAudioEncoder(writer);
+ if (err != OK) return err;
+ *totalBitRate += mAudioBitRate;
+ }
+
if (mInterleaveDurationUs > 0) {
reinterpret_cast<MPEG4Writer *>(writer.get())->
setInterleaveDuration(mInterleaveDurationUs);
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
index 7f534c0..1fcf92b 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.cpp
@@ -92,11 +92,11 @@
}
void NuPlayer::pause() {
- // XXX to be implemented
+ (new AMessage(kWhatPause, id()))->post();
}
void NuPlayer::resume() {
- // XXX to be implemented
+ (new AMessage(kWhatResume, id()))->post();
}
void NuPlayer::resetAsync() {
@@ -430,6 +430,20 @@
break;
}
+ case kWhatPause:
+ {
+ CHECK(mRenderer != NULL);
+ mRenderer->pause();
+ break;
+ }
+
+ case kWhatResume:
+ {
+ CHECK(mRenderer != NULL);
+ mRenderer->resume();
+ break;
+ }
+
default:
TRESPASS();
break;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayer.h b/media/libmediaplayerservice/nuplayer/NuPlayer.h
index 339b628..bb65162 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayer.h
@@ -75,6 +75,8 @@
kWhatRendererNotify,
kWhatReset,
kWhatSeek,
+ kWhatPause,
+ kWhatResume,
};
wp<NuPlayerDriver> mDriver;
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
index 5833697..369a3a8 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.cpp
@@ -40,9 +40,10 @@
mAnchorTimeRealUs(-1),
mFlushingAudio(false),
mFlushingVideo(false),
- mHasAudio(mAudioSink != NULL),
- mHasVideo(true),
- mSyncQueues(mHasAudio && mHasVideo) {
+ mHasAudio(false),
+ mHasVideo(false),
+ mSyncQueues(false),
+ mPaused(false) {
}
NuPlayer::Renderer::~Renderer() {
@@ -93,6 +94,14 @@
mSyncQueues = mHasAudio && mHasVideo;
}
+void NuPlayer::Renderer::pause() {
+ (new AMessage(kWhatPause, id()))->post();
+}
+
+void NuPlayer::Renderer::resume() {
+ (new AMessage(kWhatResume, id()))->post();
+}
+
void NuPlayer::Renderer::onMessageReceived(const sp<AMessage> &msg) {
switch (msg->what()) {
case kWhatDrainAudioQueue:
@@ -151,6 +160,18 @@
break;
}
+ case kWhatPause:
+ {
+ onPause();
+ break;
+ }
+
+ case kWhatResume:
+ {
+ onResume();
+ break;
+ }
+
default:
TRESPASS();
break;
@@ -158,7 +179,7 @@
}
void NuPlayer::Renderer::postDrainAudioQueue() {
- if (mDrainAudioQueuePending || mSyncQueues) {
+ if (mDrainAudioQueuePending || mSyncQueues || mPaused) {
return;
}
@@ -254,7 +275,7 @@
}
void NuPlayer::Renderer::postDrainVideoQueue() {
- if (mDrainVideoQueuePending || mSyncQueues) {
+ if (mDrainVideoQueuePending || mSyncQueues || mPaused) {
return;
}
@@ -339,6 +360,12 @@
int32_t audio;
CHECK(msg->findInt32("audio", &audio));
+ if (audio) {
+ mHasAudio = true;
+ } else {
+ mHasVideo = true;
+ }
+
if (dropBufferWhileFlushing(audio, msg)) {
return;
}
@@ -528,5 +555,39 @@
notify->post();
}
+void NuPlayer::Renderer::onPause() {
+ CHECK(!mPaused);
+
+ mDrainAudioQueuePending = false;
+ ++mAudioQueueGeneration;
+
+ mDrainVideoQueuePending = false;
+ ++mVideoQueueGeneration;
+
+ if (mHasAudio) {
+ mAudioSink->pause();
+ }
+
+ mPaused = true;
+}
+
+void NuPlayer::Renderer::onResume() {
+ CHECK(mPaused);
+
+ if (mHasAudio) {
+ mAudioSink->start();
+ }
+
+ mPaused = false;
+
+ if (!mAudioQueue.empty()) {
+ postDrainAudioQueue();
+ }
+
+ if (!mVideoQueue.empty()) {
+ postDrainVideoQueue();
+ }
+}
+
} // namespace android
diff --git a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
index dbf3ecff..703e971 100644
--- a/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
+++ b/media/libmediaplayerservice/nuplayer/NuPlayerRenderer.h
@@ -41,6 +41,9 @@
void signalAudioSinkChanged();
+ void pause();
+ void resume();
+
enum {
kWhatEOS,
kWhatFlushComplete,
@@ -60,6 +63,8 @@
kWhatQueueEOS,
kWhatFlush,
kWhatAudioSinkChanged,
+ kWhatPause,
+ kWhatResume,
};
struct QueueEntry {
@@ -91,6 +96,8 @@
bool mHasVideo;
bool mSyncQueues;
+ bool mPaused;
+
void onDrainAudioQueue();
void postDrainAudioQueue();
@@ -101,6 +108,8 @@
void onQueueEOS(const sp<AMessage> &msg);
void onFlush(const sp<AMessage> &msg);
void onAudioSinkChanged();
+ void onPause();
+ void onResume();
void notifyEOS(bool audio);
void notifyFlushComplete(bool audio);
diff --git a/media/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp
index 58c4a2e..11ac56c 100644
--- a/media/libstagefright/AwesomePlayer.cpp
+++ b/media/libstagefright/AwesomePlayer.cpp
@@ -58,6 +58,8 @@
static int64_t kLowWaterMarkUs = 2000000ll; // 2secs
static int64_t kHighWaterMarkUs = 10000000ll; // 10secs
+static const size_t kLowWaterMarkBytes = 40000;
+static const size_t kHighWaterMarkBytes = 200000;
struct AwesomeEvent : public TimedEventQueue::Event {
AwesomeEvent(
@@ -610,9 +612,6 @@
// We don't know the bitrate of the stream, use absolute size
// limits to maintain the cache.
- const size_t kLowWaterMarkBytes = 40000;
- const size_t kHighWaterMarkBytes = 200000;
-
if ((mFlags & PLAYING) && !eos
&& (cachedDataRemaining < kLowWaterMarkBytes)) {
LOGI("cache is running low (< %d) , pausing.",
@@ -1535,6 +1534,34 @@
mConnectingDataSource.clear();
dataSource = mCachedSource;
+
+ // We're going to prefill the cache before trying to instantiate
+ // the extractor below, as the latter is an operation that otherwise
+ // could block on the datasource for a significant amount of time.
+ // During that time we'd be unable to abort the preparation phase
+ // without this prefill.
+
+ mLock.unlock();
+
+ for (;;) {
+ status_t finalStatus;
+ size_t cachedDataRemaining =
+ mCachedSource->approxDataRemaining(&finalStatus);
+
+ if (finalStatus != OK || cachedDataRemaining >= kHighWaterMarkBytes
+ || (mFlags & PREPARE_CANCELLED)) {
+ break;
+ }
+
+ usleep(200000);
+ }
+
+ mLock.lock();
+
+ if (mFlags & PREPARE_CANCELLED) {
+ LOGI("Prepare cancelled while waiting for initial cache fill.");
+ return UNKNOWN_ERROR;
+ }
} else if (!strncasecmp(mUri.string(), "httplive://", 11)) {
String8 uri("http://");
uri.append(mUri.string() + 11);
diff --git a/media/libstagefright/MPEG4Writer.cpp b/media/libstagefright/MPEG4Writer.cpp
index 06c4c98..a47ee3a 100644
--- a/media/libstagefright/MPEG4Writer.cpp
+++ b/media/libstagefright/MPEG4Writer.cpp
@@ -590,6 +590,7 @@
status_t err = OK;
int64_t maxDurationUs = 0;
+ int64_t minDurationUs = 0x7fffffffffffffffLL;
for (List<Track *>::iterator it = mTracks.begin();
it != mTracks.end(); ++it) {
status_t status = (*it)->stop();
@@ -601,6 +602,14 @@
if (durationUs > maxDurationUs) {
maxDurationUs = durationUs;
}
+ if (durationUs < minDurationUs) {
+ minDurationUs = durationUs;
+ }
+ }
+
+ if (mTracks.size() > 1) {
+ LOGD("Duration from tracks range is [%lld, %lld] us",
+ minDurationUs, maxDurationUs);
}
stopWriterThread();
diff --git a/media/libstagefright/NuCachedSource2.cpp b/media/libstagefright/NuCachedSource2.cpp
index 20f1655..741aa1c 100644
--- a/media/libstagefright/NuCachedSource2.cpp
+++ b/media/libstagefright/NuCachedSource2.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
+//#define LOG_NDEBUG 0
#define LOG_TAG "NuCachedSource2"
#include <utils/Log.h>
@@ -487,4 +488,5 @@
String8 NuCachedSource2::getUri() {
return mSource->getUri();
}
+
} // namespace android
diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp
index 5979be6..c6c36e3 100644
--- a/media/libstagefright/httplive/LiveSession.cpp
+++ b/media/libstagefright/httplive/LiveSession.cpp
@@ -438,8 +438,7 @@
if (mSeqNumber < firstSeqNumberInPlaylist
|| mSeqNumber > lastSeqNumberInPlaylist) {
- if (mSeqNumber < firstSeqNumberInPlaylist
- && mPrevBandwidthIndex != (ssize_t)bandwidthIndex) {
+ if (mPrevBandwidthIndex != (ssize_t)bandwidthIndex) {
// Go back to the previous bandwidth.
LOGI("new bandwidth does not have the sequence number "
@@ -493,16 +492,35 @@
CHECK(buffer != NULL);
- CHECK_EQ((status_t)OK,
- decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer));
+ err = decryptBuffer(mSeqNumber - firstSeqNumberInPlaylist, buffer);
+
+ if (err != OK) {
+ LOGE("decryptBuffer failed w/ error %d", err);
+
+ mDataSource->queueEOS(err);
+ return;
+ }
if (buffer->size() == 0 || buffer->data()[0] != 0x47) {
// Not a transport stream???
LOGE("This doesn't look like a transport stream...");
- mDataSource->queueEOS(ERROR_UNSUPPORTED);
- return;
+ mBandwidthItems.removeAt(bandwidthIndex);
+
+ if (mBandwidthItems.isEmpty()) {
+ mDataSource->queueEOS(ERROR_UNSUPPORTED);
+ return;
+ }
+
+ LOGI("Retrying with a different bandwidth stream.");
+
+ mLastPlaylistFetchTimeUs = -1;
+ bandwidthIndex = getBandwidthIndex();
+ mPrevBandwidthIndex = bandwidthIndex;
+ mSeqNumber = -1;
+
+ goto rinse_repeat;
}
if ((size_t)mPrevBandwidthIndex != bandwidthIndex) {
diff --git a/media/libstagefright/mpeg2ts/ATSParser.cpp b/media/libstagefright/mpeg2ts/ATSParser.cpp
index d8ab080..4335b99 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.cpp
+++ b/media/libstagefright/mpeg2ts/ATSParser.cpp
@@ -75,6 +75,10 @@
struct ATSParser::Stream : public RefBase {
Stream(Program *program, unsigned elementaryPID, unsigned streamType);
+ unsigned type() const { return mStreamType; }
+ unsigned pid() const { return mElementaryPID; }
+ void setPID(unsigned pid) { mElementaryPID = pid; }
+
void parse(
unsigned payload_unit_start_indicator,
ABitReader *br);
@@ -95,6 +99,7 @@
sp<ABuffer> mBuffer;
sp<AnotherPacketSource> mSource;
bool mPayloadStarted;
+ DiscontinuityType mPendingDiscontinuity;
ElementaryStreamQueue mQueue;
@@ -107,6 +112,8 @@
void extractAACFrames(const sp<ABuffer> &buffer);
+ void deferDiscontinuity(DiscontinuityType type);
+
DISALLOW_EVIL_CONSTRUCTORS(Stream);
};
@@ -155,6 +162,11 @@
}
}
+struct StreamInfo {
+ unsigned mType;
+ unsigned mPID;
+};
+
void ATSParser::Program::parseProgramMap(ABitReader *br) {
unsigned table_id = br->getBits(8);
LOGV(" table_id = %u", table_id);
@@ -188,6 +200,8 @@
br->skipBits(program_info_length * 8); // skip descriptors
+ Vector<StreamInfo> infos;
+
// infoBytesRemaining is the number of bytes that make up the
// variable length section of ES_infos. It does not include the
// final CRC.
@@ -231,24 +245,48 @@
CHECK_EQ(info_bytes_remaining, 0u);
#endif
- ssize_t index = mStreams.indexOfKey(elementaryPID);
-#if 0 // XXX revisit
- CHECK_LT(index, 0);
- mStreams.add(elementaryPID,
- new Stream(this, elementaryPID, streamType));
-#else
- if (index < 0) {
- mStreams.add(elementaryPID,
- new Stream(this, elementaryPID, streamType));
- }
-#endif
+ StreamInfo info;
+ info.mType = streamType;
+ info.mPID = elementaryPID;
+ infos.push(info);
infoBytesRemaining -= 5 + ES_info_length;
}
CHECK_EQ(infoBytesRemaining, 0u);
-
MY_LOGV(" CRC = 0x%08x", br->getBits(32));
+
+ bool PIDsChanged = false;
+ for (size_t i = 0; i < infos.size(); ++i) {
+ StreamInfo &info = infos.editItemAt(i);
+
+ ssize_t index = mStreams.indexOfKey(info.mPID);
+
+ if (index >= 0 && mStreams.editValueAt(index)->type() != info.mType) {
+ LOGI("uh oh. stream PIDs have changed.");
+ PIDsChanged = true;
+ break;
+ }
+ }
+
+ if (PIDsChanged) {
+ mStreams.clear();
+ }
+
+ for (size_t i = 0; i < infos.size(); ++i) {
+ StreamInfo &info = infos.editItemAt(i);
+
+ ssize_t index = mStreams.indexOfKey(info.mPID);
+
+ if (index < 0) {
+ sp<Stream> stream = new Stream(this, info.mPID, info.mType);
+ mStreams.add(info.mPID, stream);
+
+ if (PIDsChanged) {
+ stream->signalDiscontinuity(DISCONTINUITY_FORMATCHANGE);
+ }
+ }
+ }
}
sp<MediaSource> ATSParser::Program::getSource(SourceType type) {
@@ -290,6 +328,7 @@
mStreamType(streamType),
mBuffer(new ABuffer(192 * 1024)),
mPayloadStarted(false),
+ mPendingDiscontinuity(DISCONTINUITY_NONE),
mQueue(streamType == 0x1b
? ElementaryStreamQueue::H264 : ElementaryStreamQueue::AAC) {
mBuffer->setRange(0, 0);
@@ -336,9 +375,13 @@
{
mQueue.clear(true);
- if (mStreamType == 0x1b && mSource != NULL) {
+ if (mStreamType == 0x1b) {
// Don't signal discontinuities on audio streams.
- mSource->queueDiscontinuity(type);
+ if (mSource != NULL) {
+ mSource->queueDiscontinuity(type);
+ } else {
+ deferDiscontinuity(type);
+ }
}
break;
}
@@ -352,6 +395,8 @@
if (mSource != NULL) {
mSource->queueDiscontinuity(type);
+ } else {
+ deferDiscontinuity(type);
}
break;
}
@@ -362,6 +407,13 @@
}
}
+void ATSParser::Stream::deferDiscontinuity(DiscontinuityType type) {
+ if (type > mPendingDiscontinuity) {
+ // Only upgrade discontinuities.
+ mPendingDiscontinuity = type;
+ }
+}
+
void ATSParser::Stream::signalEOS(status_t finalResult) {
if (mSource != NULL) {
mSource->signalEOS(finalResult);
@@ -558,6 +610,11 @@
LOGV("created source!");
mSource = new AnotherPacketSource(meta);
+ if (mPendingDiscontinuity != DISCONTINUITY_NONE) {
+ mSource->queueDiscontinuity(mPendingDiscontinuity);
+ mPendingDiscontinuity = DISCONTINUITY_NONE;
+ }
+
mSource->queueAccessUnit(accessUnit);
}
} else if (mQueue.getFormat() != NULL) {
diff --git a/media/libstagefright/mpeg2ts/ATSParser.h b/media/libstagefright/mpeg2ts/ATSParser.h
index fe31981..ec3be84 100644
--- a/media/libstagefright/mpeg2ts/ATSParser.h
+++ b/media/libstagefright/mpeg2ts/ATSParser.h
@@ -33,6 +33,7 @@
struct ATSParser : public RefBase {
enum DiscontinuityType {
+ DISCONTINUITY_NONE,
DISCONTINUITY_HTTPLIVE,
DISCONTINUITY_SEEK,
DISCONTINUITY_FORMATCHANGE
diff --git a/packages/SystemUI/assets/fonts/AndroidClock.ttf b/packages/SystemUI/assets/fonts/AndroidClock.ttf
index 3945183..7b550eed 100644
--- a/packages/SystemUI/assets/fonts/AndroidClock.ttf
+++ b/packages/SystemUI/assets/fonts/AndroidClock.ttf
Binary files differ
diff --git a/packages/SystemUI/assets/fonts/AndroidClock2.ttf b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
index fa0221e..a95d548 100644
--- a/packages/SystemUI/assets/fonts/AndroidClock2.ttf
+++ b/packages/SystemUI/assets/fonts/AndroidClock2.ttf
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png
new file mode 100644
index 0000000..9812339
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png
new file mode 100644
index 0000000..4f61511
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png
new file mode 100644
index 0000000..4757125
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png
new file mode 100644
index 0000000..8436f5a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png
new file mode 100644
index 0000000..6005075
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png
new file mode 100644
index 0000000..83068a9
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png
new file mode 100644
index 0000000..e6f2f34
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png
new file mode 100644
index 0000000..2249d01
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png
new file mode 100644
index 0000000..ca3bb5d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png
new file mode 100644
index 0000000..2591521
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png
new file mode 100644
index 0000000..56a4a1d
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png
new file mode 100644
index 0000000..7754657
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png
new file mode 100644
index 0000000..afc4057
--- /dev/null
+++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
index dadb0cd..92ffde9 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_default.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
index 51d7cc2..0cd05a30 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
index 3359602..993ea55 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
index f865e7a..7d381dd 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_large.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
index 04588bb..954621b 100644
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
+++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lights_out_dot_small.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png
new file mode 100644
index 0000000..22d6c79
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png
new file mode 100644
index 0000000..24166da
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png
new file mode 100644
index 0000000..85d9795
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
new file mode 100644
index 0000000..b389a35
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/panel_notification.png b/packages/SystemUI/res/drawable-mdpi/panel_notification.png
new file mode 100644
index 0000000..3789f3c
--- /dev/null
+++ b/packages/SystemUI/res/drawable-mdpi/panel_notification.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
deleted file mode 100755
index e9589d9..0000000
--- a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-hdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-xlarge-hdpi/recents_bg_protect_tile.png
new file mode 100644
index 0000000..a57c27a
--- /dev/null
+++ b/packages/SystemUI/res/drawable-xlarge-hdpi/recents_bg_protect_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_bg_protect_tile.png b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_bg_protect_tile.png
index 55d38d8..87c7be6 100644
--- a/packages/SystemUI/res/drawable-xlarge-mdpi/recents_bg_protect_tile.png
+++ b/packages/SystemUI/res/drawable-xlarge-mdpi/recents_bg_protect_tile.png
Binary files differ
diff --git a/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml b/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml
new file mode 100644
index 0000000..0371322
--- /dev/null
+++ b/packages/SystemUI/res/drawable/notify_panel_bg_protect_tiled.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<bitmap
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/notify_panel_bg_protect"
+ android:tileMode="repeat"
+ />
+
diff --git a/packages/SystemUI/res/drawable/status_bar_item_background.xml b/packages/SystemUI/res/drawable/status_bar_item_background.xml
index 9da92a7..3a50aa9 100644
--- a/packages/SystemUI/res/drawable/status_bar_item_background.xml
+++ b/packages/SystemUI/res/drawable/status_bar_item_background.xml
@@ -20,7 +20,6 @@
>
<item
android:drawable="@drawable/notification_item_background_color"
- android:left="16dp"
/>
</layer-list>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml
index 0533b6f..852b729 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml
@@ -78,15 +78,14 @@
</LinearLayout>
<!-- fake space bar zone -->
- <com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/fake_space_bar"
+ <com.android.systemui.statusbar.policy.EventHole android:id="@+id/fake_space_bar"
android:layout_height="match_parent"
- android:layout_width="match_parent"
+ android:layout_width="0dp"
android:paddingLeft="8dip"
android:paddingRight="8dip"
android:layout_toRightOf="@+id/navigationArea"
android:layout_toLeftOf="@+id/notificationArea"
android:visibility="gone"
- systemui:keyCode="62"
/>
</RelativeLayout>
</FrameLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
index 72e2c0b..5a41421 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_area.xml
@@ -53,7 +53,6 @@
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="center_vertical"
- android:paddingTop="5dp"
android:layout_marginLeft="8dp"
/>
</com.android.systemui.statusbar.tablet.NotificationIconArea>
@@ -63,23 +62,25 @@
android:id="@+id/notificationTrigger"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:gravity="center"
>
<com.android.systemui.statusbar.tablet.HoloClock
android:id="@+id/clock"
android:layout_width="wrap_content"
- android:layout_height="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="4dp"
>
<TextView android:id="@+id/time_bg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:singleLine="true"
- android:textSize="72dip"
+ android:textSize="40sp"
android:textColor="#1f1f1f" />
<TextView android:id="@+id/time_fg"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:singleLine="true"
- android:textSize="72dip"
+ android:textSize="40sp"
android:textColor="#2e2e2e" />
</com.android.systemui.statusbar.tablet.HoloClock>
@@ -101,14 +102,13 @@
android:id="@+id/signal_battery_cluster"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:layout_marginRight="8dp"
android:orientation="horizontal"
android:gravity="center"
>
<FrameLayout
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="top"
- android:layout_marginTop="19dp"
android:layout_marginRight="4dp"
>
<ImageView
@@ -126,10 +126,6 @@
android:id="@+id/battery"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
- android:layout_gravity="top"
- android:layout_marginTop="19dp"
- android:layout_marginLeft="2dp"
- android:layout_marginRight="2dp"
/>
</LinearLayout>
</LinearLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
index 7f84b21..4cf28ee 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel.xml
@@ -18,159 +18,37 @@
<com.android.systemui.statusbar.tablet.NotificationPanel
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:id="@+id/panel_root"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:gravity="right"
+ android:background="@drawable/notify_panel_bg_protect_tiled"
>
- <View
- android:id="@+id/scrim"
- android:background="@drawable/notify_panel_bg_protect"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:layout_alignParentTop="true"
- android:layout_alignParentRight="true"
- />
-
<RelativeLayout
android:id="@+id/content_parent"
android:layout_height="wrap_content"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
>
- <RelativeLayout
- android:id="@+id/title_area"
- android:layout_height="160dp"
- android:layout_width="384dp"
- android:layout_marginLeft="24dp"
- android:paddingTop="20dp"
- android:orientation="vertical"
+
+ <include layout="@layout/status_bar_notification_panel_title"
+ android:layout_width="471dp"
+ android:layout_height="465dp"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
- android:background="@drawable/panel_notification_tiled"
- >
-
- <com.android.systemui.statusbar.tablet.HoloClock
- android:id="@+id/clock"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_alignParentTop="true"
- android:layout_marginRight="40dip"
- android:layout_marginBottom="4dip"
- >
- <TextView android:id="@+id/time_bg"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="right"
- android:singleLine="true"
- android:textSize="90dip"
- android:textColor="#999999" />
- <TextView android:id="@+id/time_fg"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="right"
- android:singleLine="true"
- android:textSize="90dip"
- android:textColor="#666666" />
- </com.android.systemui.statusbar.tablet.HoloClock>
-
- <com.android.systemui.statusbar.policy.DateView
- android:id="@+id/date"
- style="@style/StatusBarNotificationText"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:layout_below="@id/clock"
- android:layout_marginTop="4dp"
- android:layout_marginRight="48dp"
- android:gravity="right"
- />
-
- <ImageView
- android:id="@+id/battery"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_alignParentLeft="true"
- android:layout_below="@id/date"
- android:layout_marginLeft="48dp"
- android:layout_marginTop="18dp"
- android:layout_marginRight="8dp"
- android:baseline="15dp"
- />
-
- <TextView
- android:id="@+id/battery_text"
- style="@style/StatusBarNotificationText"
- android:layout_width="56dp"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/battery"
- android:layout_alignBaseline="@id/battery"
- android:singleLine="true"
- android:text="@string/status_bar_settings_settings_button"
- />
-
- <ImageView
- android:id="@+id/network_signal"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_toRightOf="@id/battery_text"
- android:layout_alignBaseline="@id/battery"
- android:layout_marginRight="8dp"
- android:baseline="15dp"
- />
-
- <ImageView
- android:id="@+id/network_type"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:layout_toRightOf="@id/battery_text"
- android:layout_alignBaseline="@id/battery"
- android:layout_marginRight="8dp"
- android:baseline="15dp"
- />
-
- <TextView
- android:id="@+id/network_text"
- style="@style/StatusBarNotificationText"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_toRightOf="@id/network_signal"
- android:layout_alignBaseline="@id/battery"
- android:singleLine="true"
- android:text="@string/status_bar_settings_settings_button"
- />
-
- <ImageView
- android:id="@+id/settings_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignBaseline="@id/battery"
- android:layout_alignParentRight="true"
- android:paddingRight="16dp"
- android:src="@drawable/ic_notification_open"
- android:baseline="21dp"
- />
-
- <ImageView
- android:id="@+id/notification_button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentRight="true"
- android:layout_alignBaseline="@id/battery"
- android:paddingRight="16dp"
- android:visibility="invisible"
- android:src="@drawable/status_bar_veto"
- android:baseline="21dp"
- />
- </RelativeLayout>
+ />
<LinearLayout
android:id="@+id/content_frame"
+ android:background="@drawable/notify_panel_notify_bg"
android:layout_height="wrap_content"
- android:layout_width="408dp"
+ android:layout_width="447dp"
android:orientation="vertical"
- android:layout_below="@id/title_area"
android:layout_alignParentRight="true"
+ android:layout_alignParentTop="true"
+ android:layout_marginTop="352dp"
>
<ScrollView
android:id="@+id/notification_scroller"
@@ -183,23 +61,13 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal|bottom"
- android:animateLayoutChanges="true"
- android:animationCache="false"
android:orientation="vertical"
android:clickable="true"
android:focusable="true"
android:descendantFocusability="afterDescendants"
- systemui:insetLeft="16dp"
>
</com.android.systemui.statusbar.tablet.NotificationLinearLayout>
</ScrollView>
- <ImageView
- android:id="@+id/notification_glow"
- android:layout_width="match_parent"
- android:layout_height="@dimen/status_bar_panel_bottom_offset"
- android:layout_marginLeft="16dp"
- android:src="@drawable/notify_item_glow_bottom"
- />
</LinearLayout>
</RelativeLayout>
@@ -211,7 +79,7 @@
android:layout_alignTop="@id/content_parent"
android:layout_alignLeft="@id/content_parent"
android:layout_marginLeft="100dip"
- android:layout_marginTop="-100dip"
+ android:layout_marginTop="50dip"
/>
</com.android.systemui.statusbar.tablet.NotificationPanel>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
new file mode 100644
index 0000000..40f2247
--- /dev/null
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_panel_title.xml
@@ -0,0 +1,158 @@
+<!--
+ Copyright (C) 2006 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<RelativeLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
+ android:id="@+id/title_area"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:orientation="vertical"
+ android:background="@drawable/notify_panel_clock_bg"
+ >
+ <ImageView
+ android:id="@+id/network_signal"
+ android:layout_height="32dp"
+ android:layout_width="32dp"
+ android:scaleType="centerInside"
+ android:layout_alignParentLeft="true"
+ android:layout_alignParentBottom="true"
+ android:baseline="22dp"
+ android:layout_marginLeft="32dp"
+ android:layout_marginTop="16dp"
+ android:layout_marginBottom="16dp"
+ />
+
+ <ImageView
+ android:id="@+id/network_type"
+ android:layout_height="wrap_content"
+ android:layout_width="wrap_content"
+ android:layout_alignLeft="@id/network_signal"
+ android:layout_alignBottom="@id/network_signal"
+ android:layout_marginRight="8dp"
+ />
+
+ <TextView
+ android:id="@+id/network_text"
+ style="@style/StatusBarNotificationText"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/network_signal"
+ android:layout_marginRight="8dp"
+ android:layout_alignBaseline="@id/network_signal"
+ android:singleLine="true"
+ android:text="@string/status_bar_settings_settings_button"
+ />
+
+ <ImageView
+ android:id="@+id/battery"
+ android:layout_height="32dp"
+ android:layout_width="32dp"
+ android:scaleType="centerInside"
+ android:layout_toRightOf="@id/network_text"
+ android:layout_alignBaseline="@id/network_signal"
+ android:baseline="22dp"
+ />
+
+ <TextView
+ android:id="@+id/battery_text"
+ style="@style/StatusBarNotificationText"
+ android:layout_width="56dp"
+ android:layout_height="wrap_content"
+ android:layout_toRightOf="@id/battery"
+ android:layout_alignBaseline="@id/battery"
+ android:layout_marginRight="8dp"
+ android:singleLine="true"
+ android:text="@string/status_bar_settings_settings_button"
+ />
+
+ <ImageView
+ android:id="@+id/settings_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignBaseline="@id/battery"
+ android:layout_alignParentRight="true"
+ android:paddingRight="16dp"
+ android:src="@drawable/ic_notification_open"
+ android:baseline="21dp"
+ />
+
+ <ImageView
+ android:id="@+id/notification_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_alignBaseline="@id/battery"
+ android:paddingRight="16dp"
+ android:visibility="invisible"
+ android:src="@drawable/status_bar_veto"
+ android:baseline="21dp"
+ />
+
+ <View
+ android:id="@+id/title_divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_marginLeft="32dp"
+ android:layout_alignParentRight="true"
+ android:layout_alignParentBottom="true"
+ android:layout_marginBottom="64dip"
+ android:background="@android:drawable/divider_horizontal_dark"
+ />
+
+ <com.android.systemui.statusbar.tablet.HoloClock
+ android:id="@+id/clock"
+ android:layout_height="wrap_content"
+ android:layout_width="match_parent"
+ android:layout_alignParentRight="true"
+ android:layout_above="@id/title_divider"
+ android:layout_marginRight="32dip"
+ android:layout_marginBottom="8dip"
+ >
+ <TextView android:id="@+id/time_bg"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right"
+ android:singleLine="true"
+ android:textSize="72sp"
+ android:textColor="#999999" />
+ <TextView android:id="@+id/time_fg"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="right"
+ android:singleLine="true"
+ android:textSize="72sp"
+ android:textColor="#666666" />
+ </com.android.systemui.statusbar.tablet.HoloClock>
+
+ <com.android.systemui.statusbar.policy.DateView
+ android:id="@+id/date"
+ style="@style/StatusBarNotificationText"
+ android:layout_height="wrap_content"
+ android:layout_width="120dp"
+ android:layout_alignBottom="@id/clock"
+ android:layout_alignParentLeft="true"
+ android:gravity="left"
+ android:layout_marginLeft="32dp"
+ />
+
+ <Button
+ android:id="@+id/mode_toggle"
+ android:background="@null"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ />
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml b/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
index e97345b..233cb46 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_notification_row.xml
@@ -32,7 +32,6 @@
android:layout_alignParentTop="true"
android:layout_toRightOf="@id/large_icon"
android:layout_toLeftOf="@id/veto"
- android:layout_marginLeft="16dp"
android:focusable="true"
android:clickable="true"
/>
@@ -40,7 +39,6 @@
<View
android:layout_width="match_parent"
android:layout_height="1dp"
- android:layout_marginLeft="16dp"
android:layout_alignParentBottom="true"
android:background="@android:drawable/divider_horizontal_dark"
/>
diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
index 8a477e4..20a992da 100644
--- a/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
+++ b/packages/SystemUI/res/layout-xlarge/status_bar_settings_view.xml
@@ -22,8 +22,7 @@
android:layout_height="wrap_content"
android:orientation="vertical"
android:background="@drawable/status_bar_item_background"
- android:paddingLeft="16dp"
- android:paddingRight="46dp"
+ android:paddingRight="48dp"
>
<!-- Airplane mode -->
@@ -66,14 +65,6 @@
style="@style/StatusBarPanelSettingsContents"
android:text="@string/status_bar_settings_wifi_button"
/>
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:layout_marginTop="16dp"
- android:layout_marginRight="2dp"
- android:src="@drawable/ic_notification_open"
- />
</LinearLayout>
<View style="@style/StatusBarPanelSettingsPanelSeparator" />
@@ -159,14 +150,6 @@
style="@style/StatusBarPanelSettingsContents"
android:text="@string/status_bar_settings_settings_button"
/>
- <ImageView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_gravity="top"
- android:layout_marginTop="16dp"
- android:layout_marginRight="2dp"
- android:src="@drawable/ic_notification_open"
- />
</LinearLayout>
<View style="@style/StatusBarPanelSettingsPanelSeparator" />
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
new file mode 100644
index 0000000..47e758c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/EventHole.java
@@ -0,0 +1,99 @@
+/*
+ * 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 com.android.systemui.statusbar.policy;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.Region;
+import android.graphics.drawable.AnimationDrawable;
+import android.graphics.drawable.Drawable;
+import android.os.RemoteException;
+import android.os.SystemClock;
+import android.os.ServiceManager;
+import android.util.AttributeSet;
+import android.util.Slog;
+import android.view.HapticFeedbackConstants;
+import android.view.IWindowManager;
+import android.view.InputDevice;
+import android.view.KeyCharacterMap;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewTreeObserver;
+import android.widget.RemoteViews.RemoteView;
+
+import com.android.systemui.R;
+
+public class EventHole extends View implements ViewTreeObserver.OnComputeInternalInsetsListener {
+ private static final String TAG = "StatusBar.EventHole";
+
+ private boolean mWindowVis;
+ private int[] mLoc = new int[2];
+
+ public EventHole(Context context, AttributeSet attrs) {
+ this(context, attrs, 0);
+ }
+
+ public EventHole(Context context, AttributeSet attrs, int defStyle) {
+ super(context, attrs);
+ }
+
+ @Override
+ protected void onWindowVisibilityChanged(int visibility) {
+ super.onWindowVisibilityChanged(visibility);
+ mWindowVis = visibility == View.VISIBLE;
+ }
+
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ getViewTreeObserver().addOnComputeInternalInsetsListener(this);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ getViewTreeObserver().removeOnComputeInternalInsetsListener(this);
+ }
+
+ public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
+ final boolean visible = isShown() && mWindowVis && getWidth() > 0 && getHeight() > 0;
+ final int[] loc = mLoc;
+ getLocationInWindow(loc);
+ final int l = loc[0];
+ final int r = l + getWidth();
+ final int t = loc[1];
+ final int b = t + getHeight();
+
+ View top = this;
+ while (top.getParent() instanceof View) {
+ top = (View)top.getParent();
+ }
+
+ if (visible) {
+ info.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ info.touchableRegion.set(0, 0, top.getWidth(), top.getHeight());
+ info.touchableRegion.op(l, t, r, b, Region.Op.DIFFERENCE);
+ } else {
+ info.setTouchableInsets(
+ ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_FRAME);
+ }
+ }
+}
+
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
index 7012ddc..28f485c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java
@@ -124,9 +124,9 @@
if (subtype != null) {
return pm.getDrawable(imi.getPackageName(), subtype.getIconResId(),
imi.getServiceInfo().applicationInfo);
- } else if (imi.getSubtypes().size() > 0) {
+ } else if (imi.getSubtypeCount() > 0) {
return pm.getDrawable(imi.getPackageName(),
- imi.getSubtypes().get(0).getIconResId(),
+ imi.getSubtypeAt(0).getIconResId(),
imi.getServiceInfo().applicationInfo);
} else {
try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
index cc200e3..a3ccef9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodsPanel.java
@@ -342,9 +342,9 @@
if (subtype != null) {
return mPackageManager.getDrawable(imi.getPackageName(), subtype.getIconResId(),
imi.getServiceInfo().applicationInfo);
- } else if (imi.getSubtypes().size() > 0) {
+ } else if (imi.getSubtypeCount() > 0) {
return mPackageManager.getDrawable(imi.getPackageName(),
- imi.getSubtypes().get(0).getIconResId(),
+ imi.getSubtypeAt(0).getIconResId(),
imi.getServiceInfo().applicationInfo);
} else {
try {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 45a22b6..9f48b48 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.tablet;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
@@ -32,10 +33,10 @@
import android.view.ViewGroup;
import android.view.animation.AccelerateInterpolator;
import android.widget.FrameLayout;
+import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
-import android.widget.FrameLayout;
import android.widget.TextView;
import com.android.systemui.R;
@@ -47,14 +48,14 @@
boolean mShowing;
View mTitleArea;
+ View mModeToggle;
View mSettingsButton;
View mNotificationButton;
View mNotificationScroller;
- View mNotificationGlow;
ViewGroup mContentFrame;
- Rect mContentArea;
+ Rect mContentArea = new Rect();
View mSettingsView;
- View mScrim, mGlow;
+ View mGlow;
ViewGroup mContentParent;
Choreographer mChoreo = new Choreographer();
@@ -76,16 +77,15 @@
mContentParent = (ViewGroup)findViewById(R.id.content_parent);
mContentParent.bringToFront();
mTitleArea = findViewById(R.id.title_area);
- mTitleArea.setOnClickListener(this);
+ mModeToggle = findViewById(R.id.mode_toggle);
+ mModeToggle.setOnClickListener(this);
- mScrim = findViewById(R.id.scrim);
mGlow = findViewById(R.id.glow);
mSettingsButton = (ImageView)findViewById(R.id.settings_button);
mNotificationButton = (ImageView)findViewById(R.id.notification_button);
mNotificationScroller = findViewById(R.id.notification_scroller);
- mNotificationGlow = findViewById(R.id.notification_glow);
mContentFrame = (ViewGroup)findViewById(R.id.content_frame);
}
@@ -101,7 +101,6 @@
} else {
mShowing = show;
setVisibility(show ? View.VISIBLE : View.GONE);
- mChoreo.jumpTo(show);
}
}
@@ -118,60 +117,82 @@
super.onVisibilityChanged(v, vis);
// when we hide, put back the notifications
if (!isShown()) {
- switchToNotificationMode();
+ if (mSettingsView != null) removeSettingsView();
+ mNotificationScroller.setVisibility(View.VISIBLE);
+ mNotificationScroller.setAlpha(1f);
mNotificationScroller.scrollTo(0, 0);
+ updatePanelModeButtons();
}
}
- /**
- * We need to be aligned at the bottom. LinearLayout can't do this, so instead,
- * let LinearLayout do all the hard work, and then shift everything down to the bottom.
- */
+ /*
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout(changed, l, t, r, b);
- mChoreo.setPanelHeight(mContentParent.getHeight());
+
+ if (DEBUG) Slog.d(TAG, String.format("PANEL: onLayout: (%d, %d, %d, %d)", l, t, r, b));
}
@Override
public void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- mContentArea = null;
+
+ if (DEBUG) {
+ Slog.d(TAG, String.format("PANEL: onSizeChanged: (%d -> %d, %d -> %d)",
+ oldw, w, oldh, h));
+ }
}
+ */
public void onClick(View v) {
- if (v == mTitleArea) {
- if (mSettingsView == null) {
- switchToSettingsMode();
- } else {
- switchToNotificationMode();
- }
+ if (v == mModeToggle) {
+ swapPanels();
}
}
- public void switchToSettingsMode() {
- removeSettingsView();
- addSettingsView();
- mSettingsButton.setVisibility(View.INVISIBLE);
- mNotificationScroller.setVisibility(View.GONE);
- mNotificationButton.setVisibility(View.VISIBLE);
- }
+ final static int PANEL_FADE_DURATION = 150;
- public void switchToNotificationMode() {
- removeSettingsView();
- mSettingsButton.setVisibility(View.VISIBLE);
- mNotificationScroller.setVisibility(View.VISIBLE);
- mNotificationButton.setVisibility(View.INVISIBLE);
+ public void swapPanels() {
+ final View toShow, toHide;
+ if (mSettingsView == null) {
+ addSettingsView();
+ toShow = mSettingsView;
+ toHide = mNotificationScroller;
+ } else {
+ toShow = mNotificationScroller;
+ toHide = mSettingsView;
+ }
+ Animator a = ObjectAnimator.ofFloat(toHide, "alpha", 1f, 0f)
+ .setDuration(PANEL_FADE_DURATION);
+ a.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator _a) {
+ toHide.setVisibility(View.GONE);
+ toShow.setVisibility(View.VISIBLE);
+ ObjectAnimator.ofFloat(toShow, "alpha", 0f, 1f)
+ .setDuration(PANEL_FADE_DURATION)
+ .start();
+ if (toHide == mSettingsView) {
+ removeSettingsView();
+ }
+ updatePanelModeButtons();
+ }
+ });
+ a.start();
+ }
+
+ public void updatePanelModeButtons() {
+ final boolean settingsVisible = (mSettingsView != null);
+ mSettingsButton.setVisibility(!settingsVisible ? View.VISIBLE : View.INVISIBLE);
+ mNotificationButton.setVisibility(settingsVisible ? View.VISIBLE : View.INVISIBLE);
}
public boolean isInContentArea(int x, int y) {
- if (mContentArea == null) {
- mContentArea = new Rect(mContentFrame.getLeft(),
- mTitleArea.getTop(),
- mContentFrame.getRight(),
- mContentFrame.getBottom());
- offsetDescendantRectToMyCoords(mContentParent, mContentArea);
- }
+ mContentArea.left = mContentFrame.getLeft() + mContentFrame.getPaddingLeft();
+ mContentArea.top = mTitleArea.getTop() + mTitleArea.getPaddingTop();
+ mContentArea.right = mContentFrame.getRight() - mContentFrame.getPaddingRight();
+ mContentArea.bottom = mContentFrame.getBottom() - mContentFrame.getPaddingBottom();
+ offsetDescendantRectToMyCoords(mContentParent, mContentArea);
return mContentArea.contains(x, y);
}
@@ -182,10 +203,12 @@
}
}
+ // NB: it will be invisible until you show it
void addSettingsView() {
LayoutInflater infl = LayoutInflater.from(getContext());
mSettingsView = infl.inflate(R.layout.status_bar_settings_view, mContentFrame, false);
- mContentFrame.addView(mSettingsView, mContentFrame.indexOfChild(mNotificationGlow));
+ mSettingsView.setVisibility(View.GONE);
+ mContentFrame.addView(mSettingsView);
}
private class Choreographer implements Animator.AnimatorListener {
@@ -194,18 +217,21 @@
AnimatorSet mContentAnim;
// should group this into a multi-property animation
- final int OPEN_DURATION = 136;
- final int CLOSE_DURATION = 250;
+ final static int OPEN_DURATION = 136;
+ final static int CLOSE_DURATION = 250;
// the panel will start to appear this many px from the end
- final int HYPERSPACE_OFFRAMP = 30;
+ final int HYPERSPACE_OFFRAMP = 100;
Choreographer() {
}
void createAnimation(boolean appearing) {
- Animator bgAnim = ObjectAnimator.ofFloat(mScrim,
- "alpha", mScrim.getAlpha(), appearing ? 1 : 0);
+ // mVisible: previous state; appearing: new state
+
+ View root = findViewById(R.id.panel_root);
+ Animator bgAnim = ObjectAnimator.ofInt(root.getBackground(), "alpha",
+ mVisible ? 255 : 0, appearing ? 255 : 0);
float start, end;
@@ -215,34 +241,33 @@
if (appearing) {
// we want to go from near-the-top to the top, unless we're half-open in the right
// general vicinity
- start = (y < HYPERSPACE_OFFRAMP)
- ? y
- : HYPERSPACE_OFFRAMP;
+ start = (y < HYPERSPACE_OFFRAMP) ? y : HYPERSPACE_OFFRAMP;
end = 0;
} else {
start = y;
end = y + HYPERSPACE_OFFRAMP;
}
- Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY", start, end);
+ Animator posAnim = ObjectAnimator.ofFloat(mContentParent, "translationY",
+ start, end);
posAnim.setInterpolator(appearing
- ? new android.view.animation.DecelerateInterpolator(2.0f)
- : new android.view.animation.AccelerateInterpolator(2.0f));
+ ? new android.view.animation.DecelerateInterpolator(1.0f)
+ : new android.view.animation.AccelerateInterpolator(1.0f));
- Animator glowAnim = ObjectAnimator.ofFloat(mGlow, "alpha",
- mGlow.getAlpha(), appearing ? 1.0f : 0.0f);
+ Animator glowAnim = ObjectAnimator.ofInt(mGlow.getBackground(), "alpha",
+ mVisible ? 255 : 0, appearing ? 255 : 0);
glowAnim.setInterpolator(appearing
? new android.view.animation.AccelerateInterpolator(1.0f)
: new android.view.animation.DecelerateInterpolator(1.0f));
mContentAnim = new AnimatorSet();
mContentAnim
- .play(ObjectAnimator.ofFloat(mContentParent, "alpha", mContentParent.getAlpha(),
- appearing ? 1.0f : 0.0f))
- .with(glowAnim)
+ .play(ObjectAnimator.ofFloat(mContentParent, "alpha",
+ mContentParent.getAlpha(), appearing ? 1.0f : 0.0f))
.with(bgAnim)
+ .with(glowAnim)
.with(posAnim)
;
- mContentAnim.setDuration(appearing ? OPEN_DURATION : CLOSE_DURATION);
+ mContentAnim.setDuration((DEBUG?10:1)*(appearing ? OPEN_DURATION : CLOSE_DURATION));
mContentAnim.addListener(this);
}
@@ -252,30 +277,12 @@
createAnimation(appearing);
mContentParent.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ mGlow.setLayerType(View.LAYER_TYPE_HARDWARE, null);
mContentAnim.start();
mVisible = appearing;
}
- void jumpTo(boolean appearing) {
-// setBgAlpha(appearing ? 255 : 0);
- mContentParent.setTranslationY(appearing ? 0 : mPanelHeight);
- }
-
- public void setPanelHeight(int h) {
- if (DEBUG) Slog.d(TAG, "panelHeight=" + h);
- mPanelHeight = h;
- if (mPanelHeight == 0) {
- // fully closed, no animation necessary
- } else if (mVisible) {
- if (DEBUG) {
- Slog.d(TAG, "panelHeight not zero but trying to open; scheduling an anim"
- + " to open fully");
- }
- startAnimation(true);
- }
- }
-
public void onAnimationCancel(Animator animation) {
if (DEBUG) Slog.d(TAG, "onAnimationCancel");
// force this to zero so we close the window
@@ -288,6 +295,7 @@
setVisibility(View.GONE);
}
mContentParent.setLayerType(View.LAYER_TYPE_NONE, null);
+ mGlow.setLayerType(View.LAYER_TYPE_NONE, null);
mContentAnim = null;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 6db74d1..a3a58ed 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -189,7 +189,7 @@
mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- 720, // ViewGroup.LayoutParams.MATCH_PARENT,
+ 512, // ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL,
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
diff --git a/packages/VpnServices/Android.mk b/packages/VpnServices/Android.mk
deleted file mode 100644
index 6cdf674..0000000
--- a/packages/VpnServices/Android.mk
+++ /dev/null
@@ -1,16 +0,0 @@
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE_TAGS := optional
-
-LOCAL_SRC_FILES := $(call all-subdir-java-files)
-
-LOCAL_JAVA_LIBRARIES :=
-
-LOCAL_PACKAGE_NAME := VpnServices
-LOCAL_CERTIFICATE := platform
-
-include $(BUILD_PACKAGE)
-
-########################
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/packages/VpnServices/AndroidManifest.xml b/packages/VpnServices/AndroidManifest.xml
deleted file mode 100644
index 6092e30..0000000
--- a/packages/VpnServices/AndroidManifest.xml
+++ /dev/null
@@ -1,22 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.server.vpn"
- android:sharedUserId="android.uid.system"
- >
- <application android:label="@string/app_label">
-
- <service android:name=".VpnServiceBinder" android:process=":remote">
- <intent-filter>
- <!-- These are the interfaces supported by the service, which
- you can bind to. -->
- <action android:name="android.net.vpn.IVpnService" />
- <!-- This is an action code you can use to select the service
- without explicitly supplying the implementation class. -->
- <action android:name="android.net.vpn.SERVICE" />
- </intent-filter>
- </service>
-
- </application>
-
- <uses-permission android:name="android.permission.INTERNET"></uses-permission>
-</manifest>
diff --git a/packages/VpnServices/MODULE_LICENSE_APACHE2 b/packages/VpnServices/MODULE_LICENSE_APACHE2
deleted file mode 100644
index e69de29..0000000
--- a/packages/VpnServices/MODULE_LICENSE_APACHE2
+++ /dev/null
diff --git a/packages/VpnServices/NOTICE b/packages/VpnServices/NOTICE
deleted file mode 100644
index c5b1efa..0000000
--- a/packages/VpnServices/NOTICE
+++ /dev/null
@@ -1,190 +0,0 @@
-
- Copyright (c) 2005-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.
-
- 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.
-
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
diff --git a/packages/VpnServices/res/values-ar/strings.xml b/packages/VpnServices/res/values-ar/strings.xml
deleted file mode 100644
index 6bac120..0000000
--- a/packages/VpnServices/res/values-ar/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"خدمات الشبكة الظاهرية الخاصة (VPN)"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"تم توصيل الشبكة الظاهرية الخاصة (VPN) لـ <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"تم فصل الشبكة الظاهرية الخاصة (VPN) لـ <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"يمكنك اللمس لإعادة الاتصال بالشبكة الظاهرية الخاصة (VPN)."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-bg/strings.xml b/packages/VpnServices/res/values-bg/strings.xml
deleted file mode 100644
index fdcbf64..0000000
--- a/packages/VpnServices/res/values-bg/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN услуги"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Връзката с VPN <xliff:g id="PROFILENAME">%s</xliff:g> бе установена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Връзката с VPN <xliff:g id="PROFILENAME">%s</xliff:g> бе прекъсната"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Докоснете за повторно свързване с VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ca/strings.xml b/packages/VpnServices/res/values-ca/strings.xml
deleted file mode 100644
index b37790a..0000000
--- a/packages/VpnServices/res/values-ca/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Serveis VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconnectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toqueu-ho per tornar-vos a connectar a una VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-cs/strings.xml b/packages/VpnServices/res/values-cs/strings.xml
deleted file mode 100644
index 96d4cc5..0000000
--- a/packages/VpnServices/res/values-cs/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Služby VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je připojena"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Síť VPN <xliff:g id="PROFILENAME">%s</xliff:g> odpojena"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotykem se znovu připojíte k síti VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-da/strings.xml b/packages/VpnServices/res/values-da/strings.xml
deleted file mode 100644
index 0f05bbc..0000000
--- a/packages/VpnServices/res/values-da/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN forbundet"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN afbrudt"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tryk for at oprette forbindelse til et VPN igen."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-de/strings.xml b/packages/VpnServices/res/values-de/strings.xml
deleted file mode 100644
index b907be8b..0000000
--- a/packages/VpnServices/res/values-de/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-Dienste"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> mit VPN verbunden"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> von VPN getrennt"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Zur Wiederherstellung der Verbindung mit einem VPN berühren"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-el/strings.xml b/packages/VpnServices/res/values-el/strings.xml
deleted file mode 100644
index d96f3e0..0000000
--- a/packages/VpnServices/res/values-el/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Υπηρεσίες VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> συνδέθηκε"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Το VPN <xliff:g id="PROFILENAME">%s</xliff:g> αποσυνδέθηκε"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Πατήστε για να επανασυνδεθείτε σε ένα VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-en-rGB/strings.xml b/packages/VpnServices/res/values-en-rGB/strings.xml
deleted file mode 100644
index 905c265..0000000
--- a/packages/VpnServices/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN Services"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN connected"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN disconnected"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Touch to reconnect to a VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-es-rUS/strings.xml b/packages/VpnServices/res/values-es-rUS/strings.xml
deleted file mode 100644
index 8f5053c..0000000
--- a/packages/VpnServices/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servicios VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN conectados"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tocar para volver a conectarse a una VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-es/strings.xml b/packages/VpnServices/res/values-es/strings.xml
deleted file mode 100644
index 9182459..0000000
--- a/packages/VpnServices/res/values-es/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servicios VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toca para volver a conectarte a una red VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fa/strings.xml b/packages/VpnServices/res/values-fa/strings.xml
deleted file mode 100644
index 7cee16d..0000000
--- a/packages/VpnServices/res/values-fa/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"سرویس های VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN وصل شد"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN قطع شد"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"برای اتصال مجدد به VPN لمس کنید."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fi/strings.xml b/packages/VpnServices/res/values-fi/strings.xml
deleted file mode 100644
index b15202a..0000000
--- a/packages/VpnServices/res/values-fi/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-palvelut"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g>: VPN-yhteys muodostettu"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g>: VPN-yhteys katkaistu"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Yhdistä VPN-verkkoon uudelleen koskettamalla."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-fr/strings.xml b/packages/VpnServices/res/values-fr/strings.xml
deleted file mode 100644
index 4a93e0a..0000000
--- a/packages/VpnServices/res/values-fr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Services VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connecté"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> déconnecté"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Touchez l\'écran pour vous reconnecter à un VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-hr/strings.xml b/packages/VpnServices/res/values-hr/strings.xml
deleted file mode 100644
index aedb536..0000000
--- a/packages/VpnServices/res/values-hr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN usluge"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN priključen"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN je isključen"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotaknite za ponovno povezivanje s VPN-om."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-hu/strings.xml b/packages/VpnServices/res/values-hu/strings.xml
deleted file mode 100644
index 44f5427..0000000
--- a/packages/VpnServices/res/values-hu/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-szolgáltatások"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Kapcsolódva a(z) <xliff:g id="PROFILENAME">%s</xliff:g> virtuális magánhálózathoz"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Kapcsolat bontva a(z) <xliff:g id="PROFILENAME">%s</xliff:g> virtuális magánhálózattal"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Érintse meg az újracsatlakozáshoz."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-in/strings.xml b/packages/VpnServices/res/values-in/strings.xml
deleted file mode 100644
index 8b6b4c2..0000000
--- a/packages/VpnServices/res/values-in/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Layanan VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> terhubung"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> terputus"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Sentuh untuk terhubung kembali ke suatu VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-it/strings.xml b/packages/VpnServices/res/values-it/strings.xml
deleted file mode 100644
index 1c7a588..0000000
--- a/packages/VpnServices/res/values-it/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servizi VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> collegata"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> scollegata"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tocca per riconnetterti a una rete VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-iw/strings.xml b/packages/VpnServices/res/values-iw/strings.xml
deleted file mode 100644
index 74971d6..0000000
--- a/packages/VpnServices/res/values-iw/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"שירותי VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN של <xliff:g id="PROFILENAME">%s</xliff:g> מחובר"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN של <xliff:g id="PROFILENAME">%s</xliff:g> נותק"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"גע כדי להתחבר שוב ל-VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ja/strings.xml b/packages/VpnServices/res/values-ja/strings.xml
deleted file mode 100644
index 548d8a9..0000000
--- a/packages/VpnServices/res/values-ja/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPNサービス"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが接続されました"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPNが切断されました"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"タップしてVPNに再接続してください。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ko/strings.xml b/packages/VpnServices/res/values-ko/strings.xml
deleted file mode 100644
index 4185291..0000000
--- a/packages/VpnServices/res/values-ko/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN 서비스"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결됨"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 연결 끊김"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"VPN에 다시 연결하려면 터치하세요."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-lt/strings.xml b/packages/VpnServices/res/values-lt/strings.xml
deleted file mode 100644
index 58f1f58..0000000
--- a/packages/VpnServices/res/values-lt/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPT paslaugos"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPT prijungtas"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPT atjungtas"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Palieskite, kad būtų iš naujo sujungta su VPT."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-lv/strings.xml b/packages/VpnServices/res/values-lv/strings.xml
deleted file mode 100644
index cb80908..0000000
--- a/packages/VpnServices/res/values-lv/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN pakalpojumi"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN ir savienots"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN ir atvienots"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Pieskarieties, lai atkārtoti izveidotu savienojumu ar VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-nb/strings.xml b/packages/VpnServices/res/values-nb/strings.xml
deleted file mode 100644
index 4790600..0000000
--- a/packages/VpnServices/res/values-nb/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-tjenester"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Koblet til VPNet <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Koblet fra VPNet <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Trykk for å koble til et VPN på nytt"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-nl/strings.xml b/packages/VpnServices/res/values-nl/strings.xml
deleted file mode 100644
index 175c7dd..0000000
--- a/packages/VpnServices/res/values-nl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-services"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> verbonden via VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN-verbinding met <xliff:g id="PROFILENAME">%s</xliff:g> verbroken"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Raak aan om opnieuw verbinding te maken met een VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pl/strings.xml b/packages/VpnServices/res/values-pl/strings.xml
deleted file mode 100644
index 565d249..0000000
--- a/packages/VpnServices/res/values-pl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Usługi VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Połączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Rozłączono z siecią VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotknij, aby ponownie połączyć się z siecią VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pt-rPT/strings.xml b/packages/VpnServices/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 020188f..0000000
--- a/packages/VpnServices/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Serviços VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> ligado"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> desligado"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toque para voltar a ligar a uma VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-pt/strings.xml b/packages/VpnServices/res/values-pt/strings.xml
deleted file mode 100644
index f47652a..0000000
--- a/packages/VpnServices/res/values-pt/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Serviços de VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> conectada"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN de <xliff:g id="PROFILENAME">%s</xliff:g> desconectada"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Toque para reconectar-se a uma VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-rm/strings.xml b/packages/VpnServices/res/values-rm/strings.xml
deleted file mode 100644
index 80f2817..0000000
--- a/packages/VpnServices/res/values-rm/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servetschs VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> connectà"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> deconnectà"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tutgar per reconnectar ad in VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ro/strings.xml b/packages/VpnServices/res/values-ro/strings.xml
deleted file mode 100644
index a22792c..0000000
--- a/packages/VpnServices/res/values-ro/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Servicii VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> conectat"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> deconectat"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Atingeţi pentru a vă reconecta la o reţea VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-ru/strings.xml b/packages/VpnServices/res/values-ru/strings.xml
deleted file mode 100644
index 8a839c3..0000000
--- a/packages/VpnServices/res/values-ru/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Службы VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) подключена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Сеть VPN (<xliff:g id="PROFILENAME">%s</xliff:g>) отключена"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Нажмите, чтобы повторно подключиться к VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sk/strings.xml b/packages/VpnServices/res/values-sk/strings.xml
deleted file mode 100644
index 167b6f3..0000000
--- a/packages/VpnServices/res/values-sk/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Služby VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Sieť VPN <xliff:g id="PROFILENAME">%s</xliff:g> je pripojená"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Sieť VPN <xliff:g id="PROFILENAME">%s</xliff:g> odpojená"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotykom sa znova pripojíte k sieti VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sl/strings.xml b/packages/VpnServices/res/values-sl/strings.xml
deleted file mode 100644
index c5b72c4..0000000
--- a/packages/VpnServices/res/values-sl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Storitve VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN profila <xliff:g id="PROFILENAME">%s</xliff:g> je povezan"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN profila <xliff:g id="PROFILENAME">%s</xliff:g> je izklopljen"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Dotaknite se, če želite preklopiti v navidezno zasebno omrežje."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sr/strings.xml b/packages/VpnServices/res/values-sr/strings.xml
deleted file mode 100644
index bfe6cc8..0000000
--- a/packages/VpnServices/res/values-sr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN услуге"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN веза је успостављена"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN веза је прекинута"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Додирните да бисте се поново повезали са VPN-ом."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-sv/strings.xml b/packages/VpnServices/res/values-sv/strings.xml
deleted file mode 100644
index 24f9f58..0000000
--- a/packages/VpnServices/res/values-sv/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN-tjänster"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN anslutet"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN frånkopplat"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Tryck här om du vill återansluta till ett VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-th/strings.xml b/packages/VpnServices/res/values-th/strings.xml
deleted file mode 100644
index 3aa9c6e..0000000
--- a/packages/VpnServices/res/values-th/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"บริการ VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> เชื่อมต่อ VPN แล้ว"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> ตัดการเชื่อมต่อ VPN แล้ว"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"แตะเพื่อเชื่อมต่อกับ VPN อีกครั้ง"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-tl/strings.xml b/packages/VpnServices/res/values-tl/strings.xml
deleted file mode 100644
index bd988a1..0000000
--- a/packages/VpnServices/res/values-tl/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Mga serbisyo ng VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Hindi konektado ang <xliff:g id="PROFILENAME">%s</xliff:g> VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Hindi konektado ang <xliff:g id="PROFILENAME">%s</xliff:g> VPN"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Galawin upang muling kumonekta sa VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-tr/strings.xml b/packages/VpnServices/res/values-tr/strings.xml
deleted file mode 100644
index 8666b35..0000000
--- a/packages/VpnServices/res/values-tr/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN Hizmetleri"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlandı"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN bağlantısı kesildi"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Bir VPN\'ye tekrar bağlanmak için dokunun."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-uk/strings.xml b/packages/VpnServices/res/values-uk/strings.xml
deleted file mode 100644
index 208659a..0000000
--- a/packages/VpnServices/res/values-uk/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Служби VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> підключ. ч-з VPN"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN <xliff:g id="PROFILENAME">%s</xliff:g> роз\'єднано"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Натисн. для повт. з\'єдн. з VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-vi/strings.xml b/packages/VpnServices/res/values-vi/strings.xml
deleted file mode 100644
index 3022c9c..0000000
--- a/packages/VpnServices/res/values-vi/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"Dịch vụ VPN"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"Đã kết nối VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"Đã ngắt kết nối VPN <xliff:g id="PROFILENAME">%s</xliff:g>"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"Chạm để kết nối lại với VPN."</string>
-</resources>
diff --git a/packages/VpnServices/res/values-zh-rCN/strings.xml b/packages/VpnServices/res/values-zh-rCN/strings.xml
deleted file mode 100644
index cad08e1..0000000
--- a/packages/VpnServices/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"虚拟专用网服务"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"VPN“<xliff:g id="PROFILENAME">%s</xliff:g>”已连接"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"VPN“<xliff:g id="PROFILENAME">%s</xliff:g>”连接已断开"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"轻触可重新连接到虚拟专用网。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values-zh-rTW/strings.xml b/packages/VpnServices/res/values-zh-rTW/strings.xml
deleted file mode 100644
index ee5a42b..0000000
--- a/packages/VpnServices/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4589592829302498102">"VPN 服務"</string>
- <string name="vpn_notification_title_connected" msgid="8598654486956133580">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已連線"</string>
- <string name="vpn_notification_title_disconnected" msgid="6216572264382192027">"<xliff:g id="PROFILENAME">%s</xliff:g> VPN 已中斷連線"</string>
- <string name="vpn_notification_hint_disconnected" msgid="1952209867082269429">"輕觸即可重新連線至 VPN。"</string>
-</resources>
diff --git a/packages/VpnServices/res/values/strings.xml b/packages/VpnServices/res/values/strings.xml
deleted file mode 100755
index d82f52a..0000000
--- a/packages/VpnServices/res/values/strings.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <!-- Title for the VPN Services activity. -->
- <string name="app_label">VPN Services</string>
-
- <string name="vpn_notification_title_connected"><xliff:g id="profilename">%s</xliff:g> VPN connected</string>
- <string name="vpn_notification_title_disconnected"><xliff:g id="profilename">%s</xliff:g> VPN disconnected</string>
- <string name="vpn_notification_hint_disconnected">Touch to reconnect to a VPN.</string>
-</resources>
-
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java b/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
deleted file mode 100644
index eeafd5a..0000000
--- a/packages/VpnServices/src/com/android/server/vpn/VpnServiceBinder.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * Copyright (C) 2009, The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.server.vpn;
-
-import android.app.Service;
-import android.content.Intent;
-import android.net.vpn.IVpnService;
-import android.net.vpn.L2tpIpsecProfile;
-import android.net.vpn.L2tpIpsecPskProfile;
-import android.net.vpn.L2tpProfile;
-import android.net.vpn.PptpProfile;
-import android.net.vpn.VpnManager;
-import android.net.vpn.VpnProfile;
-import android.net.vpn.VpnState;
-import android.os.Environment;
-import android.os.IBinder;
-import android.os.SystemProperties;
-import android.util.Log;
-
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.ObjectInputStream;
-import java.io.ObjectOutputStream;
-
-/**
- * The service class for managing a VPN connection. It implements the
- * {@link IVpnService} binder interface.
- */
-public class VpnServiceBinder extends Service {
- private static final String TAG = VpnServiceBinder.class.getSimpleName();
- private static final boolean DBG = true;
-
- private static final String STATES_FILE_RELATIVE_PATH = "/misc/vpn/.states";
-
- // The actual implementation is delegated to the VpnService class.
- private VpnService<? extends VpnProfile> mService;
-
- // TODO(oam): Test VPN when EFS is enabled (will do later)...
- private static String getStateFilePath() {
- // This call will return the correcu directory whether Encrypted FS is enabled or not
- // Disabled: /data/misc/vpn/.states Enabled: /data/secure/misc/vpn/.states
- return Environment.getSecureDataDirectory().getPath() + STATES_FILE_RELATIVE_PATH;
- }
-
- private final IBinder mBinder = new IVpnService.Stub() {
- public boolean connect(VpnProfile p, String username, String password) {
- return VpnServiceBinder.this.connect(p, username, password);
- }
-
- public void disconnect() {
- VpnServiceBinder.this.disconnect();
- }
-
- public void checkStatus(VpnProfile p) {
- VpnServiceBinder.this.checkStatus(p);
- }
- };
-
- @Override
- public void onCreate() {
- super.onCreate();
- checkSavedStates();
- }
-
-
- @Override
- public void onStart(Intent intent, int startId) {
- super.onStart(intent, startId);
- }
-
- @Override
- public IBinder onBind(Intent intent) {
- return mBinder;
- }
-
- void saveStates() throws IOException {
- if (DBG) Log.d("VpnServiceBinder", " saving states");
- ObjectOutputStream oos =
- new ObjectOutputStream(new FileOutputStream(getStateFilePath()));
- oos.writeObject(mService);
- oos.close();
- }
-
- void removeStates() {
- try {
- File f = new File(getStateFilePath());
- if (f.exists()) f.delete();
- } catch (Throwable e) {
- if (DBG) Log.d("VpnServiceBinder", " remove states: " + e);
- }
- }
-
- private synchronized boolean connect(final VpnProfile p,
- final String username, final String password) {
- if (mService != null) return false;
- final VpnService s = mService = createService(p);
-
- new Thread(new Runnable() {
- public void run() {
- s.onConnect(username, password);
- }
- }).start();
- return true;
- }
-
- private synchronized void disconnect() {
- if (mService == null) return;
- final VpnService s = mService;
-
- new Thread(new Runnable() {
- public void run() {
- s.onDisconnect();
- }
- }).start();
- }
-
- private synchronized void checkStatus(VpnProfile p) {
- if ((mService == null)
- || (!p.getName().equals(mService.mProfile.getName()))) {
- broadcastConnectivity(p.getName(), VpnState.IDLE);
- } else {
- broadcastConnectivity(p.getName(), mService.getState());
- }
- }
-
- private void checkSavedStates() {
- try {
- ObjectInputStream ois = new ObjectInputStream(new FileInputStream(
- getStateFilePath()));
- mService = (VpnService<? extends VpnProfile>) ois.readObject();
- mService.recover(this);
- ois.close();
- } catch (FileNotFoundException e) {
- // do nothing
- } catch (Throwable e) {
- Log.i("VpnServiceBinder", "recovery error, remove states: " + e);
- removeStates();
- }
- }
-
- private VpnService<? extends VpnProfile> createService(VpnProfile p) {
- switch (p.getType()) {
- case L2TP:
- L2tpService l2tp = new L2tpService();
- l2tp.setContext(this, (L2tpProfile) p);
- return l2tp;
-
- case PPTP:
- PptpService pptp = new PptpService();
- pptp.setContext(this, (PptpProfile) p);
- return pptp;
-
- case L2TP_IPSEC_PSK:
- L2tpIpsecPskService psk = new L2tpIpsecPskService();
- psk.setContext(this, (L2tpIpsecPskProfile) p);
- return psk;
-
- case L2TP_IPSEC:
- L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
- l2tpIpsec.setContext(this, (L2tpIpsecProfile) p);
- return l2tpIpsec;
-
- default:
- return null;
- }
- }
-
- private void broadcastConnectivity(String name, VpnState s) {
- new VpnManager(this).broadcastConnectivity(name, s);
- }
-}
diff --git a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
index eb4d930..5b80a93 100644
--- a/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
+++ b/policy/src/com/android/internal/policy/impl/PasswordUnlockScreen.java
@@ -100,17 +100,27 @@
|| DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC == quality
|| DevicePolicyManager.PASSWORD_QUALITY_COMPLEX == quality;
+ // TODO: re-enable on phones with keyboards
+ final boolean isPhysicalKbShowing = false;
mKeyboardView = (PasswordEntryKeyboardView) findViewById(R.id.keyboard);
mKeyboardViewAlpha = (PasswordEntryKeyboardView) findViewById(R.id.keyboardAlpha);
mPasswordEntry = (EditText) findViewById(R.id.passwordEntry);
mPasswordEntry.setOnEditorActionListener(this);
+ mPasswordEntry.setOnClickListener(new OnClickListener() {
+ public void onClick(View v) {
+ if (mIsAlpha && !isPhysicalKbShowing) {
+ mKeyboardViewAlpha.setVisibility(
+ mKeyboardViewAlpha.getVisibility() == View.VISIBLE
+ ? View.GONE : View.VISIBLE);
+ mCallback.pokeWakelock();
+ }
+ }
+ });
mEmergencyCallButton = (Button) findViewById(R.id.emergencyCall);
mEmergencyCallButton.setOnClickListener(this);
mLockPatternUtils.updateEmergencyCallButtonState(mEmergencyCallButton);
mKeyboardHelper = new PasswordEntryKeyboardHelper(context, mKeyboardView, this, false);
- // TODO: re-enable on phones with keyboards
- boolean isPhysicalKbShowing = false;
//mCreationHardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO;
if (mKeyboardViewAlpha == null || !mIsAlpha) {
mKeyboardHelper.setKeyboardMode(mIsAlpha ?
@@ -123,24 +133,21 @@
mKeyboardHelper.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_NUMERIC);
mKeyboardHelperAlpha.setKeyboardMode(PasswordEntryKeyboardHelper.KEYBOARD_MODE_ALPHA);
mKeyboardView.setVisibility(View.GONE);
- mKeyboardViewAlpha.setVisibility(isPhysicalKbShowing ? View.INVISIBLE : View.VISIBLE);
mPasswordEntry.setWidth(mKeyboardViewAlpha.getLayoutParams().width);
}
- mPasswordEntry.setCompoundDrawablesWithIntrinsicBounds(R.drawable.ic_lock_idle_lock, 0,
- 0, 0);
mPasswordEntry.requestFocus();
// This allows keyboards with overlapping qwerty/numeric keys to choose just the
// numeric keys.
if (mIsAlpha) {
mPasswordEntry.setKeyListener(TextKeyListener.getInstance());
- mStatusView.setHelpMessage(R.string.keyguard_password_enter_password_code,
- StatusView.LOCK_ICON);
+ // mStatusView.setHelpMessage(R.string.keyguard_password_enter_password_code,
+ // StatusView.LOCK_ICON);
} else {
mPasswordEntry.setKeyListener(DigitsKeyListener.getInstance());
- mStatusView.setHelpMessage(R.string.keyguard_password_enter_pin_code,
- StatusView.LOCK_ICON);
+ //mStatusView.setHelpMessage(R.string.keyguard_password_enter_pin_code,
+ // StatusView.LOCK_ICON);
}
mKeyboardHelper.setVibratePattern(mLockPatternUtils.isTactileFeedbackEnabled() ?
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 16c042d..11ad4e4 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -5443,19 +5443,21 @@
// clear auxiliary effect input buffer for next accumulation
if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_AUXILIARY) {
- memset(mConfig.inputCfg.buffer.raw, 0, mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
+ memset(mConfig.inputCfg.buffer.raw, 0,
+ mConfig.inputCfg.buffer.frameCount*sizeof(int32_t));
}
} else if ((mDescriptor.flags & EFFECT_FLAG_TYPE_MASK) == EFFECT_FLAG_TYPE_INSERT &&
- mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw){
- // If an insert effect is idle and input buffer is different from output buffer, copy input to
- // output
+ mConfig.inputCfg.buffer.raw != mConfig.outputCfg.buffer.raw) {
+ // If an insert effect is idle and input buffer is different from output buffer,
+ // accumulate input onto output
sp<EffectChain> chain = mChain.promote();
if (chain != 0 && chain->activeTracks() != 0) {
- size_t size = mConfig.inputCfg.buffer.frameCount * sizeof(int16_t);
- if (mConfig.inputCfg.channels == CHANNEL_STEREO) {
- size *= 2;
+ size_t frameCnt = mConfig.inputCfg.buffer.frameCount * 2; //always stereo here
+ int16_t *in = mConfig.inputCfg.buffer.s16;
+ int16_t *out = mConfig.outputCfg.buffer.s16;
+ for (size_t i = 0; i < frameCnt; i++) {
+ out[i] = clamp16((int32_t)out[i] + (int32_t)in[i]);
}
- memcpy(mConfig.outputCfg.buffer.raw, mConfig.inputCfg.buffer.raw, size);
}
}
}
diff --git a/services/input/InputReader.cpp b/services/input/InputReader.cpp
index 8e9a5a4..2e83256 100644
--- a/services/input/InputReader.cpp
+++ b/services/input/InputReader.cpp
@@ -744,7 +744,7 @@
}
uint32_t SwitchInputMapper::getSources() {
- return 0;
+ return AINPUT_SOURCE_SWITCH;
}
void SwitchInputMapper::process(const RawEvent* rawEvent) {
diff --git a/services/input/tests/InputReader_test.cpp b/services/input/tests/InputReader_test.cpp
index 775747c..98d627d 100644
--- a/services/input/tests/InputReader_test.cpp
+++ b/services/input/tests/InputReader_test.cpp
@@ -1484,7 +1484,7 @@
SwitchInputMapper* mapper = new SwitchInputMapper(mDevice);
addMapperAndConfigure(mapper);
- ASSERT_EQ(uint32_t(0), mapper->getSources());
+ ASSERT_EQ(uint32_t(AINPUT_SOURCE_SWITCH), mapper->getSources());
}
TEST_F(SwitchInputMapperTest, GetSwitchState) {
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 2321e30..bd3c554 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -32,6 +32,7 @@
import android.net.NetworkUtils;
import android.net.Proxy;
import android.net.ProxyProperties;
+import android.net.vpn.VpnManager;
import android.net.wifi.WifiStateTracker;
import android.os.Binder;
import android.os.Handler;
@@ -442,6 +443,8 @@
mSettingsObserver.observe(mContext);
loadGlobalProxy();
+
+ VpnManager.startVpnService(context);
}
diff --git a/services/java/com/android/server/DevicePolicyManagerService.java b/services/java/com/android/server/DevicePolicyManagerService.java
index 8a9e351..b2d534b 100644
--- a/services/java/com/android/server/DevicePolicyManagerService.java
+++ b/services/java/com/android/server/DevicePolicyManagerService.java
@@ -53,6 +53,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
+import android.os.SystemProperties;
import android.provider.Settings;
import android.util.PrintWriterPrinter;
import android.util.Printer;
@@ -1925,7 +1926,14 @@
* {@link DevicePolicyManager#ENCRYPTION_STATUS_ACTIVE}.
*/
private int getEncryptionStatus() {
- return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
+ String status = SystemProperties.get("ro.crypto.state", "unsupported");
+ if ("encrypted".equalsIgnoreCase(status)) {
+ return DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE;
+ } else if ("unencrypted".equalsIgnoreCase(status)) {
+ return DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE;
+ } else {
+ return DevicePolicyManager.ENCRYPTION_STATUS_UNSUPPORTED;
+ }
}
/**
diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java
index 4d40620..b5cc5aa 100644
--- a/services/java/com/android/server/InputMethodManagerService.java
+++ b/services/java/com/android/server/InputMethodManagerService.java
@@ -118,7 +118,6 @@
private static final int NOT_A_SUBTYPE_ID = -1;
private static final String NOT_A_SUBTYPE_ID_STR = String.valueOf(NOT_A_SUBTYPE_ID);
- private static final String EXTRA_INPUT_METHOD_ID = "input_method_id";
private static final String SUBTYPE_MODE_KEYBOARD = "keyboard";
private static final String SUBTYPE_MODE_VOICE = "voice";
@@ -565,19 +564,35 @@
}
}
+ private HashMap<InputMethodInfo, List<InputMethodSubtype>>
+ getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked() {
+ HashMap<InputMethodInfo, List<InputMethodSubtype>> enabledInputMethodAndSubtypes =
+ new HashMap<InputMethodInfo, List<InputMethodSubtype>>();
+ for (InputMethodInfo imi: getEnabledInputMethodList()) {
+ enabledInputMethodAndSubtypes.put(
+ imi, getEnabledInputMethodSubtypeListLocked(imi, true));
+ }
+ return enabledInputMethodAndSubtypes;
+ }
+
+ public List<InputMethodSubtype> getEnabledInputMethodSubtypeListLocked(InputMethodInfo imi,
+ boolean allowsImplicitlySelectedSubtypes) {
+ if (imi == null && mCurMethodId != null) {
+ imi = mMethodMap.get(mCurMethodId);
+ }
+ final List<InputMethodSubtype> enabledSubtypes =
+ mSettings.getEnabledInputMethodSubtypeListLocked(imi);
+ if (!allowsImplicitlySelectedSubtypes || enabledSubtypes.size() > 0) {
+ return enabledSubtypes;
+ } else {
+ return getApplicableSubtypesLocked(mRes, getSubtypes(imi));
+ }
+ }
+
public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(InputMethodInfo imi,
boolean allowsImplicitlySelectedSubtypes) {
synchronized (mMethodMap) {
- if (imi == null && mCurMethodId != null) {
- imi = mMethodMap.get(mCurMethodId);
- }
- final List<InputMethodSubtype> enabledSubtypes =
- mSettings.getEnabledInputMethodSubtypeListLocked(imi);
- if (!allowsImplicitlySelectedSubtypes || enabledSubtypes.size() > 0) {
- return enabledSubtypes;
- } else {
- return getApplicableSubtypesLocked(mRes, imi.getSubtypes());
- }
+ return getEnabledInputMethodSubtypeListLocked(imi, allowsImplicitlySelectedSubtypes);
}
}
@@ -1015,10 +1030,9 @@
}
if (id.equals(mCurMethodId)) {
- ArrayList<InputMethodSubtype> subtypes = info.getSubtypes();
InputMethodSubtype subtype = null;
- if (subtypeId >= 0 && subtypeId < subtypes.size()) {
- subtype = subtypes.get(subtypeId);
+ if (subtypeId >= 0 && subtypeId < info.getSubtypeCount()) {
+ subtype = info.getSubtypeAt(subtypeId);
}
if (subtype != mCurrentSubtype) {
synchronized (mMethodMap) {
@@ -1150,9 +1164,11 @@
if (!mIWindowManager.inputMethodClientHasFocus(client)) {
if (DEBUG) Slog.w(TAG, "Ignoring hideSoftInput of uid "
+ uid + ": " + client);
+ mStatusBar.setIMEButtonVisible(mCurToken, false);
return false;
}
} catch (RemoteException e) {
+ mStatusBar.setIMEButtonVisible(mCurToken, false);
return false;
}
}
@@ -1544,6 +1560,15 @@
& ApplicationInfo.FLAG_SYSTEM) != 0;
}
+ private static ArrayList<InputMethodSubtype> getSubtypes(InputMethodInfo imi) {
+ ArrayList<InputMethodSubtype> subtypes = new ArrayList<InputMethodSubtype>();
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int i = 0; i < subtypeCount; ++i) {
+ subtypes.add(imi.getSubtypeAt(i));
+ }
+ return subtypes;
+ }
+
private boolean chooseNewDefaultIMELocked() {
List<InputMethodInfo> enabled = mSettings.getEnabledInputMethodListLocked();
if (enabled != null && enabled.size() > 0) {
@@ -1640,12 +1665,12 @@
}
private void showInputMethodAndSubtypeEnabler(String inputMethodId) {
- Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_AND_SUBTYPE_ENABLER);
+ Intent intent = new Intent(Settings.ACTION_INPUT_METHOD_SUBTYPE_SETTINGS);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED
| Intent.FLAG_ACTIVITY_CLEAR_TOP);
if (!TextUtils.isEmpty(inputMethodId)) {
- intent.putExtra(EXTRA_INPUT_METHOD_ID, inputMethodId);
+ intent.putExtra(Settings.EXTRA_INPUT_METHOD_ID, inputMethodId);
}
mContext.startActivity(intent);
}
@@ -1671,75 +1696,53 @@
if (DEBUG) Slog.v(TAG, "Current IME: " + lastInputMethodId);
synchronized (mMethodMap) {
- final List<Pair<InputMethodInfo, ArrayList<String>>> immis =
- mSettings.getEnabledInputMethodAndSubtypeHashCodeListLocked();
- int N = immis.size();
-
- // Add applicable subtypes if no subtype for each IME is enabled.
- for (int i = 0; i < N; ++i) {
- InputMethodInfo imi = immis.get(i).first;
- ArrayList<String> subtypes = immis.get(i).second;
- if (subtypes != null && subtypes.size() == 0) {
- ArrayList<InputMethodSubtype> applicableSubtypes =
- getApplicableSubtypesLocked(mRes, imi.getSubtypes());
- final int numSubtypes = applicableSubtypes.size();
- for (int j = 0; j < numSubtypes; ++j) {
- subtypes.add(String.valueOf(applicableSubtypes.get(j).hashCode()));
- }
- }
- }
-
- ArrayList<Integer> subtypeIds = new ArrayList<Integer>();
-
+ final HashMap<InputMethodInfo, List<InputMethodSubtype>> immis =
+ getExplicitlyOrImplicitlyEnabledInputMethodsAndSubtypeListLocked();
if (immis == null || immis.size() == 0) {
return;
}
hideInputMethodMenuLocked();
-
final Map<CharSequence, Pair<InputMethodInfo, Integer>> imMap =
new TreeMap<CharSequence, Pair<InputMethodInfo, Integer>>(Collator.getInstance());
- for (int i = 0; i < N; ++i) {
- InputMethodInfo property = immis.get(i).first;
- final ArrayList<String> enabledSubtypeIds = immis.get(i).second;
+ for (InputMethodInfo imi: immis.keySet()) {
+ if (imi == null) continue;
+ List<InputMethodSubtype> explicitlyOrImplicitlyEnabledSubtypeList = immis.get(imi);
HashSet<String> enabledSubtypeSet = new HashSet<String>();
- for (String s : enabledSubtypeIds) {
- enabledSubtypeSet.add(s);
+ for (InputMethodSubtype subtype: explicitlyOrImplicitlyEnabledSubtypeList) {
+ enabledSubtypeSet.add(String.valueOf(subtype.hashCode()));
}
- if (property == null) {
- continue;
- }
- ArrayList<InputMethodSubtype> subtypes = property.getSubtypes();
- CharSequence label = property.loadLabel(pm);
+ ArrayList<InputMethodSubtype> subtypes = getSubtypes(imi);
+ CharSequence label = imi.loadLabel(pm);
if (showSubtypes && enabledSubtypeSet.size() > 0) {
- for (int j = 0; j < subtypes.size(); ++j) {
- InputMethodSubtype subtype = subtypes.get(j);
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int j = 0; j < subtypeCount; ++j) {
+ InputMethodSubtype subtype = imi.getSubtypeAt(j);
if (enabledSubtypeSet.contains(String.valueOf(subtype.hashCode()))) {
CharSequence title;
int nameResId = subtype.getNameResId();
String mode = subtype.getMode();
if (nameResId != 0) {
- title = pm.getText(property.getPackageName(), nameResId,
- property.getServiceInfo().applicationInfo);
+ title = pm.getText(imi.getPackageName(), nameResId,
+ imi.getServiceInfo().applicationInfo);
} else {
CharSequence language = subtype.getLocale();
// TODO: Use more friendly Title and UI
title = label + "," + (mode == null ? "" : mode) + ","
+ (language == null ? "" : language);
}
- imMap.put(title, new Pair<InputMethodInfo, Integer>(property, j));
+ imMap.put(title, new Pair<InputMethodInfo, Integer>(imi, j));
}
}
} else {
imMap.put(label,
- new Pair<InputMethodInfo, Integer>(property, NOT_A_SUBTYPE_ID));
- subtypeIds.add(0);
+ new Pair<InputMethodInfo, Integer>(imi, NOT_A_SUBTYPE_ID));
}
}
- N = imMap.size();
+ final int N = imMap.size();
mItems = imMap.keySet().toArray(new CharSequence[N]);
mIms = new InputMethodInfo[N];
mSubtypeIds = new int[N];
@@ -1791,7 +1794,7 @@
hideInputMethodMenu();
if (im != null) {
if ((subtypeId < 0)
- || (subtypeId >= im.getSubtypes().size())) {
+ || (subtypeId >= im.getSubtypeCount())) {
subtypeId = NOT_A_SUBTYPE_ID;
}
setInputMethodLocked(im.getId(), subtypeId);
@@ -1916,10 +1919,10 @@
mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
mCurrentSubtype = null;
} else {
- final ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
- if (subtypeId < subtypes.size()) {
- mSettings.putSelectedSubtype(subtypes.get(subtypeId).hashCode());
- mCurrentSubtype = subtypes.get(subtypeId);
+ if (subtypeId < imi.getSubtypeCount()) {
+ InputMethodSubtype subtype = imi.getSubtypeAt(subtypeId);
+ mSettings.putSelectedSubtype(subtype.hashCode());
+ mCurrentSubtype = subtype;
} else {
mSettings.putSelectedSubtype(NOT_A_SUBTYPE_ID);
mCurrentSubtype = null;
@@ -1967,9 +1970,9 @@
private int getSubtypeIdFromHashCode(InputMethodInfo imi, int subtypeHashCode) {
if (imi != null) {
- ArrayList<InputMethodSubtype> subtypes = imi.getSubtypes();
- for (int i = 0; i < subtypes.size(); ++i) {
- InputMethodSubtype ims = subtypes.get(i);
+ final int subtypeCount = imi.getSubtypeCount();
+ for (int i = 0; i < subtypeCount; ++i) {
+ InputMethodSubtype ims = imi.getSubtypeAt(i);
if (subtypeHashCode == ims.hashCode()) {
return i;
}
@@ -2113,13 +2116,13 @@
// 4. Search by the current subtype's locale from all subtypes.
if (subtype == null && mCurrentSubtype != null) {
subtype = findLastResortApplicableSubtypeLocked(
- mRes, imi.getSubtypes(), mode, mCurrentSubtype.getLocale(), false);
+ mRes, getSubtypes(imi), mode, mCurrentSubtype.getLocale(), false);
}
// 5. Search by the system locale from all subtypes.
// 6. Search the first enabled subtype matched with mode from all subtypes.
if (subtype == null) {
subtype = findLastResortApplicableSubtypeLocked(
- mRes, imi.getSubtypes(), mode, null, true);
+ mRes, getSubtypes(imi), mode, null, true);
}
if (subtype != null) {
if (imiId.equals(mCurMethodId)) {
@@ -2197,7 +2200,7 @@
}
} else {
mCurrentSubtype =
- mMethodMap.get(lastInputMethodId).getSubtypes().get(subtypeId);
+ getSubtypes(mMethodMap.get(lastInputMethodId)).get(subtypeId);
}
}
return mCurrentSubtype;
@@ -2320,8 +2323,9 @@
for (Pair<String, ArrayList<String>> imsPair : imsList) {
InputMethodInfo info = mMethodMap.get(imsPair.first);
if (info != null && info.getId().equals(imi.getId())) {
- ArrayList<InputMethodSubtype> subtypes = info.getSubtypes();
- for (InputMethodSubtype ims: subtypes) {
+ final int subtypeCount = info.getSubtypeCount();
+ for (int i = 0; i < subtypeCount; ++i) {
+ InputMethodSubtype ims = info.getSubtypeAt(i);
for (String s: imsPair.second) {
if (String.valueOf(ims.hashCode()).equals(s)) {
enabledSubtypes.add(ims);
@@ -2351,7 +2355,7 @@
}
}
- public List<Pair<String, ArrayList<String>>> getEnabledInputMethodsAndSubtypeListLocked() {
+ private List<Pair<String, ArrayList<String>>> getEnabledInputMethodsAndSubtypeListLocked() {
ArrayList<Pair<String, ArrayList<String>>> imsList
= new ArrayList<Pair<String, ArrayList<String>>>();
final String enabledInputMethodsStr = getEnabledInputMethodsStr();
@@ -2491,7 +2495,7 @@
for (Pair<String, String> ime: subtypeHistory) {
if (ime.first.equals(imeId)) {
if (DEBUG) {
- Slog.v(TAG, "Subtype found in the history: " + imeId
+ Slog.v(TAG, "Subtype found in the history: " + imeId + ", "
+ ime.second);
}
// We should break here
@@ -2499,6 +2503,9 @@
break;
}
}
+ if (DEBUG) {
+ Slog.v(TAG, "Add subtype to the history: " + imeId + ", " + subtypeId);
+ }
saveSubtypeHistory(subtypeHistory, imeId, subtypeId);
}
@@ -2538,7 +2545,7 @@
enabledImes, imeInTheHistory, subtypeInTheHistory);
if (!TextUtils.isEmpty(subtypeHashCode)) {
if (DEBUG) {
- Slog.d(TAG, "Enabled subtype found in the history:" + subtypeHashCode);
+ Slog.d(TAG, "Enabled subtype found in the history: " + subtypeHashCode);
}
return new Pair<String, String>(imeInTheHistory, subtypeHashCode);
}
@@ -2561,9 +2568,9 @@
InputMethodInfo ime = mMethodMap.get(imeId);
// If IME is enabled and no subtypes are enabled, applicable subtypes
// are enabled implicitly, so needs to treat them to be enabled.
- if (ime != null && ime.getSubtypes().size() > 0) {
+ if (ime != null && ime.getSubtypeCount() > 0) {
List<InputMethodSubtype> implicitlySelectedSubtypes =
- getApplicableSubtypesLocked(mRes, ime.getSubtypes());
+ getApplicableSubtypesLocked(mRes, getSubtypes(ime));
if (implicitlySelectedSubtypes != null) {
final int N = implicitlySelectedSubtypes.size();
for (int i = 0; i < N; ++i) {
diff --git a/services/java/com/android/server/MountService.java b/services/java/com/android/server/MountService.java
index d6804f9..7440f52 100644
--- a/services/java/com/android/server/MountService.java
+++ b/services/java/com/android/server/MountService.java
@@ -19,6 +19,7 @@
import com.android.internal.app.IMediaContainerService;
import com.android.server.am.ActivityManagerService;
+import android.Manifest;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -618,7 +619,7 @@
Slog.w(TAG, "Failed to get share availability");
}
/*
- * Now that we've done our initialization, release
+ * Now that we've done our initialization, release
* the hounds!
*/
mReady = true;
@@ -1237,7 +1238,7 @@
waitForReady();
return doGetVolumeShared(Environment.getExternalStorageDirectory().getPath(), "ums");
}
-
+
/**
* @return state of the volume at the specified mount point
*/
@@ -1407,7 +1408,7 @@
return rc;
}
-
+
public int mountSecureContainer(String id, String key, int ownerUid) {
validatePermission(android.Manifest.permission.ASEC_MOUNT_UNMOUNT);
waitForReady();
@@ -1495,7 +1496,7 @@
synchronized (mAsecMountSet) {
/*
- * Because a mounted container has active internal state which cannot be
+ * Because a mounted container has active internal state which cannot be
* changed while active, we must ensure both ids are not currently mounted.
*/
if (mAsecMountSet.contains(oldId) || mAsecMountSet.contains(newId)) {
@@ -1635,7 +1636,8 @@
throw new IllegalArgumentException("password cannot be null");
}
- // TODO: Enforce a permission
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
+ "no permission to access the crypt keeper");
waitForReady();
@@ -1644,13 +1646,30 @@
}
try {
- mConnector.doCommand(String.format("cryptfs checkpw %s", password));
+ ArrayList<String> rsp = mConnector.doCommand("cryptfs checkpw " + password);
+ String []tok = rsp.get(0).split(" ");
+
+ if (tok == null || tok.length != 2) {
+ return -1;
+ }
+
+ int code = Integer.parseInt(tok[1]);
+
+ if (code == 0) {
+ // Decrypt was successful. Post a delayed message before restarting in order
+ // to let the UI to clear itself
+ mHandler.postDelayed(new Runnable() {
+ public void run() {
+ mConnector.doCommand(String.format("cryptfs restart"));
+ }
+ }, 2000); // 2 seconds
+ }
+
+ return code;
} catch (NativeDaemonConnectorException e) {
// Decryption failed
return e.getCode();
}
-
- return 0;
}
public int encryptStorage(String password) {
@@ -1658,16 +1677,17 @@
throw new IllegalArgumentException("password cannot be null");
}
- // TODO: Enforce a permission
+ mContext.enforceCallingOrSelfPermission(Manifest.permission.CRYPT_KEEPER,
+ "no permission to access the crypt keeper");
waitForReady();
if (DEBUG_EVENTS) {
- Slog.i(TAG, "decrypting storage...");
+ Slog.i(TAG, "encrypting storage...");
}
try {
- mConnector.doCommand(String.format("cryptfs enablecrypto wipe %s", password));
+ mConnector.doCommand(String.format("cryptfs enablecrypto inplace %s", password));
} catch (NativeDaemonConnectorException e) {
// Encryption failed
return e.getCode();
diff --git a/services/java/com/android/server/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java
index 3e930ae..2af291d 100644
--- a/services/java/com/android/server/WindowManagerService.java
+++ b/services/java/com/android/server/WindowManagerService.java
@@ -583,7 +583,7 @@
void broadcastDragStartedLw(final float touchX, final float touchY) {
// Cache a base-class instance of the clip metadata so that parceling
// works correctly in calling out to the apps.
- mDataDescription = mData.getDescription();
+ mDataDescription = (mData != null) ? mData.getDescription() : null;
mNotifiedWindows.clear();
mDragInProgress = true;
@@ -708,16 +708,20 @@
// Move the surface to the given touch
if (SHOW_TRANSACTIONS) Slog.i(TAG, ">>> OPEN TRANSACTION notifyMoveLw");
- mSurface.openTransaction();
+ Surface.openTransaction();
try {
mSurface.setPosition((int)(x - mThumbOffsetX), (int)(y - mThumbOffsetY));
} finally {
- mSurface.closeTransaction();
+ Surface.closeTransaction();
if (SHOW_TRANSACTIONS) Slog.i(TAG, "<<< CLOSE TRANSACTION notifyMoveLw");
}
// Tell the affected window
WindowState touchedWin = getTouchedWinAtPointLw(x, y);
+ if (touchedWin == null) {
+ if (DEBUG_DRAG) Slog.d(TAG, "No touched win at x=" + x + " y=" + y);
+ return;
+ }
if ((mFlags & View.DRAG_FLAG_GLOBAL) == 0) {
final IBinder touchedBinder = touchedWin.mClient.asBinder();
if (touchedBinder != mLocalWin) {
@@ -5865,7 +5869,7 @@
final InputWindow inputWindow = windowList.add();
inputWindow.inputChannel = mDragState.mServerChannel;
inputWindow.name = "drag";
- inputWindow.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
+ inputWindow.layoutParamsFlags = 0;
inputWindow.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
inputWindow.dispatchingTimeoutNanos = DEFAULT_INPUT_DISPATCHING_TIMEOUT_NANOS;
inputWindow.visible = true;
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index 2ef85d5..9e9a4f2 100755
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -6817,6 +6817,9 @@
if (info.durationMillis != -1) {
sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
}
+ if (info.numInstances != -1) {
+ sb.append("Instance-Count: ").append(info.numInstances).append("\n");
+ }
if (info.tags != null) {
for (String tag : info.tags) {
sb.append("Span-Tag: ").append(tag).append("\n");
diff --git a/services/sensorservice/RotationVectorSensor.cpp b/services/sensorservice/RotationVectorSensor.cpp
index 418e7f8..3abfc12 100644
--- a/services/sensorservice/RotationVectorSensor.cpp
+++ b/services/sensorservice/RotationVectorSensor.cpp
@@ -34,9 +34,9 @@
RotationVectorSensor::RotationVectorSensor(sensor_t const* list, size_t count)
: mSensorDevice(SensorDevice::getInstance()),
- mALowPass(M_SQRT1_2, 5.0f),
+ mALowPass(M_SQRT1_2, 1.5f),
mAX(mALowPass), mAY(mALowPass), mAZ(mALowPass),
- mMLowPass(M_SQRT1_2, 2.5f),
+ mMLowPass(M_SQRT1_2, 1.5f),
mMX(mMLowPass), mMY(mMLowPass), mMZ(mMLowPass)
{
for (size_t i=0 ; i<count ; i++) {
diff --git a/services/sensorservice/RotationVectorSensor.h b/services/sensorservice/RotationVectorSensor.h
index b7c9512..17699f8 100644
--- a/services/sensorservice/RotationVectorSensor.h
+++ b/services/sensorservice/RotationVectorSensor.h
@@ -38,9 +38,9 @@
double mAccTime;
double mMagTime;
SecondOrderLowPassFilter mALowPass;
- BiquadFilter mAX, mAY, mAZ;
+ CascadedBiquadFilter mAX, mAY, mAZ;
SecondOrderLowPassFilter mMLowPass;
- BiquadFilter mMX, mMY, mMZ;
+ CascadedBiquadFilter mMX, mMY, mMZ;
public:
RotationVectorSensor(sensor_t const* list, size_t count);
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index fde68f6..3730739 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -691,22 +691,6 @@
}
}
-void Layer::finishPageFlip()
-{
- ClientRef::Access sharedClient(mUserClientRef);
- SharedBufferServer* lcblk(sharedClient.get());
- if (lcblk) {
- int buf = mBufferManager.getActiveBufferIndex();
- if (buf >= 0) {
- status_t err = lcblk->unlock( buf );
- LOGE_IF(err!=NO_ERROR,
- "layer %p, buffer=%d wasn't locked!",
- this, buf);
- }
- }
-}
-
-
void Layer::dump(String8& result, char* buffer, size_t SIZE) const
{
LayerBaseClient::dump(result, buffer, SIZE);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 5444d2f..2908119 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -75,7 +75,6 @@
virtual uint32_t doTransaction(uint32_t transactionFlags);
virtual void lockPageFlip(bool& recomputeVisibleRegions);
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
- virtual void finishPageFlip();
virtual bool needsBlending() const { return mNeedsBlending; }
virtual bool needsDithering() const { return mNeedsDithering; }
virtual bool needsFiltering() const;
diff --git a/services/surfaceflinger/LayerBase.cpp b/services/surfaceflinger/LayerBase.cpp
index 0c1fcf9..464841b 100644
--- a/services/surfaceflinger/LayerBase.cpp
+++ b/services/surfaceflinger/LayerBase.cpp
@@ -273,10 +273,6 @@
}
}
-void LayerBase::finishPageFlip()
-{
-}
-
void LayerBase::invalidate()
{
if ((android_atomic_or(1, &mInvalidate)&1) == 0) {
@@ -534,6 +530,12 @@
result.append(buffer);
}
+void LayerBase::shortDump(String8& result, char* scratch, size_t size) const
+{
+ LayerBase::dump(result, scratch, size);
+}
+
+
// ---------------------------------------------------------------------------
int32_t LayerBaseClient::sIdentity = 1;
@@ -585,6 +587,12 @@
result.append(buffer);
}
+
+void LayerBaseClient::shortDump(String8& result, char* scratch, size_t size) const
+{
+ LayerBaseClient::dump(result, scratch, size);
+}
+
// ---------------------------------------------------------------------------
LayerBaseClient::Surface::Surface(
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index f6c49fc..1a34f52 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -174,11 +174,6 @@
virtual void unlockPageFlip(const Transform& planeTransform, Region& outDirtyRegion);
/**
- * finishPageFlip - called after all surfaces have drawn.
- */
- virtual void finishPageFlip();
-
- /**
* needsBlending - true if this surface needs blending
*/
virtual bool needsBlending() const { return false; }
@@ -211,6 +206,7 @@
/** always call base class first */
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void shortDump(String8& result, char* scratch, size_t size) const;
enum { // flags for doTransaction()
@@ -324,6 +320,7 @@
protected:
virtual void dump(String8& result, char* scratch, size_t size) const;
+ virtual void shortDump(String8& result, char* scratch, size_t size) const;
private:
mutable Mutex mLock;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 65ad956..694af70 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -394,14 +394,10 @@
logger.log(GraphicLog::SF_SWAP_BUFFERS, index);
postFramebuffer();
- logger.log(GraphicLog::SF_UNLOCK_CLIENTS, index);
- unlockClients();
-
logger.log(GraphicLog::SF_REPAINT_DONE, index);
} else {
// pretend we did the post
hw.compositionComplete();
- unlockClients();
usleep(16667); // 60 fps period
}
return true;
@@ -872,30 +868,36 @@
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(layers[i]);
layer->setPerFrameData(&cur[i]);
- if (cur[i].hints & HWC_HINT_CLEAR_FB) {
- if (!(layer->needsBlending())) {
- transparent.orSelf(layer->visibleRegionScreen);
- }
- }
}
err = hwc.prepare();
LOGE_IF(err, "HWComposer::prepare failed (%s)", strerror(-err));
- }
- /*
- * clear the area of the FB that need to be transparent
- */
- transparent.andSelf(dirty);
- if (!transparent.isEmpty()) {
- glClearColor(0,0,0,0);
- Region::const_iterator it = transparent.begin();
- Region::const_iterator const end = transparent.end();
- const int32_t height = hw.getHeight();
- while (it != end) {
- const Rect& r(*it++);
- const GLint sy = height - (r.top + r.height());
- glScissor(r.left, sy, r.width(), r.height());
- glClear(GL_COLOR_BUFFER_BIT);
+ if (err == NO_ERROR) {
+ for (size_t i=0 ; i<count ; i++) {
+ if (cur[i].hints & HWC_HINT_CLEAR_FB) {
+ const sp<LayerBase>& layer(layers[i]);
+ if (!(layer->needsBlending())) {
+ transparent.orSelf(layer->visibleRegionScreen);
+ }
+ }
+ }
+
+ /*
+ * clear the area of the FB that need to be transparent
+ */
+ transparent.andSelf(dirty);
+ if (!transparent.isEmpty()) {
+ glClearColor(0,0,0,0);
+ Region::const_iterator it = transparent.begin();
+ Region::const_iterator const end = transparent.end();
+ const int32_t height = hw.getHeight();
+ while (it != end) {
+ const Rect& r(*it++);
+ const GLint sy = height - (r.top + r.height());
+ glScissor(r.left, sy, r.width(), r.height());
+ glClear(GL_COLOR_BUFFER_BIT);
+ }
+ }
}
}
@@ -920,17 +922,6 @@
}
}
-void SurfaceFlinger::unlockClients()
-{
- const LayerVector& drawingLayers(mDrawingState.layersSortedByZ);
- const size_t count = drawingLayers.size();
- sp<LayerBase> const* const layers = drawingLayers.array();
- for (size_t i=0 ; i<count ; ++i) {
- const sp<LayerBase>& layer = layers[i];
- layer->finishPageFlip();
- }
-}
-
void SurfaceFlinger::debugFlashRegions()
{
const DisplayHardware& hw(graphicPlane(0).displayHardware());
@@ -1491,8 +1482,13 @@
result.append(buffer);
}
+ /*
+ * Dump the visible layer list
+ */
const LayerVector& currentLayers = mCurrentState.layersSortedByZ;
const size_t count = currentLayers.size();
+ snprintf(buffer, SIZE, "Visible layers (count = %d)\n", count);
+ result.append(buffer);
for (size_t i=0 ; i<count ; i++) {
const sp<LayerBase>& layer(currentLayers[i]);
layer->dump(result, buffer, SIZE);
@@ -1502,6 +1498,24 @@
layer->visibleRegionScreen.dump(result, "visibleRegionScreen");
}
+ /*
+ * Dump the layers in the purgatory
+ */
+
+ const size_t purgatorySize = mLayerPurgatory.size();
+ snprintf(buffer, SIZE, "Purgatory state (%d entries)\n", purgatorySize);
+ result.append(buffer);
+ for (size_t i=0 ; i<purgatorySize ; i++) {
+ const sp<LayerBase>& layer(mLayerPurgatory.itemAt(i));
+ layer->shortDump(result, buffer, SIZE);
+ }
+
+ /*
+ * Dump SurfaceFlinger global state
+ */
+
+ snprintf(buffer, SIZE, "SurfaceFlinger global state\n");
+ result.append(buffer);
mWormholeRegion.dump(result, "WormholeRegion");
const DisplayHardware& hw(graphicPlane(0).displayHardware());
snprintf(buffer, SIZE,
@@ -1527,6 +1541,9 @@
result.append(buffer);
}
+ /*
+ * Dump HWComposer state
+ */
HWComposer& hwc(hw.getHwComposer());
snprintf(buffer, SIZE, " h/w composer %s and %s\n",
hwc.initCheck()==NO_ERROR ? "present" : "not present",
@@ -1534,6 +1551,9 @@
result.append(buffer);
hwc.dump(result, buffer, SIZE);
+ /*
+ * Dump gralloc state
+ */
const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
alloc.dump(result);
hw.dump(result);
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index eabdc64..6dd91ac 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -314,7 +314,6 @@
void handleRepaint();
void postFramebuffer();
void composeSurfaces(const Region& dirty);
- void unlockClients();
ssize_t addClientLayer(const sp<Client>& client,
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index c143424..a3d3781 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -30,6 +30,7 @@
import android.util.EventLog;
import java.net.InetAddress;
+import java.net.Inet4Address;
import java.net.InterfaceAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
@@ -448,22 +449,65 @@
NetworkInterface networkInterface = NetworkInterface.getByName(interfaceName);
linkProperties.setInterfaceName(interfaceName);
- // TODO: Get gateway and dns via RIL interface not property?
- String gatewayAddress = SystemProperties.get(prefix + "gw");
- linkProperties.setGateway(InetAddress.getByName(gatewayAddress));
+ if (response.length >= 5) {
+ log("response.length >=5 using response for ip='" + response[2] +
+ "' dns='" + response[3] + "' gateway='" + response[4] + "'");
+ String [] addresses = response[2].split(" ");
+ String [] dnses = response[3].split(" ");
+ String gateway = response[4];
+ for (String addr : addresses) {
+ LinkAddress la;
+ if (!InetAddress.isNumeric(addr)) {
+ throw new RuntimeException(
+ "Vendor ril bug: Non-numeric ip addr=" + addr);
+ }
+ InetAddress ia = InetAddress.getByName(addr);
+ if (ia instanceof Inet4Address) {
+ la = new LinkAddress(ia, 32);
+ } else {
+ la = new LinkAddress(ia, 128);
+ }
+ linkProperties.addLinkAddress(la);
+ }
- for (InterfaceAddress addr : networkInterface.getInterfaceAddresses()) {
- linkProperties.addLinkAddress(new LinkAddress(addr));
- }
- // TODO: Get gateway and dns via RIL interface not property?
- String dnsServers[] = new String[2];
- dnsServers[0] = SystemProperties.get(prefix + "dns1");
- dnsServers[1] = SystemProperties.get(prefix + "dns2");
- if (isDnsOk(dnsServers)) {
- linkProperties.addDns(InetAddress.getByName(dnsServers[0]));
- linkProperties.addDns(InetAddress.getByName(dnsServers[1]));
+ if (dnses.length != 0) {
+ for (String addr : dnses) {
+ if (!InetAddress.isNumeric(addr)) {
+ throw new RuntimeException(
+ "Vendor ril bug: Non-numeric dns addr=" + addr);
+ }
+ InetAddress ia = InetAddress.getByName(addr);
+ linkProperties.addDns(ia);
+ }
+ result = SetupResult.SUCCESS;
+ } else {
+ result = SetupResult.ERR_BadDns;
+ }
+
+ if (!InetAddress.isNumeric(gateway)) {
+ throw new RuntimeException(
+ "Vendor ril bug: Non-numeric gateway addr=" + gateway);
+ }
+ linkProperties.setGateway(InetAddress.getByName(gateway));
+
} else {
- result = SetupResult.ERR_BadDns;
+ log("response.length < 5 using properties for dns and gateway");
+ for (InterfaceAddress addr : networkInterface.getInterfaceAddresses()) {
+ linkProperties.addLinkAddress(new LinkAddress(addr));
+ }
+
+ String gatewayAddress = SystemProperties.get(prefix + "gw");
+ linkProperties.setGateway(InetAddress.getByName(gatewayAddress));
+
+ String dnsServers[] = new String[2];
+ dnsServers[0] = SystemProperties.get(prefix + "dns1");
+ dnsServers[1] = SystemProperties.get(prefix + "dns2");
+ if (isDnsOk(dnsServers)) {
+ linkProperties.addDns(InetAddress.getByName(dnsServers[0]));
+ linkProperties.addDns(InetAddress.getByName(dnsServers[1]));
+ } else {
+ result = SetupResult.ERR_BadDns;
+ }
}
} catch (UnknownHostException e1) {
log("onSetupCompleted: UnknowHostException " + e1);
diff --git a/tests/CoreTests/android/core/URLTest.java b/tests/CoreTests/android/core/URLTest.java
deleted file mode 100644
index 5efcd5b..0000000
--- a/tests/CoreTests/android/core/URLTest.java
+++ /dev/null
@@ -1,228 +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.core;
-
-import android.test.suitebuilder.annotation.Suppress;
-import junit.framework.TestCase;
-
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.io.OutputStream;
-import java.io.PrintWriter;
-import java.net.HttpURLConnection;
-import java.net.ServerSocket;
-import java.net.Socket;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.HashMap;
-import java.util.Map;
-
-public class URLTest extends TestCase {
-
- private static void get(String u) throws IOException {
- URL url = new URL(u);
- URLConnection cn = url.openConnection();
- cn.connect();
-// System.out.println("Content-Type: " + cn.getContentType());
-// System.out.println("Content-Length: " + cn.getContentLength());
-
- InputStream stream = cn.getInputStream();
- if (stream == null) {
- throw new RuntimeException("stream is null");
- }
- byte[] data = new byte[1024];
- stream.read(data);
-
-// if (true) {
-// System.out.print("data=");
-// System.out.write(data);
-// System.out.println();
-// }
-
-// System.out.println("Content-Type: " + cn.getContentType());
-// System.out.print("data:");
-// System.out.write(data);
-// System.out.println();
-
- assertTrue(new String(data).indexOf("<html>") >= 0);
- }
-
- @Suppress
- public void testGetHTTP() throws Exception {
- get("http://www.google.com");
- }
-
- @Suppress
- public void testGetHTTPS() throws Exception {
- get("https://www.fortify.net/cgi/ssl_2.pl");
- }
-
- /**
- * Dummy HTTP server class for testing keep-alive behavior. Listens a
- * single time and responds to a given number of requests on the same
- * socket. Then closes the socket.
- */
- private static class DummyServer implements Runnable {
-
- private int keepAliveCount;
- private Map<String, String> headers = new HashMap<String, String>();
-
- public DummyServer(int keepAliveCount) {
- this.keepAliveCount = keepAliveCount;
- }
-
- public void run() {
- try {
- ServerSocket server = new ServerSocket(8182);
- Socket socket = server.accept();
-
- InputStream input = socket.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input));
- try {
- for (int i = 0; i < keepAliveCount; i++) {
- reader.readLine();
- headers.clear();
- while (true) {
- String header = reader.readLine();
- if (header.length() == 0) {
- break;
- }
- int colon = header.indexOf(":");
- String key = header.substring(0, colon);
- String value = header.substring(colon + 1).trim();
- headers.put(key, value);
- }
-
- OutputStream output = socket.getOutputStream();
- PrintWriter writer = new PrintWriter(output);
-
- try {
- writer.println("HTTP/1.1 200 OK");
- String body = "Hello, Android world #" + i + "!";
- writer.println("Content-Length: " + body.length());
- writer.println("");
- writer.print(body);
- writer.flush();
- } finally {
- writer.close();
- }
- }
- } finally {
- reader.close();
- }
- socket.close();
- server.close();
- } catch (Exception ex) {
- throw new RuntimeException(ex);
- }
- }
- }
-
- /**
- * Does a request to the given URL, reads and returns the result.
- */
- private String request(URL url) throws Exception {
- URLConnection connection = url.openConnection();
- connection.connect();
-
- InputStream input = connection.getInputStream();
- BufferedReader reader = new BufferedReader(new InputStreamReader(input));
- try {
- return reader.readLine();
- } finally {
- reader.close();
- }
- }
-
- /**
- * Test case for HTTP keep-alive behavior.
- */
- @Suppress
- public void testGetKeepAlive() throws Exception {
- new Thread(new DummyServer(3)).start();
- Thread.sleep(100);
-
- // We expect the request to work three times, then it fails.
- URL url = new URL("http://localhost:8182");
- assertEquals("Hello, Android world #0!", request(url));
- assertEquals("Hello, Android world #1!", request(url));
- assertEquals("Hello, Android world #2!", request(url));
-
- try {
- request(url);
- fail("ConnectException expected.");
- } catch (Exception ex) {
- // Ok.
- }
- }
-
- @Suppress
- public void testUserAgentHeader() throws Exception {
- DummyServer server = new DummyServer(1);
- new Thread(server).start();
- Thread.sleep(100);
-
- // We expect the request to work three times, then it fails.
- request(new URL("http://localhost:8182"));
-
- String userAgent = server.headers.get("User-Agent");
- assertTrue("Unexpected User-Agent: " + userAgent, userAgent.matches(
- "Dalvik/[\\d.]+ \\(Linux; U; Android \\w+(;.*)?( Build/\\w+)?\\)"));
- }
-
- /**
- * Regression for issue 1001814.
- */
- @Suppress
- public void testHttpConnectionTimeout() throws Exception {
- int timeout = 5000;
- HttpURLConnection cn = null;
- long start = 0;
- try {
- start = System.currentTimeMillis();
- URL url = new URL("http://123.123.123.123");
- cn = (HttpURLConnection) url.openConnection();
- cn.setConnectTimeout(5000);
- cn.connect();
- fail("should have thrown an exception");
- } catch (IOException ioe) {
- long delay = System.currentTimeMillis() - start;
- if (Math.abs(timeout - delay) > 1000) {
- fail("Timeout was not accurate. it needed " + delay +
- " instead of " + timeout + "miliseconds");
- }
- } finally {
- if (cn != null) {
- cn.disconnect();
- }
- }
- }
-
- /**
- * Regression test for issue 1158780 where using '{' and '}' in an URL threw
- * an NPE. The RI accepts this URL and returns the status 404.
- */
- @Suppress
- public void testMalformedUrl() throws Exception {
- URL url = new URL("http://www.google.com/cgi-bin/myscript?g={United+States}+Borders+Mexico+{Climate+change}+Marketing+{Automotive+industry}+News+Health+Internet");
- HttpURLConnection conn = (HttpURLConnection)url.openConnection();
- int status = conn.getResponseCode();
- android.util.Log.d("URLTest", "status: " + status);
- }
-}
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
index b2d2a98..39a4614 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java
@@ -122,6 +122,8 @@
ignoreResultList.add("storage/indexeddb"); // indexeddb not supported
ignoreResultList.add("storage/private-browsing-readonly.html"); // private browsing not supported
ignoreResultList.add("websocket/tests/workers"); // workers not supported
+ ignoreResultList.add("dom/xhtml/level2/html/htmldocument04.xhtml"); // /mnt/sdcard on SR uses lowercase filesystem, this test checks filename and is case senstive.
+ ignoreResultList.add("dom/html/level2/html/htmldocument04.html"); // ditto
// Expected failures due to missing expected results
ignoreResultList.add("dom/xhtml/level3/core/canonicalform08.xhtml");
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
index a3466e2..9c4fa97 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/TestShellActivity.java
@@ -37,6 +37,7 @@
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.ConsoleMessage;
+import android.webkit.CookieManager;
import android.webkit.GeolocationPermissions;
import android.webkit.HttpAuthHandler;
import android.webkit.JsPromptResult;
@@ -827,6 +828,7 @@
setDefaultWebSettings(mWebView);
mIsGeolocationPermissionSet = false;
mPendingGeolocationPermissionCallbacks = null;
+ CookieManager.getInstance().removeAllCookie();
}
private long[] getDrawWebViewTime(WebView view, int count) {
diff --git a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
index 383d782..17345ae 100644
--- a/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
+++ b/tests/DumpRenderTree/src/com/android/dumprendertree/WebViewEventSender.java
@@ -357,11 +357,11 @@
}
private int contentsToWindowX(int x) {
- return (int) (x * mWebView.getScale()) - mWebView.getScrollX();
+ return Math.round(x * mWebView.getScale()) - mWebView.getScrollX();
}
private int contentsToWindowY(int y) {
- return (int) (y * mWebView.getScale()) - mWebView.getScrollY();
+ return Math.round(y * mWebView.getScale()) - mWebView.getScrollY();
}
private WebView mWebView = null;
diff --git a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java b/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java
index d425734..af22039 100644
--- a/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java
+++ b/tests/DumpRenderTree2/src/com/android/dumprendertree2/EventSenderImpl.java
@@ -73,8 +73,8 @@
}
private Point createViewPointFromContentCoordinates(int x, int y) {
- return new Point((int)(x * mWebView.getScale()) - mWebView.getScrollX(),
- (int)(y * mWebView.getScale()) - mWebView.getScrollY());
+ return new Point(Math.round(x * mWebView.getScale()) - mWebView.getScrollX(),
+ Math.round(y * mWebView.getScale()) - mWebView.getScrollY());
}
public static class TouchPoint {
diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml
index 691aff28..61f8e1a 100644
--- a/tests/HwAccelerationTest/AndroidManifest.xml
+++ b/tests/HwAccelerationTest/AndroidManifest.xml
@@ -25,6 +25,24 @@
android:hardwareAccelerated="true">
<activity
+ android:name="BitmapMeshActivity"
+ android:label="_BitmapMesh">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
+ android:name="ShapesActivity"
+ android:label="_Shapes">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="SimplePatchActivity"
android:label="_SimplePatch"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
@@ -53,6 +71,15 @@
</activity>
<activity
+ android:name="ViewLayersActivity3"
+ android:label="_ViewLayers3">
+ <intent-filter>
+ <action android:name="android.intent.action.MAIN" />
+ <category android:name="android.intent.category.LAUNCHER" />
+ </intent-filter>
+ </activity>
+
+ <activity
android:name="AlphaLayersActivity"
android:label="_αLayers">
<intent-filter>
diff --git a/tests/HwAccelerationTest/res/layout/view_layers_3.xml b/tests/HwAccelerationTest/res/layout/view_layers_3.xml
new file mode 100644
index 0000000..a820f5f
--- /dev/null
+++ b/tests/HwAccelerationTest/res/layout/view_layers_3.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <LinearLayout
+ android:background="#30ff0000"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+ <LinearLayout
+ android:background="#3000ff00"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1"
+ android:padding="12dip">
+
+ <ListView
+ android:id="@+id/list1"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:background="#300000ff"
+ android:layout_width="0dip"
+ android:layout_height="match_parent"
+ android:layout_weight="1" />
+
+</LinearLayout>
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java
new file mode 100644
index 0000000..833d559
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/BitmapMeshActivity.java
@@ -0,0 +1,67 @@
+/*
+ * 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 com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class BitmapMeshActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ final BitmapMeshView view = new BitmapMeshView(this);
+ view.setDrawingCacheEnabled(true);
+ setContentView(view);
+ }
+
+ static class BitmapMeshView extends View {
+ private Paint mBitmapPaint;
+ private final Bitmap mBitmap1;
+
+ BitmapMeshView(Context c) {
+ super(c);
+
+ mBitmap1 = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.drawARGB(255, 255, 255, 255);
+ canvas.translate(100, 100);
+ final float width = mBitmap1.getWidth() / 3.0f;
+ final float height = mBitmap1.getHeight() / 3.0f;
+ canvas.drawBitmapMesh(mBitmap1, 3, 3, new float[] {
+ 0.0f, 0.0f, width, 0.0f, width * 2, 0.0f, width * 3, 0.0f,
+ 0.0f, height, width, height, width * 2, height, width * 4, height,
+ 0.0f, height * 2, width, height * 2, width * 2, height * 2, width * 3, height * 2,
+ 0.0f, height * 4, width, height * 4, width * 2, height * 4, width * 4, height * 4,
+ }, 0, null, 0, null);
+ }
+ }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java
new file mode 100644
index 0000000..536a669
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java
@@ -0,0 +1,92 @@
+/*
+ * 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 com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.RectF;
+import android.os.Bundle;
+import android.view.View;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ShapesActivity extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(new ShapesView(this));
+ }
+
+ static class ShapesView extends View {
+ private Paint mNormalPaint;
+ private Paint mStrokePaint;
+ private Paint mFillPaint;
+ private RectF mRect;
+
+ ShapesView(Context c) {
+ super(c);
+
+ mRect = new RectF(0.0f, 0.0f, 160.0f, 90.0f);
+
+ mNormalPaint = new Paint();
+ mNormalPaint.setAntiAlias(true);
+ mNormalPaint.setColor(0xff0000ff);
+ mNormalPaint.setStrokeWidth(6.0f);
+ mNormalPaint.setStyle(Paint.Style.FILL_AND_STROKE);
+
+ mStrokePaint = new Paint();
+ mStrokePaint.setAntiAlias(true);
+ mStrokePaint.setColor(0xff0000ff);
+ mStrokePaint.setStrokeWidth(6.0f);
+ mStrokePaint.setStyle(Paint.Style.STROKE);
+
+ mFillPaint = new Paint();
+ mFillPaint.setAntiAlias(true);
+ mFillPaint.setColor(0xff0000ff);
+ mFillPaint.setStyle(Paint.Style.FILL);
+ }
+
+ @Override
+ protected void onDraw(Canvas canvas) {
+ super.onDraw(canvas);
+
+ canvas.save();
+ canvas.translate(50.0f, 50.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mNormalPaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mStrokePaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawRoundRect(mRect, 6.0f, 6.0f, mFillPaint);
+ canvas.restore();
+
+ canvas.save();
+ canvas.translate(250.0f, 50.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mNormalPaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mStrokePaint);
+
+ canvas.translate(0.0f, 110.0f);
+ canvas.drawCircle(80.0f, 45.0f, 45.0f, mFillPaint);
+ canvas.restore();
+ }
+ }
+}
diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
new file mode 100644
index 0000000..c8ae75b
--- /dev/null
+++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ViewLayersActivity3.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.test.hwui;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.Resources;
+import android.os.Bundle;
+import android.util.DisplayMetrics;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+@SuppressWarnings({"UnusedDeclaration"})
+public class ViewLayersActivity3 extends Activity {
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ setContentView(R.layout.view_layers_3);
+
+ setupList(R.id.list1);
+ }
+
+ private void setupList(int listId) {
+ final ListView list = (ListView) findViewById(listId);
+ list.setAdapter(new SimpleListAdapter(this));
+ list.setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ ((View) list.getParent()).setLayerType(View.LAYER_TYPE_HARDWARE, null);
+ }
+
+ private static class SimpleListAdapter extends ArrayAdapter<String> {
+ public SimpleListAdapter(Context context) {
+ super(context, android.R.layout.simple_list_item_1, DATA_LIST);
+ }
+
+ @Override
+ public View getView(int position, View convertView, ViewGroup parent) {
+ TextView v = (TextView) super.getView(position, convertView, parent);
+ final Resources r = getContext().getResources();
+ final DisplayMetrics metrics = r.getDisplayMetrics();
+ v.setCompoundDrawablePadding((int) (6 * metrics.density + 0.5f));
+ v.setCompoundDrawablesWithIntrinsicBounds(r.getDrawable(R.drawable.icon),
+ null, null, null);
+ return v;
+ }
+ }
+
+ private static final String[] DATA_LIST = {
+ "Afghanistan", "Albania", "Algeria", "American Samoa", "Andorra",
+ "Angola", "Anguilla", "Antarctica", "Antigua and Barbuda", "Argentina",
+ "Armenia", "Aruba", "Australia", "Austria", "Azerbaijan",
+ "Bahrain", "Bangladesh", "Barbados", "Belarus", "Belgium",
+ "Belize", "Benin", "Bermuda", "Bhutan", "Bolivia",
+ "Bosnia and Herzegovina", "Botswana", "Bouvet Island", "Brazil",
+ "British Indian Ocean Territory", "British Virgin Islands", "Brunei", "Bulgaria",
+ "Burkina Faso", "Burundi", "Cote d'Ivoire", "Cambodia", "Cameroon", "Canada", "Cape Verde",
+ "Cayman Islands", "Central African Republic", "Chad", "Chile", "China",
+ "Christmas Island", "Cocos (Keeling) Islands", "Colombia", "Comoros", "Congo",
+ "Cook Islands", "Costa Rica", "Croatia", "Cuba", "Cyprus", "Czech Republic",
+ "Democratic Republic of the Congo", "Denmark", "Djibouti", "Dominica", "Dominican Republic",
+ "East Timor", "Ecuador", "Egypt", "El Salvador", "Equatorial Guinea", "Eritrea",
+ "Estonia", "Ethiopia", "Faeroe Islands", "Falkland Islands", "Fiji", "Finland",
+ "Former Yugoslav Republic of Macedonia", "France", "French Guiana", "French Polynesia",
+ "French Southern Territories", "Gabon", "Georgia", "Germany", "Ghana", "Gibraltar",
+ "Greece", "Greenland", "Grenada", "Guadeloupe", "Guam", "Guatemala", "Guinea", "Guinea-Bissau",
+ "Guyana", "Haiti", "Heard Island and McDonald Islands", "Honduras", "Hong Kong", "Hungary",
+ "Iceland", "India", "Indonesia", "Iran", "Iraq", "Ireland", "Israel", "Italy", "Jamaica",
+ "Japan", "Jordan", "Kazakhstan", "Kenya", "Kiribati", "Kuwait", "Kyrgyzstan", "Laos",
+ "Latvia", "Lebanon", "Lesotho", "Liberia", "Libya", "Liechtenstein", "Lithuania", "Luxembourg",
+ "Macau", "Madagascar", "Malawi", "Malaysia", "Maldives", "Mali", "Malta", "Marshall Islands",
+ "Martinique", "Mauritania", "Mauritius", "Mayotte", "Mexico", "Micronesia", "Moldova",
+ "Monaco", "Mongolia", "Montserrat", "Morocco", "Mozambique", "Myanmar", "Namibia",
+ "Nauru", "Nepal", "Netherlands", "Netherlands Antilles", "New Caledonia", "New Zealand",
+ "Nicaragua", "Niger", "Nigeria", "Niue", "Norfolk Island", "North Korea", "Northern Marianas",
+ "Norway", "Oman", "Pakistan", "Palau", "Panama", "Papua New Guinea", "Paraguay", "Peru",
+ "Philippines", "Pitcairn Islands", "Poland", "Portugal", "Puerto Rico", "Qatar",
+ "Reunion", "Romania", "Russia", "Rwanda", "Sqo Tome and Principe", "Saint Helena",
+ "Saint Kitts and Nevis", "Saint Lucia", "Saint Pierre and Miquelon",
+ "Saint Vincent and the Grenadines", "Samoa", "San Marino", "Saudi Arabia", "Senegal",
+ "Seychelles", "Sierra Leone", "Singapore", "Slovakia", "Slovenia", "Solomon Islands",
+ "Somalia", "South Africa", "South Georgia and the South Sandwich Islands", "South Korea",
+ "Spain", "Sri Lanka", "Sudan", "Suriname", "Svalbard and Jan Mayen", "Swaziland", "Sweden",
+ "Switzerland", "Syria", "Taiwan", "Tajikistan", "Tanzania", "Thailand", "The Bahamas",
+ "The Gambia", "Togo", "Tokelau", "Tonga", "Trinidad and Tobago", "Tunisia", "Turkey",
+ "Turkmenistan", "Turks and Caicos Islands", "Tuvalu", "Virgin Islands", "Uganda",
+ "Ukraine", "United Arab Emirates", "United Kingdom",
+ "United States", "United States Minor Outlying Islands", "Uruguay", "Uzbekistan",
+ "Vanuatu", "Vatican City", "Venezuela", "Vietnam", "Wallis and Futuna", "Western Sahara",
+ "Yemen", "Yugoslavia", "Zambia", "Zimbabwe"
+ };
+}
diff --git a/vpn/java/android/net/vpn/IVpnService.aidl b/vpn/java/android/net/vpn/IVpnService.aidl
index fedccb0..6bf3edd 100644
--- a/vpn/java/android/net/vpn/IVpnService.aidl
+++ b/vpn/java/android/net/vpn/IVpnService.aidl
@@ -24,10 +24,11 @@
*/
interface IVpnService {
/**
- * Sets up the VPN connection.
+ * Sets up a VPN connection.
* @param profile the profile object
* @param username the username for authentication
* @param password the corresponding password for authentication
+ * @return true if VPN is successfully connected
*/
boolean connect(in VpnProfile profile, String username, String password);
@@ -37,7 +38,13 @@
void disconnect();
/**
- * Makes the service broadcast the connectivity state.
+ * Gets the the current connection state.
*/
- void checkStatus(in VpnProfile profile);
+ String getState(in VpnProfile profile);
+
+ /**
+ * Returns the idle state.
+ * @return true if the system is not connecting/connected to a VPN
+ */
+ boolean isIdle();
}
diff --git a/vpn/java/android/net/vpn/VpnManager.java b/vpn/java/android/net/vpn/VpnManager.java
index ce40b5d..02486bb 100644
--- a/vpn/java/android/net/vpn/VpnManager.java
+++ b/vpn/java/android/net/vpn/VpnManager.java
@@ -16,17 +16,19 @@
package android.net.vpn;
-import java.io.File;
-
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.ServiceConnection;
import android.os.Environment;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.os.ServiceManager;
import android.os.SystemProperties;
import android.util.Log;
+import com.android.server.vpn.VpnServiceBinder;
+
/**
* The class provides interface to manage all VPN-related tasks, including:
* <ul>
@@ -40,8 +42,6 @@
* {@hide}
*/
public class VpnManager {
- // Action for broadcasting a connectivity state.
- private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
/** Key to the profile name of a connectivity broadcast event. */
public static final String BROADCAST_PROFILE_NAME = "profile_name";
/** Key to the connectivity state of a connectivity broadcast event. */
@@ -74,8 +74,10 @@
private static final String PACKAGE_PREFIX =
VpnManager.class.getPackage().getName() + ".";
- // Action to start VPN service
- private static final String ACTION_VPN_SERVICE = PACKAGE_PREFIX + "SERVICE";
+ // Action for broadcasting a connectivity state.
+ private static final String ACTION_VPN_CONNECTIVITY = "vpn.connectivity";
+
+ private static final String VPN_SERVICE_NAME = "vpn";
// Action to start VPN settings
private static final String ACTION_VPN_SETTINGS =
@@ -96,13 +98,76 @@
return VpnType.values();
}
+ public static void startVpnService(Context c) {
+ ServiceManager.addService(VPN_SERVICE_NAME, new VpnServiceBinder(c));
+ }
+
private Context mContext;
+ private IVpnService mVpnService;
/**
* Creates a manager object with the specified context.
*/
public VpnManager(Context c) {
mContext = c;
+ createVpnServiceClient();
+ }
+
+ private void createVpnServiceClient() {
+ IBinder b = ServiceManager.getService(VPN_SERVICE_NAME);
+ mVpnService = IVpnService.Stub.asInterface(b);
+ }
+
+ /**
+ * Sets up a VPN connection.
+ * @param profile the profile object
+ * @param username the username for authentication
+ * @param password the corresponding password for authentication
+ * @return true if VPN is successfully connected
+ */
+ public boolean connect(VpnProfile p, String username, String password) {
+ try {
+ return mVpnService.connect(p, username, password);
+ } catch (RemoteException e) {
+ Log.e(TAG, "connect()", e);
+ return false;
+ }
+ }
+
+ /**
+ * Tears down the VPN connection.
+ */
+ public void disconnect() {
+ try {
+ mVpnService.disconnect();
+ } catch (RemoteException e) {
+ Log.e(TAG, "disconnect()", e);
+ }
+ }
+
+ /**
+ * Gets the the current connection state.
+ */
+ public VpnState getState(VpnProfile p) {
+ try {
+ return Enum.valueOf(VpnState.class, mVpnService.getState(p));
+ } catch (RemoteException e) {
+ Log.e(TAG, "getState()", e);
+ return VpnState.IDLE;
+ }
+ }
+
+ /**
+ * Returns the idle state.
+ * @return true if the system is not connecting/connected to a VPN
+ */
+ public boolean isIdle() {
+ try {
+ return mVpnService.isIdle();
+ } catch (RemoteException e) {
+ Log.e(TAG, "isIdle()", e);
+ return true;
+ }
}
/**
@@ -134,33 +199,6 @@
}
}
- /**
- * Starts the VPN service to establish VPN connection.
- */
- public void startVpnService() {
- mContext.startService(new Intent(ACTION_VPN_SERVICE));
- }
-
- /**
- * Stops the VPN service.
- */
- public void stopVpnService() {
- mContext.stopService(new Intent(ACTION_VPN_SERVICE));
- }
-
- /**
- * Binds the specified ServiceConnection with the VPN service.
- */
- public boolean bindVpnService(ServiceConnection c) {
- if (!mContext.bindService(new Intent(ACTION_VPN_SERVICE), c, 0)) {
- Log.w(TAG, "failed to connect to VPN service");
- return false;
- } else {
- Log.d(TAG, "succeeded to connect to VPN service");
- return true;
- }
- }
-
/** Broadcasts the connectivity state of the specified profile. */
public void broadcastConnectivity(String profileName, VpnState s) {
broadcastConnectivity(profileName, s, VPN_ERROR_NO_ERROR);
diff --git a/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java b/vpn/java/com/android/server/vpn/DaemonProxy.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java
rename to vpn/java/com/android/server/vpn/DaemonProxy.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java b/vpn/java/com/android/server/vpn/L2tpIpsecPskService.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java
rename to vpn/java/com/android/server/vpn/L2tpIpsecPskService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java b/vpn/java/com/android/server/vpn/L2tpIpsecService.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java
rename to vpn/java/com/android/server/vpn/L2tpIpsecService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/L2tpService.java b/vpn/java/com/android/server/vpn/L2tpService.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/L2tpService.java
rename to vpn/java/com/android/server/vpn/L2tpService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/PptpService.java b/vpn/java/com/android/server/vpn/PptpService.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/PptpService.java
rename to vpn/java/com/android/server/vpn/PptpService.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java b/vpn/java/com/android/server/vpn/VpnConnectingError.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java
rename to vpn/java/com/android/server/vpn/VpnConnectingError.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnDaemons.java b/vpn/java/com/android/server/vpn/VpnDaemons.java
similarity index 100%
rename from packages/VpnServices/src/com/android/server/vpn/VpnDaemons.java
rename to vpn/java/com/android/server/vpn/VpnDaemons.java
diff --git a/packages/VpnServices/src/com/android/server/vpn/VpnService.java b/vpn/java/com/android/server/vpn/VpnService.java
similarity index 94%
rename from packages/VpnServices/src/com/android/server/vpn/VpnService.java
rename to vpn/java/com/android/server/vpn/VpnService.java
index a618423..4966c06 100644
--- a/packages/VpnServices/src/com/android/server/vpn/VpnService.java
+++ b/vpn/java/com/android/server/vpn/VpnService.java
@@ -27,8 +27,9 @@
import android.text.TextUtils;
import android.util.Log;
+import com.android.internal.R;
+
import java.io.IOException;
-import java.io.Serializable;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.NetworkInterface;
@@ -37,8 +38,7 @@
/**
* The service base class for managing a type of VPN connection.
*/
-abstract class VpnService<E extends VpnProfile> implements Serializable {
- static final long serialVersionUID = 1L;
+abstract class VpnService<E extends VpnProfile> {
private static final boolean DBG = true;
private static final int NOTIFICATION_ID = 1;
@@ -55,10 +55,8 @@
private final String TAG = VpnService.class.getSimpleName();
- // FIXME: profile is only needed in connecting phase, so we can just save
- // the profile name and service class name for recovery
E mProfile;
- transient VpnServiceBinder mContext;
+ transient Context mContext;
private VpnState mState = VpnState.IDLE;
private Throwable mError;
@@ -105,12 +103,8 @@
return InetAddress.getByName(hostName).getHostAddress();
}
- void setContext(VpnServiceBinder context, E profile) {
+ void setContext(Context context, E profile) {
mProfile = profile;
- recover(context);
- }
-
- void recover(VpnServiceBinder context) {
mContext = context;
mNotification = new NotificationHelper();
@@ -124,6 +118,10 @@
return mState;
}
+ boolean isIdle() {
+ return (mState == VpnState.IDLE);
+ }
+
synchronized boolean onConnect(String username, String password) {
try {
setState(VpnState.CONNECTING);
@@ -216,21 +214,12 @@
mStartTime = System.currentTimeMillis();
- // Correct order to make sure VpnService doesn't break when killed:
- // (1) set state to CONNECTED
- // (2) save states
- // (3) set DNS
setState(VpnState.CONNECTED);
- saveSelf();
setVpnDns();
startConnectivityMonitor();
}
- private void saveSelf() throws IOException {
- mContext.saveStates();
- }
-
private synchronized void onFinalCleanUp() {
if (DBG) Log.d(TAG, "onFinalCleanUp()");
@@ -243,10 +232,7 @@
restoreOriginalDomainSuffices();
setState(VpnState.IDLE);
- // stop the service itself
SystemProperties.set(VPN_STATUS, VPN_IS_DOWN);
- mContext.removeStates();
- mContext.stopSelf();
}
private boolean anyError() {
@@ -413,9 +399,6 @@
}
}
- private class DaemonHelper implements Serializable {
- }
-
// Helper class for showing, updating notification.
private class NotificationHelper {
private NotificationManager mNotificationManager = (NotificationManager)
diff --git a/vpn/java/com/android/server/vpn/VpnServiceBinder.java b/vpn/java/com/android/server/vpn/VpnServiceBinder.java
new file mode 100644
index 0000000..c474ff9
--- /dev/null
+++ b/vpn/java/com/android/server/vpn/VpnServiceBinder.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (C) 2009, The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.vpn;
+
+import android.app.Service;
+import android.content.Context;
+import android.content.Intent;
+import android.net.vpn.IVpnService;
+import android.net.vpn.L2tpIpsecProfile;
+import android.net.vpn.L2tpIpsecPskProfile;
+import android.net.vpn.L2tpProfile;
+import android.net.vpn.PptpProfile;
+import android.net.vpn.VpnManager;
+import android.net.vpn.VpnProfile;
+import android.net.vpn.VpnState;
+import android.util.Log;
+
+/**
+ * The service class for managing a VPN connection. It implements the
+ * {@link IVpnService} binder interface.
+ */
+public class VpnServiceBinder extends IVpnService.Stub {
+ private static final String TAG = VpnServiceBinder.class.getSimpleName();
+ private static final boolean DBG = true;
+
+ // The actual implementation is delegated to the VpnService class.
+ private VpnService<? extends VpnProfile> mService;
+
+ private Context mContext;
+
+ public VpnServiceBinder(Context context) {
+ mContext = context;
+ }
+
+ @Override
+ public synchronized boolean connect(VpnProfile p, final String username,
+ final String password) {
+ if ((mService != null) && !mService.isIdle()) return false;
+ final VpnService s = mService = createService(p);
+
+ new Thread(new Runnable() {
+ public void run() {
+ s.onConnect(username, password);
+ }
+ }).start();
+ return true;
+ }
+
+ @Override
+ public synchronized void disconnect() {
+ if (mService == null) return;
+ final VpnService s = mService;
+ mService = null;
+
+ new Thread(new Runnable() {
+ public void run() {
+ s.onDisconnect();
+ }
+ }).start();
+ }
+
+ @Override
+ public synchronized String getState(VpnProfile p) {
+ if ((mService == null)
+ || (!p.getName().equals(mService.mProfile.getName()))) {
+ return VpnState.IDLE.toString();
+ } else {
+ return mService.getState().toString();
+ }
+ }
+
+ @Override
+ public synchronized boolean isIdle() {
+ return (mService == null || mService.isIdle());
+ }
+
+ private VpnService<? extends VpnProfile> createService(VpnProfile p) {
+ switch (p.getType()) {
+ case L2TP:
+ L2tpService l2tp = new L2tpService();
+ l2tp.setContext(mContext, (L2tpProfile) p);
+ return l2tp;
+
+ case PPTP:
+ PptpService pptp = new PptpService();
+ pptp.setContext(mContext, (PptpProfile) p);
+ return pptp;
+
+ case L2TP_IPSEC_PSK:
+ L2tpIpsecPskService psk = new L2tpIpsecPskService();
+ psk.setContext(mContext, (L2tpIpsecPskProfile) p);
+ return psk;
+
+ case L2TP_IPSEC:
+ L2tpIpsecService l2tpIpsec = new L2tpIpsecService();
+ l2tpIpsec.setContext(mContext, (L2tpIpsecProfile) p);
+ return l2tpIpsec;
+
+ default:
+ return null;
+ }
+ }
+}
diff --git a/wifi/java/android/net/wifi/SupplicantStateTracker.java b/wifi/java/android/net/wifi/SupplicantStateTracker.java
index f96a5ae..3cde949 100644
--- a/wifi/java/android/net/wifi/SupplicantStateTracker.java
+++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java
@@ -31,7 +31,7 @@
* Tracks the state changes in supplicant and provides functionality
* that is based on these state changes:
* - detect a failed WPA handshake that loops indefinitely
- * - password failure handling
+ * - authentication failure handling
*/
class SupplicantStateTracker extends HierarchicalStateMachine {
@@ -39,14 +39,14 @@
private static final boolean DBG = false;
private WifiStateMachine mWifiStateMachine;
- private int mPasswordFailuresCount = 0;
+ private int mAuthenticationFailuresCount = 0;
/* Indicates authentication failure in supplicant broadcast.
* TODO: enhance auth failure reporting to include notification
* for all type of failures: EAP, WPS & WPA networks */
private boolean mAuthFailureInSupplicantBroadcast = false;
- /* Maximum retries on a password failure notification */
- private static final int MAX_RETRIES_ON_PASSWORD_FAILURE = 2;
+ /* Maximum retries on a authentication failure notification */
+ private static final int MAX_RETRIES_ON_AUTHENTICATION_FAILURE = 2;
/* Tracks if networks have been disabled during a connection */
private boolean mNetworksDisabledDuringConnect = false;
@@ -155,8 +155,8 @@
public boolean processMessage(Message message) {
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
switch (message.what) {
- case WifiStateMachine.PASSWORD_MAY_BE_INCORRECT_EVENT:
- mPasswordFailuresCount++;
+ case WifiStateMachine.AUTHENTICATION_FAILURE_EVENT:
+ mAuthenticationFailuresCount++;
mAuthFailureInSupplicantBroadcast = true;
break;
case WifiStateMachine.SUPPLICANT_STATE_CHANGE_EVENT:
@@ -206,18 +206,17 @@
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
- /* If a disconnect event happens after password key failure
+ /* If a disconnect event happens after authentication failure
* exceeds maximum retries, disable the network
*/
-
Message message = getCurrentMessage();
StateChangeResult stateChangeResult = (StateChangeResult) message.obj;
- if (mPasswordFailuresCount >= MAX_RETRIES_ON_PASSWORD_FAILURE) {
+ if (mAuthenticationFailuresCount >= MAX_RETRIES_ON_AUTHENTICATION_FAILURE) {
Log.d(TAG, "Failed to authenticate, disabling network " +
stateChangeResult.networkId);
handleNetworkConnectionFailure(stateChangeResult.networkId);
- mPasswordFailuresCount = 0;
+ mAuthenticationFailuresCount = 0;
}
}
}
@@ -282,8 +281,8 @@
@Override
public void enter() {
if (DBG) Log.d(TAG, getName() + "\n");
- /* Reset password failure count */
- mPasswordFailuresCount = 0;
+ /* Reset authentication failure count */
+ mAuthenticationFailuresCount = 0;
if (mNetworksDisabledDuringConnect) {
WifiConfigStore.enableAllNetworks();
mNetworksDisabledDuringConnect = false;
diff --git a/wifi/java/android/net/wifi/WifiMonitor.java b/wifi/java/android/net/wifi/WifiMonitor.java
index 090ad3b..ce38261 100644
--- a/wifi/java/android/net/wifi/WifiMonitor.java
+++ b/wifi/java/android/net/wifi/WifiMonitor.java
@@ -42,7 +42,8 @@
private static final int LINK_SPEED = 5;
private static final int TERMINATING = 6;
private static final int DRIVER_STATE = 7;
- private static final int UNKNOWN = 8;
+ private static final int EAP_FAILURE = 8;
+ private static final int UNKNOWN = 9;
/** All events coming from the supplicant start with this prefix */
private static final String eventPrefix = "CTRL-EVENT-";
@@ -110,6 +111,17 @@
* <code>state</code> is either STARTED or STOPPED
*/
private static final String driverStateEvent = "DRIVER-STATE";
+ /**
+ * <pre>
+ * CTRL-EVENT-EAP-FAILURE EAP authentication failed
+ * </pre>
+ */
+ private static final String eapFailureEvent = "EAP-FAILURE";
+
+ /**
+ * This indicates an authentication failure on EAP FAILURE event
+ */
+ private static final String eapAuthFailure = "EAP authentication failed";
/**
* Regex pattern for extracting an Ethernet-style MAC address from a string.
@@ -176,7 +188,7 @@
if (!eventStr.startsWith(eventPrefix)) {
if (eventStr.startsWith(wpaEventPrefix) &&
0 < eventStr.indexOf(passwordKeyMayBeIncorrectEvent)) {
- handlePasswordKeyMayBeIncorrect();
+ mWifiStateMachine.notifyAuthenticationFailure();
} else if (eventStr.startsWith(wpsOverlapEvent)) {
mWifiStateMachine.notifyWpsOverlap();
}
@@ -207,16 +219,17 @@
event = LINK_SPEED;
else if (eventName.equals(terminatingEvent))
event = TERMINATING;
- else if (eventName.equals(driverStateEvent)) {
+ else if (eventName.equals(driverStateEvent))
event = DRIVER_STATE;
- }
+ else if (eventName.equals(eapFailureEvent))
+ event = EAP_FAILURE;
else
event = UNKNOWN;
String eventData = eventStr;
if (event == DRIVER_STATE || event == LINK_SPEED)
eventData = eventData.split(" ")[1];
- else if (event == STATE_CHANGE) {
+ else if (event == STATE_CHANGE || event == EAP_FAILURE) {
int ind = eventStr.indexOf(" ");
if (ind != -1) {
eventData = eventStr.substring(ind + 1);
@@ -261,6 +274,10 @@
// notify and exit
mWifiStateMachine.notifySupplicantLost();
break;
+ } else if (event == EAP_FAILURE) {
+ if (eventData.startsWith(eapAuthFailure)) {
+ mWifiStateMachine.notifyAuthenticationFailure();
+ }
} else {
handleEvent(event, eventData);
}
@@ -284,10 +301,6 @@
return false;
}
- private void handlePasswordKeyMayBeIncorrect() {
- mWifiStateMachine.notifyPasswordKeyMayBeIncorrect();
- }
-
private void handleDriverEvent(String state) {
if (state == null) {
return;
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 0548b4d..4d0acdd 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -61,7 +61,6 @@
import android.provider.Settings;
import android.util.EventLog;
import android.util.Log;
-import android.util.Slog;
import android.app.backup.IBackupManager;
import android.bluetooth.BluetoothAdapter;
import android.content.BroadcastReceiver;
@@ -213,8 +212,8 @@
static final int SCAN_RESULTS_EVENT = 38;
/* Supplicate state changed */
static final int SUPPLICANT_STATE_CHANGE_EVENT = 39;
- /* Password may be incorrect */
- static final int PASSWORD_MAY_BE_INCORRECT_EVENT = 40;
+ /* Password failure and EAP authentication failure */
+ static final int AUTHENTICATION_FAILURE_EVENT = 40;
/* WPS overlap detected */
static final int WPS_OVERLAP_EVENT = 41;
@@ -1384,11 +1383,12 @@
}
/**
- * Send the tracker a notification that a user-entered password key
- * may be incorrect (i.e., caused authentication to fail).
+ * Send the tracker a notification that a user provided
+ * configuration caused authentication failure - this could
+ * be a password failure or a EAP authentication failure
*/
- void notifyPasswordKeyMayBeIncorrect() {
- sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
+ void notifyAuthenticationFailure() {
+ sendMessage(AUTHENTICATION_FAILURE_EVENT);
}
/**
@@ -1516,7 +1516,7 @@
case NETWORK_DISCONNECTION_EVENT:
case SCAN_RESULTS_EVENT:
case SUPPLICANT_STATE_CHANGE_EVENT:
- case PASSWORD_MAY_BE_INCORRECT_EVENT:
+ case AUTHENTICATION_FAILURE_EVENT:
case WPS_OVERLAP_EVENT:
case CMD_BLACKLIST_NETWORK:
case CMD_CLEAR_BLACKLIST:
@@ -1671,10 +1671,18 @@
nwService.startAccessPoint((WifiConfiguration) message.obj,
mInterfaceName,
SOFTAP_IFACE);
- } catch(Exception e) {
- Log.e(TAG, "Exception in startAccessPoint()");
- sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
- break;
+ } catch (Exception e) {
+ Log.e(TAG, "Exception in softap start " + e);
+ try {
+ nwService.stopAccessPoint();
+ nwService.startAccessPoint((WifiConfiguration) message.obj,
+ mInterfaceName,
+ SOFTAP_IFACE);
+ } catch (Exception ee) {
+ Log.e(TAG, "Exception during softap restart : " + ee);
+ sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
+ break;
+ }
}
Log.d(TAG, "Soft AP start successful");
setWifiApState(WIFI_AP_STATE_ENABLED);
@@ -2060,7 +2068,7 @@
case SUPPLICANT_STATE_CHANGE_EVENT:
case NETWORK_CONNECTION_EVENT:
case NETWORK_DISCONNECTION_EVENT:
- case PASSWORD_MAY_BE_INCORRECT_EVENT:
+ case AUTHENTICATION_FAILURE_EVENT:
case WPS_OVERLAP_EVENT:
case CMD_SET_SCAN_TYPE:
case CMD_SET_HIGH_PERF_MODE:
@@ -2293,8 +2301,8 @@
if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
StateChangeResult stateChangeResult;
switch(message.what) {
- case PASSWORD_MAY_BE_INCORRECT_EVENT:
- mSupplicantStateTracker.sendMessage(PASSWORD_MAY_BE_INCORRECT_EVENT);
+ case AUTHENTICATION_FAILURE_EVENT:
+ mSupplicantStateTracker.sendMessage(AUTHENTICATION_FAILURE_EVENT);
break;
case WPS_OVERLAP_EVENT:
/* We just need to broadcast the error */
@@ -2824,13 +2832,16 @@
mInterfaceName,
SOFTAP_IFACE);
} catch(Exception e) {
- Log.e(TAG, "Exception in nwService during soft AP set");
+ Log.e(TAG, "Exception in softap set " + e);
try {
nwService.stopAccessPoint();
+ nwService.startAccessPoint((WifiConfiguration) message.obj,
+ mInterfaceName,
+ SOFTAP_IFACE);
} catch (Exception ee) {
- Slog.e(TAG, "Could not stop AP, :" + ee);
+ Log.e(TAG, "Could not restart softap after set failed " + ee);
+ sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
}
- sendMessage(obtainMessage(CMD_UNLOAD_DRIVER, WIFI_AP_STATE_FAILED, 0));
}
break;
/* Fail client mode operation when soft AP is enabled */