diff options
264 files changed, 6351 insertions, 3467 deletions
diff --git a/Android.mk b/Android.mk index 5d989d1d72fd..7728b0210c74 100644 --- a/Android.mk +++ b/Android.mk @@ -384,10 +384,10 @@ web_docs_sample_code_flags := \ -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 @@ web_docs_sample_code_flags := \ 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 1acb620bee2d..337b30f0843a 100644 --- a/CleanSpec.mk +++ b/CleanSpec.mk @@ -89,6 +89,7 @@ $(call add-clean-step, rm -rf $(OUT_DIR)/target/target/common/obj/APPS/Music2_in $(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 6c06a0afda1a..5f3cd5115bbd 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" @@ -15982,7 +16004,7 @@ type="int" transient="false" volatile="false" - value="16974069" + value="16974060" static="true" final="true" deprecated="not deprecated" @@ -16033,44 +16055,44 @@ visibility="public" > </field> -<field name="Widget_DropDownItem" +<field name="Widget_DatePicker" type="int" transient="false" volatile="false" - value="16973867" + value="16974063" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_DropDownItem_Spinner" +<field name="Widget_DropDownItem" type="int" transient="false" volatile="false" - value="16973868" + value="16973867" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_EditText" +<field name="Widget_DropDownItem_Spinner" type="int" transient="false" volatile="false" - value="16973859" + value="16973868" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_EditText_NumberPickerInputText" +<field name="Widget_EditText" type="int" transient="false" volatile="false" - value="16974061" + value="16973859" static="true" final="true" deprecated="not deprecated" @@ -16268,7 +16290,7 @@ type="int" transient="false" volatile="false" - value="16974070" + value="16974061" static="true" final="true" deprecated="not deprecated" @@ -16308,44 +16330,44 @@ visibility="public" > </field> -<field name="Widget_Holo_DropDownItem" +<field name="Widget_Holo_DatePicker" type="int" transient="false" volatile="false" - value="16973995" + value="16974064" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_Holo_DropDownItem_Spinner" +<field name="Widget_Holo_DropDownItem" type="int" transient="false" volatile="false" - value="16973996" + value="16973995" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_Holo_EditText" +<field name="Widget_Holo_DropDownItem_Spinner" type="int" transient="false" volatile="false" - value="16973972" + value="16973996" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_Holo_EditText_NumberPickerInputText" +<field name="Widget_Holo_EditText" type="int" transient="false" volatile="false" - value="16974064" + value="16973972" static="true" final="true" deprecated="not deprecated" @@ -16396,28 +16418,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 +16543,7 @@ type="int" transient="false" volatile="false" - value="16974071" + value="16974062" static="true" final="true" deprecated="not deprecated" @@ -16616,17 +16616,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 +16660,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 +17188,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" @@ -24311,6 +24256,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 +39712,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 +136067,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 +136249,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 +146694,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 +146715,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 +146792,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 +160234,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 +163345,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 +163587,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 +166514,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 +166761,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" @@ -175634,6 +175782,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 +175815,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 +206417,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 +206476,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 +219566,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 +231426,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 +236237,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 +240675,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 +240941,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 +249500,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 +249607,7 @@ > </field> </interface> -<interface name="NumberPicker.OnValueChangedListener" +<interface name="NumberPicker.OnValueChangeListener" abstract="true" static="true" final="false" @@ -252338,21 +252571,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"> diff --git a/api/current.xml b/api/current.xml index 73581f16e829..5f3cd5115bbd 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" @@ -15993,7 +16004,7 @@ type="int" transient="false" volatile="false" - value="16974069" + value="16974060" static="true" final="true" deprecated="not deprecated" @@ -16044,44 +16055,44 @@ visibility="public" > </field> -<field name="Widget_DropDownItem" +<field name="Widget_DatePicker" type="int" transient="false" volatile="false" - value="16973867" + value="16974063" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_DropDownItem_Spinner" +<field name="Widget_DropDownItem" type="int" transient="false" volatile="false" - value="16973868" + value="16973867" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_EditText" +<field name="Widget_DropDownItem_Spinner" type="int" transient="false" volatile="false" - value="16973859" + value="16973868" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_EditText_NumberPickerInputText" +<field name="Widget_EditText" type="int" transient="false" volatile="false" - value="16974061" + value="16973859" static="true" final="true" deprecated="not deprecated" @@ -16279,7 +16290,7 @@ type="int" transient="false" volatile="false" - value="16974070" + value="16974061" static="true" final="true" deprecated="not deprecated" @@ -16319,44 +16330,44 @@ visibility="public" > </field> -<field name="Widget_Holo_DropDownItem" +<field name="Widget_Holo_DatePicker" type="int" transient="false" volatile="false" - value="16973995" + value="16974064" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_Holo_DropDownItem_Spinner" +<field name="Widget_Holo_DropDownItem" type="int" transient="false" volatile="false" - value="16973996" + value="16973995" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_Holo_EditText" +<field name="Widget_Holo_DropDownItem_Spinner" type="int" transient="false" volatile="false" - value="16973972" + value="16973996" static="true" final="true" deprecated="not deprecated" visibility="public" > </field> -<field name="Widget_Holo_EditText_NumberPickerInputText" +<field name="Widget_Holo_EditText" type="int" transient="false" volatile="false" - value="16974064" + value="16973972" static="true" final="true" deprecated="not deprecated" @@ -16407,28 +16418,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 +16543,7 @@ type="int" transient="false" volatile="false" - value="16974071" + value="16974062" static="true" final="true" deprecated="not deprecated" @@ -16627,17 +16616,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 +16660,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 +17188,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" @@ -39778,6 +39712,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 +146715,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 +160234,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 +163345,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 +163587,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 +166514,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 +166761,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" @@ -206342,25 +206417,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 +206476,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 +231426,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 +240675,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 +240941,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 +249500,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 +249607,7 @@ > </field> </interface> -<interface name="NumberPicker.OnValueChangedListener" +<interface name="NumberPicker.OnValueChangeListener" abstract="true" static="true" final="false" @@ -252483,21 +252571,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"> @@ -260298,7 +260371,7 @@ deprecated="not deprecated" visibility="public" > -<parameter name="t" type="T"> +<parameter name="arg0" type="T"> </parameter> </method> </interface> diff --git a/build/phone-hdpi-512-dalvik-heap.mk b/build/phone-hdpi-512-dalvik-heap.mk index afc45ee11486..630cf035a741 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 ee30b92079cd..ab33b9654bed 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 9cb2f6bdebc1..37c3ec531a80 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 e6eaf71634aa..2c99f14d2554 100644 --- a/core/java/android/accounts/AccountManagerService.java +++ b/core/java/android/accounts/AccountManagerService.java @@ -722,6 +722,9 @@ public class AccountManagerService 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 @@ public class AccountManagerService 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 b66669b49018..ff4326092c41 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/Activity.java b/core/java/android/app/Activity.java index 0a640708a02f..2aef860a62b0 100644 --- a/core/java/android/app/Activity.java +++ b/core/java/android/app/Activity.java @@ -1762,8 +1762,11 @@ public class Activity extends ContextThemeWrapper /** * 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 +1776,17 @@ public class Activity extends ContextThemeWrapper /** * 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 +1796,13 @@ public class Activity extends ContextThemeWrapper /** * 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 +4447,9 @@ public class Activity extends ContextThemeWrapper 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 d5aa9619962c..133a7d04003f 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -64,8 +64,11 @@ public class ActivityManager { 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 db046ef73597..7cf60f99efbd 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -3463,7 +3463,7 @@ public final class ActivityThread { } 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/Notification.java b/core/java/android/app/Notification.java index 0243b02524e4..de84c566e5f7 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -34,6 +34,9 @@ import java.text.NumberFormat; * 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 @@ public class Notification implements Parcelable /** * 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 @@ public class Notification implements Parcelable /** * 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable 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 @@ public class Notification implements Parcelable } } + /** + * 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/appwidget/AppWidgetProviderInfo.java b/core/java/android/appwidget/AppWidgetProviderInfo.java index a3db01dfe683..fe33782f6e2d 100644 --- a/core/java/android/appwidget/AppWidgetProviderInfo.java +++ b/core/java/android/appwidget/AppWidgetProviderInfo.java @@ -121,8 +121,6 @@ public class AppWidgetProviderInfo implements Parcelable { * * <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/BluetoothInputDevice.java b/core/java/android/bluetooth/BluetoothInputDevice.java index bc8a836183bc..a70de59a48f6 100644 --- a/core/java/android/bluetooth/BluetoothInputDevice.java +++ b/core/java/android/bluetooth/BluetoothInputDevice.java @@ -85,6 +85,19 @@ public final class BluetoothInputDevice { */ 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 7dee25e4afa8..1f07349b4c13 100644 --- a/core/java/android/bluetooth/BluetoothPan.java +++ b/core/java/android/bluetooth/BluetoothPan.java @@ -70,6 +70,19 @@ public final class BluetoothPan { 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/os/StrictMode.java b/core/java/android/os/StrictMode.java index 997ea53cfc97..ae92b09ed484 100644 --- a/core/java/android/os/StrictMode.java +++ b/core/java/android/os/StrictMode.java @@ -30,6 +30,7 @@ import com.android.internal.os.RuntimeInit; import dalvik.system.BlockGuard; import dalvik.system.CloseGuard; +import dalvik.system.VMDebug; import java.io.PrintWriter; import java.io.StringWriter; @@ -184,6 +185,15 @@ public final class StrictMode { /** * @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: @@ -573,11 +583,15 @@ public final class StrictMode { } 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 +599,8 @@ public final class StrictMode { * 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 | @@ -1347,6 +1361,41 @@ public final class StrictMode { } /** + * @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 (Class klass : policy.classInstanceLimit.keySet()) { + int limit = policy.classInstanceLimit.get(klass); + 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 sProcessIdleHandler + 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. @@ -1357,6 +1406,19 @@ public final class StrictMode { sVmPolicy = policy; sVmPolicyMask = policy.mask; setCloseGuardEnabled(vmClosableObjectLeaksEnabled()); + + Looper looper = Looper.getMainLooper(); + if (looper != null) { + MessageQueue mq = looper.mQueue; + synchronized (sProcessIdleHandler) { + if (policy.classInstanceLimit.size() == 0) { + mq.removeIdleHandler(sProcessIdleHandler); + } else if (!sIsIdlerRegistered) { + mq.addIdleHandler(sProcessIdleHandler); + sIsIdlerRegistered = true; + } + } + } } /** @@ -1406,19 +1468,39 @@ public final class StrictMode { 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) { - Log.e(TAG, message, originStack); + 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); + + 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); + } } - boolean penaltyDropbox = (sVmPolicyMask & PENALTY_DROPBOX) != 0; - boolean penaltyDeath = (sVmPolicyMask & PENALTY_DEATH) != 0; + Log.d(TAG, "Time since last vm violation: " + timeSinceLastViolationMillis); - int violationMaskSubset = PENALTY_DROPBOX | DETECT_VM_CURSOR_LEAKS; - ViolationInfo info = new ViolationInfo(originStack, sVmPolicyMask); + if (penaltyLog && timeSinceLastViolationMillis > MIN_LOG_INTERVAL_MS) { + Log.e(TAG, message, originStack); + } + + int violationMaskSubset = PENALTY_DROPBOX | (ALL_VM_DETECT_BITS & sVmPolicyMask); if (penaltyDropbox && !penaltyDeath) { // Common case for userdebug/eng builds. If no death and @@ -1428,7 +1510,7 @@ public final class StrictMode { 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 @@ -1786,6 +1868,12 @@ public final class StrictMode { 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 +1894,9 @@ public final class StrictMode { 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 +1958,7 @@ public final class StrictMode { violationNumThisLoop = in.readInt(); numAnimationsRunning = in.readInt(); violationUptimeMillis = in.readLong(); + numInstances = in.readLong(); broadcastIntentAction = in.readString(); tags = in.readStringArray(); } @@ -1881,6 +1973,7 @@ public final class StrictMode { dest.writeInt(violationNumThisLoop); dest.writeInt(numAnimationsRunning); dest.writeLong(violationUptimeMillis); + dest.writeLong(numInstances); dest.writeString(broadcastIntentAction); dest.writeStringArray(tags); } @@ -1895,6 +1988,9 @@ public final class StrictMode { 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 +2010,29 @@ public final class StrictMode { } } + + // 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[1]; + static { + FAKE_STACK[0] = new StackTraceElement("android.os.StrictMode", "setClassInstanceLimit", + "StrictMode.java", 1); + } + + public InstanceCountViolation(Class klass, long instances, int limit) { + // Note: now including instances here, otherwise signatures would all be different. + super(klass.toString() + "; limit=" + limit); + setStackTrace(FAKE_STACK); + mClass = klass; + mInstances = instances; + mLimit = limit; + } + } } diff --git a/core/java/android/provider/MediaStore.java b/core/java/android/provider/MediaStore.java index 9f0ea325b3c0..82fe7dede98d 100644 --- a/core/java/android/provider/MediaStore.java +++ b/core/java/android/provider/MediaStore.java @@ -57,6 +57,8 @@ public final class MediaStore { * 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 cec99e96b7be..6f23215bb676 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -280,18 +280,25 @@ public final class Settings { "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 final class Settings { 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 539a696bdb8e..cd3bc3e7c32a 100644 --- a/core/java/android/server/BluetoothEventLoop.java +++ b/core/java/android/server/BluetoothEventLoop.java @@ -748,9 +748,9 @@ class BluetoothEventLoop { } } - 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 @@ class BluetoothEventLoop { 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 @@ class BluetoothEventLoop { } } - 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 @@ class BluetoothEventLoop { 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/view/DragEvent.java b/core/java/android/view/DragEvent.java index 6634f008ecc0..25b680e65b94 100644 --- a/core/java/android/view/DragEvent.java +++ b/core/java/android/view/DragEvent.java @@ -274,7 +274,7 @@ public static final int ACTION_DRAG_EXITED = 6; 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 99b686e075d0..d82f051eebd4 100644 --- a/core/java/android/view/GLES20Canvas.java +++ b/core/java/android/view/GLES20Canvas.java @@ -452,11 +452,14 @@ class GLES20Canvas extends HardwareCanvas { @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 @@ class GLES20Canvas extends HardwareCanvas { @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, @@ -629,9 +635,13 @@ class GLES20Canvas extends HardwareCanvas { @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 +777,15 @@ class GLES20Canvas extends HardwareCanvas { @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 7ca5a1917f40..3ff7fcd6d778 100644 --- a/core/java/android/view/KeyCharacterMap.java +++ b/core/java/android/view/KeyCharacterMap.java @@ -170,7 +170,7 @@ public class KeyCharacterMap { * * @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 @@ public class KeyCharacterMap { /** * 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 ecf1aefc935e..941331a224dc 100755 --- a/core/java/android/view/KeyEvent.java +++ b/core/java/android/view/KeyEvent.java @@ -2163,7 +2163,7 @@ public class KeyEvent extends InputEvent implements Parcelable { * 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 270ea7689e1a..2447f8cd986f 100644 --- a/core/java/android/view/View.java +++ b/core/java/android/view/View.java @@ -58,7 +58,6 @@ import android.util.PoolableManager; 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; diff --git a/core/java/android/view/ViewGroup.java b/core/java/android/view/ViewGroup.java index d1781cc0d96c..115431e2fac6 100644 --- a/core/java/android/view/ViewGroup.java +++ b/core/java/android/view/ViewGroup.java @@ -935,15 +935,17 @@ public abstract class ViewGroup extends View implements ViewParent, ViewManager } 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 961b633170d8..97983ba050ca 100644 --- a/core/java/android/view/ViewRoot.java +++ b/core/java/android/view/ViewRoot.java @@ -489,17 +489,17 @@ public final class ViewRoot extends Handler implements ViewParent, // 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); @@ -2803,6 +2803,7 @@ public final class ViewRoot extends Handler implements ViewParent, // 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); diff --git a/core/java/android/view/VolumePanel.java b/core/java/android/view/VolumePanel.java index e21824e0647d..e447dbb8a5f2 100644 --- a/core/java/android/view/VolumePanel.java +++ b/core/java/android/view/VolumePanel.java @@ -284,10 +284,11 @@ public class VolumePanel extends Handler 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 @@ public class VolumePanel extends Handler 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 c54a3cf15310..8eb42690229c 100644 --- a/core/java/android/view/WindowManager.java +++ b/core/java/android/view/WindowManager.java @@ -817,7 +817,7 @@ public interface WindowManager extends ViewManager { 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 defd104510bb..32eec9fa0e55 100644 --- a/core/java/android/view/inputmethod/InputMethodInfo.java +++ b/core/java/android/view/inputmethod/InputMethodInfo.java @@ -265,10 +265,19 @@ public final class InputMethodInfo implements Parcelable { } /** - * 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/webkit/BrowserFrame.java b/core/java/android/webkit/BrowserFrame.java index e246717b7241..ec3c32971c26 100644 --- a/core/java/android/webkit/BrowserFrame.java +++ b/core/java/android/webkit/BrowserFrame.java @@ -1177,6 +1177,17 @@ class BrowserFrame extends Handler { 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 6073f7a92414..a553a4592720 100644 --- a/core/java/android/webkit/CacheManager.java +++ b/core/java/android/webkit/CacheManager.java @@ -244,6 +244,9 @@ public final class CacheManager { * 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 @@ public final class CacheManager { 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/WebView.java b/core/java/android/webkit/WebView.java index 9e09c286f1d0..f5ad6feb0fac 100644 --- a/core/java/android/webkit/WebView.java +++ b/core/java/android/webkit/WebView.java @@ -408,10 +408,13 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 class WebView extends AbsoluteLayout */ 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 @@ public class WebView extends AbsoluteLayout * @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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout * (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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout mTouchMode = TOUCH_DRAG_MODE; mLastTouchX = x; mLastTouchY = y; - fDeltaX = 0.0f; - fDeltaY = 0.0f; deltaX = 0; deltaY = 0; @@ -5619,9 +5635,7 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout // 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 @@ public class WebView extends AbsoluteLayout cancelLongPress(); mPrivateHandler.removeMessages(SWITCH_TO_LONGPRESS); if (!mZoomManager.supportsPanDuringZoom()) { - return false; + return; } mTouchMode = TOUCH_DRAG_MODE; if (mVelocityTracker == null) { @@ -5937,16 +5945,17 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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 @@ public class WebView extends AbsoluteLayout 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); @@ -6630,8 +6639,8 @@ public class WebView extends AbsoluteLayout 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 +6699,8 @@ public class WebView extends AbsoluteLayout 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 +7061,8 @@ public class WebView extends AbsoluteLayout || (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 +7113,8 @@ public class WebView extends AbsoluteLayout 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 diff --git a/core/java/android/webkit/WebViewCore.java b/core/java/android/webkit/WebViewCore.java index c56f25270c6c..4fe16781027c 100644 --- a/core/java/android/webkit/WebViewCore.java +++ b/core/java/android/webkit/WebViewCore.java @@ -1770,7 +1770,7 @@ final class WebViewCore { private void clearCache(boolean includeDiskFiles) { mBrowserFrame.clearCache(); - if (includeDiskFiles && !JniUtil.useChromiumHttpStack()) { + if (includeDiskFiles) { CacheManager.removeAllCacheFiles(); } } diff --git a/core/java/android/widget/AdapterViewAnimator.java b/core/java/android/widget/AdapterViewAnimator.java index c27082f928f9..4c1279ff1e0c 100644 --- a/core/java/android/widget/AdapterViewAnimator.java +++ b/core/java/android/widget/AdapterViewAnimator.java @@ -981,11 +981,21 @@ public abstract class AdapterViewAnimator extends AdapterView<Adapter> // 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 772168863775..273c2588e90c 100644 --- a/core/java/android/widget/AdapterViewFlipper.java +++ b/core/java/android/widget/AdapterViewFlipper.java @@ -258,8 +258,14 @@ public class AdapterViewFlipper extends AdapterViewAnimator { } }; + /** + * 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 bb162de98a9e..dc13ebb7764f 100644 --- a/core/java/android/widget/Advanceable.java +++ b/core/java/android/widget/Advanceable.java @@ -34,5 +34,5 @@ public interface Advanceable { * 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 b4ece241ec03..593cb59c9fbb 100644 --- a/core/java/android/widget/ArrayAdapter.java +++ b/core/java/android/widget/ArrayAdapter.java @@ -25,9 +25,9 @@ import android.view.ViewGroup; 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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { 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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { * @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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { * @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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { * @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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { * @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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { * @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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { * 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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { * 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 @@ public class ArrayAdapter<T> extends BaseAdapter implements Filterable { 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 4d8d21f4a3e0..707b92d5c164 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.CompletionInfo; 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 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe 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 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe 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 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe mBlockCompletion = true; replaceText(convertSelectionToString(selectedItem)); - mBlockCompletion = false; + mBlockCompletion = false; if (mItemClickListener != null) { final ListPopupWindow list = mPopup; @@ -903,10 +908,10 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe /** {@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 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe 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 @@ public class AutoCompleteTextView extends EditText implements Filter.FilterListe // 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 2c530050e736..f1786e28c501 100644 --- a/core/java/android/widget/DatePicker.java +++ b/core/java/android/widget/DatePicker.java @@ -30,7 +30,7 @@ import android.util.AttributeSet; 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 class DatePicker extends FrameLayout { } 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 f6b1dbc99b40..db22a0cb1e31 100644 --- a/core/java/android/widget/HorizontalScrollView.java +++ b/core/java/android/widget/HorizontalScrollView.java @@ -511,8 +511,10 @@ public class HorizontalScrollView extends FrameLayout { 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 @@ public class HorizontalScrollView extends FrameLayout { } // 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 63dbfbfc0352..08db2071da44 100644 --- a/core/java/android/widget/NumberPicker.java +++ b/core/java/android/widget/NumberPicker.java @@ -32,6 +32,7 @@ import android.graphics.Color; 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.TextUtils; 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.VelocityTracker; 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 @@ import android.view.inputmethod.InputMethodManager; * <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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { /** * 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { // 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { // 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(); + + 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 - public void onWindowFocusChanged(boolean hasWindowFocus) { - super.onWindowFocusChanged(hasWindowFocus); - if (!hasWindowFocus) { - removeAllCallbacks(); - } + 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { @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 @@ public class NumberPicker extends LinearLayout { * * @param onValueChangedListener The listener. */ - public void setOnValueChangedListener(OnValueChangedListener onValueChangedListener) { - mOnValueChangedListener = onValueChangedListener; + public void setOnValueChangedListener(OnValueChangeListener onValueChangedListener) { + mOnValueChangeListener = onValueChangedListener; } /** @@ -813,6 +839,7 @@ public class NumberPicker extends LinearLayout { } mFormatter = formatter; resetSelectorWheelIndices(); + updateInputTextView(); } /** @@ -1021,6 +1048,17 @@ public class NumberPicker extends LinearLayout { } @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 @@ public class NumberPicker extends LinearLayout { // 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { 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 @@ public class NumberPicker extends LinearLayout { /** * 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 @@ public class NumberPicker extends LinearLayout { /** * 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 @@ public class NumberPicker extends LinearLayout { * 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 @@ public class NumberPicker extends LinearLayout { mPreviousScrollerY = 0; if (mInitialScrollOffset == mCurrentScrollOffset) { updateInputTextView(); - showInputControls(); + showInputControls(mShowInputControlsAnimimationDuration); return; } // adjust to the closest value @@ -1546,9 +1623,7 @@ public class NumberPicker extends LinearLayout { 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 79d6a81d2461..439e0cabe19f 100644 --- a/core/java/android/widget/PopupWindow.java +++ b/core/java/android/widget/PopupWindow.java @@ -28,7 +28,6 @@ import android.graphics.drawable.StateListDrawable; 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 @@ public class PopupWindow { 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 c336ccbbd988..482ce56f83ae 100644 --- a/core/java/android/widget/RemoteViews.java +++ b/core/java/android/widget/RemoteViews.java @@ -1277,18 +1277,6 @@ public class RemoteViews implements Parcelable, Filter { /** * 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 16126aad1c94..e5a3de28ca62 100644 --- a/core/java/android/widget/RemoteViewsService.java +++ b/core/java/android/widget/RemoteViewsService.java @@ -42,7 +42,7 @@ public abstract class RemoteViewsService extends Service { /** * 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 @@ public abstract class RemoteViewsService extends Service { * 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 8558c70e40de..ce6da72a2c98 100644 --- a/core/java/android/widget/ScrollView.java +++ b/core/java/android/widget/ScrollView.java @@ -521,8 +521,10 @@ public class ScrollView extends FrameLayout { 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 @@ public class ScrollView extends FrameLayout { } // Remember where the motion event started - mLastMotionY = y; + mLastMotionY = ev.getY(); mActivePointerId = ev.getPointerId(0); break; } diff --git a/core/java/android/widget/StackView.java b/core/java/android/widget/StackView.java index 2c100773951c..22edf6d5f68f 100644 --- a/core/java/android/widget/StackView.java +++ b/core/java/android/widget/StackView.java @@ -347,6 +347,9 @@ public class StackView extends AdapterViewAnimator { } } + /** + * {@inheritDoc} + */ @Override @android.view.RemotableViewMethod public void showNext() { @@ -362,6 +365,9 @@ public class StackView extends AdapterViewAnimator { super.showNext(); } + /** + * {@inheritDoc} + */ @Override @android.view.RemotableViewMethod public void showPrevious() { @@ -474,6 +480,9 @@ public class StackView extends AdapterViewAnimator { } } + /** + * {@inheritDoc} + */ @Override public boolean onInterceptTouchEvent(MotionEvent ev) { int action = ev.getAction(); @@ -561,6 +570,9 @@ public class StackView extends AdapterViewAnimator { } } + /** + * {@inheritDoc} + */ @Override public boolean onTouchEvent(MotionEvent ev) { super.onTouchEvent(ev); @@ -939,6 +951,9 @@ public class StackView extends AdapterViewAnimator { } } + /** + * {@inheritDoc} + */ @Override public void onRemoteAdapterConnected() { super.onRemoteAdapterConnected(); diff --git a/core/java/android/widget/SuggestionsAdapter.java b/core/java/android/widget/SuggestionsAdapter.java index 1ebe62294f79..2cfc0169a46e 100644 --- a/core/java/android/widget/SuggestionsAdapter.java +++ b/core/java/android/widget/SuggestionsAdapter.java @@ -78,15 +78,15 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene // 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 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene 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 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene } private Drawable getIcon1(Cursor cursor) { - if (mIconName1Col < 0) { + if (mIconName1Col == INVALID_INDEX) { return null; } String value = cursor.getString(mIconName1Col); @@ -403,7 +403,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene } private Drawable getIcon2(Cursor cursor) { - if (mIconName2Col < 0) { + if (mIconName2Col == INVALID_INDEX) { return null; } String value = cursor.getString(mIconName2Col); @@ -687,7 +687,7 @@ class SuggestionsAdapter extends ResourceCursorAdapter implements OnClickListene } 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 1895d793de13..d09e52f7ba8b 100644 --- a/core/java/android/widget/TextView.java +++ b/core/java/android/widget/TextView.java @@ -3426,8 +3426,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 +3449,7 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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 +3477,8 @@ public class TextView extends View implements ViewTreeObserver.OnPreDrawListener 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), diff --git a/core/java/android/widget/TimePicker.java b/core/java/android/widget/TimePicker.java index 8f3442e4d6f5..2688b952a72a 100644 --- a/core/java/android/widget/TimePicker.java +++ b/core/java/android/widget/TimePicker.java @@ -20,61 +20,67 @@ import com.android.internal.R; 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 class TimePicker extends FrameLayout { 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 @@ public class TimePicker extends FrameLayout { /* 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 @@ public class TimePicker extends FrameLayout { } 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 @@ public class TimePicker extends FrameLayout { 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 @@ public class TimePicker extends FrameLayout { mHour = hour; mMinute = minute; } - + private SavedState(Parcel in) { super(in); mHour = in.readInt(); @@ -244,8 +287,7 @@ public class TimePicker extends FrameLayout { } @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 @@ public class TimePicker extends FrameLayout { @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 @@ public class TimePicker extends FrameLayout { /** * 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 @@ public class TimePicker extends FrameLayout { } /** - * @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 class TimePicker extends FrameLayout { 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 @@ public class TimePicker extends FrameLayout { 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 @@ public class TimePicker extends FrameLayout { 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 a8f9f62222c2..6a7db1f0b83c 100644 --- a/core/java/android/widget/Toast.java +++ b/core/java/android/widget/Toast.java @@ -33,8 +33,6 @@ import android.view.WindowManagerImpl; import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; -import java.lang.ref.WeakReference; - /** * A toast is a view containing a quick little message for the user. The toast class * helps you create and show those. @@ -72,11 +70,6 @@ public class Toast { 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,8 +81,8 @@ public class Toast { */ public Toast(Context context) { mContext = context; - mTN = new TN(this); - mY = context.getResources().getDimensionPixelSize( + mTN = new TN(); + mTN.mY = context.getResources().getDimensionPixelSize( com.android.internal.R.dimen.toast_y_offset); } @@ -103,9 +96,11 @@ public class Toast { INotificationManager service = getService(); String pkg = mContext.getPackageName(); + TN tn = mTN; + tn.mNextView = mNextView; try { - service.enqueueToast(pkg, mTN, mDuration); + service.enqueueToast(pkg, tn, mDuration); } catch (RemoteException e) { // Empty } @@ -165,22 +160,22 @@ public class Toast { * 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; } /** @@ -189,9 +184,9 @@ public class Toast { * @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; } /** @@ -200,21 +195,21 @@ public class Toast { * @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; } /** @@ -281,21 +276,6 @@ public class Toast { 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. @@ -312,8 +292,6 @@ public class Toast { } private static class TN extends ITransientNotification.Stub { - final Handler mHandler = new Handler(); - final Runnable mShow = new Runnable() { public void run() { handleShow(); @@ -327,12 +305,20 @@ public class Toast { }; private final WindowManager.LayoutParams mParams = new WindowManager.LayoutParams(); - private final WeakReference<Toast> mToast; + 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; - TN(Toast toast) { - mToast = new WeakReference<Toast>(toast); + TN() { // XXX This should be changed to use a Dialog, with a Theme.Toast // defined that sets up the layout params appropriately. final WindowManager.LayoutParams params = mParams; @@ -364,53 +350,64 @@ public class Toast { } public void handleShow() { - final Toast toast = mToast.get(); - if (toast != null) { - if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + toast.mView - + " mNextView=" + toast.mNextView); - if (toast.mView != toast.mNextView) { - // remove the old view if necessary - handleHide(); - toast.mView = toast.mNextView; - mWM = WindowManagerImpl.getDefault(); - final int gravity = toast.mGravity; - mParams.gravity = gravity; - if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { - mParams.horizontalWeight = 1.0f; - } - if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { - mParams.verticalWeight = 1.0f; - } - mParams.x = toast.mX; - mParams.y = toast.mY; - mParams.verticalMargin = toast.mVerticalMargin; - mParams.horizontalMargin = toast.mHorizontalMargin; - if (toast.mView.getParent() != null) { - if (localLOGV) Log.v(TAG, "REMOVE! " + toast.mView + " in " + this); - mWM.removeView(toast.mView); - } - if (localLOGV) Log.v(TAG, "ADD! " + toast.mView + " in " + this); - mWM.addView(toast.mView, mParams); - toast.trySendAccessibilityEvent(); + if (localLOGV) Log.v(TAG, "HANDLE SHOW: " + this + " mView=" + mView + + " mNextView=" + mNextView); + if (mView != mNextView) { + // remove the old view if necessary + handleHide(); + mView = mNextView; + mWM = WindowManagerImpl.getDefault(); + final int gravity = mGravity; + mParams.gravity = gravity; + if ((gravity & Gravity.HORIZONTAL_GRAVITY_MASK) == Gravity.FILL_HORIZONTAL) { + mParams.horizontalWeight = 1.0f; + } + if ((gravity & Gravity.VERTICAL_GRAVITY_MASK) == Gravity.FILL_VERTICAL) { + mParams.verticalWeight = 1.0f; + } + mParams.x = mX; + mParams.y = mY; + mParams.verticalMargin = mVerticalMargin; + mParams.horizontalMargin = mHorizontalMargin; + if (mView.getParent() != null) { + if (localLOGV) Log.v(TAG, "REMOVE! " + mView + " in " + this); + mWM.removeView(mView); } + if (localLOGV) Log.v(TAG, "ADD! " + mView + " in " + this); + mWM.addView(mView, mParams); + trySendAccessibilityEvent(); } } + 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() { - final Toast toast = mToast.get(); - if (toast != null) { - if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + toast.mView); - if (toast.mView != null) { - // note: checking parent() just to make sure the view has - // 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 (toast.mView.getParent() != null) { - if (localLOGV) Log.v(TAG, "REMOVE! " + toast.mView + " in " + this); - mWM.removeView(toast.mView); - } - - toast.mView = null; + if (localLOGV) Log.v(TAG, "HANDLE HIDE: " + this + " mView=" + mView); + if (mView != null) { + // note: checking parent() just to make sure the view has + // 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); + mWM.removeView(mView); } + + mView = null; + mNextView = null; } } } diff --git a/core/java/com/android/internal/widget/EditableInputConnection.java b/core/java/com/android/internal/widget/EditableInputConnection.java index 6a1beb422f36..e992e7c40ab1 100644 --- a/core/java/com/android/internal/widget/EditableInputConnection.java +++ b/core/java/com/android/internal/widget/EditableInputConnection.java @@ -142,10 +142,6 @@ public class EditableInputConnection extends BaseInputConnection { 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/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp index f023e9469578..342b8840ed51 100644 --- a/core/jni/AndroidRuntime.cpp +++ b/core/jni/AndroidRuntime.cpp @@ -568,6 +568,7 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) 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 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv) 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 c43b5ce14eb1..24452292ab62 100644 --- a/core/jni/android/graphics/Region.cpp +++ b/core/jni/android/graphics/Region.cpp @@ -154,6 +154,16 @@ static void Region_scale(JNIEnv* env, jobject region, jfloat scale, jobject dst) 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 @@ static JNINativeMethod gRegionMethods[] = { { "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 9222e1a7b61c..3364703d49e9 100644 --- a/core/jni/android_bluetooth_common.h +++ b/core/jni/android_bluetooth_common.h @@ -38,6 +38,7 @@ namespace android { #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 @@ void get_bdaddr_as_string(const bdaddr_t *ba, char *str); 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 b0ba6955c3b6..fd12c2d736f8 100644 --- a/core/jni/android_server_BluetoothEventLoop.cpp +++ b/core/jni/android_server_BluetoothEventLoop.cpp @@ -134,11 +134,11 @@ static void classInitNative(JNIEnv* env, jclass clazz) { 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 @@ success: #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 @@ void onInputDeviceConnectionResult(DBusMessage *msg, void *user, void *n) { 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 @@ void onPanDeviceConnectionResult(DBusMessage *msg, void *user, void *n) { 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_view_GLES20Canvas.cpp b/core/jni/android_view_GLES20Canvas.cpp index ac491ea25a5e..bfd2b58e8b86 100644 --- a/core/jni/android_view_GLES20Canvas.cpp +++ b/core/jni/android_view_GLES20Canvas.cpp @@ -299,6 +299,17 @@ static void android_view_GLES20Canvas_drawRect(JNIEnv* env, jobject canvas, 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); @@ -570,6 +581,8 @@ static JNINativeMethod gMethods[] = { { "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/res/drawable-hdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png Binary files differnew file mode 100644 index 000000000000..7719df8a4e83 --- /dev/null +++ b/core/res/res/drawable-hdpi/numberpicker_selection_divider.9.png diff --git a/packages/VpnServices/res/drawable/vpn_connected.png b/core/res/res/drawable-hdpi/vpn_connected.png Binary files differindex 65fc6db787bf..65fc6db787bf 100644 --- a/packages/VpnServices/res/drawable/vpn_connected.png +++ b/core/res/res/drawable-hdpi/vpn_connected.png diff --git a/packages/VpnServices/res/drawable/vpn_disconnected.png b/core/res/res/drawable-hdpi/vpn_disconnected.png Binary files differindex 2440c6909ef5..2440c6909ef5 100644 --- a/packages/VpnServices/res/drawable/vpn_disconnected.png +++ b/core/res/res/drawable-hdpi/vpn_disconnected.png diff --git a/core/res/res/drawable-ldpi/vpn_connected.png b/core/res/res/drawable-ldpi/vpn_connected.png Binary files differnew file mode 100644 index 000000000000..65fc6db787bf --- /dev/null +++ b/core/res/res/drawable-ldpi/vpn_connected.png diff --git a/core/res/res/drawable-ldpi/vpn_disconnected.png b/core/res/res/drawable-ldpi/vpn_disconnected.png Binary files differnew file mode 100644 index 000000000000..2440c6909ef5 --- /dev/null +++ b/core/res/res/drawable-ldpi/vpn_disconnected.png diff --git a/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png Binary files differnew file mode 100644 index 000000000000..a933d9a6c939 --- /dev/null +++ b/core/res/res/drawable-mdpi/numberpicker_selection_divider.9.png 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 Binary files differnew file mode 100644 index 000000000000..137923b4a224 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_bg_activated_holo_dark.9.png 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 Binary files differnew file mode 100644 index 000000000000..62b1debdccec --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_bg_default_holo_dark.9.png 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 Binary files differnew file mode 100644 index 000000000000..ab30a7728bea --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_bg_disabled_focused_holo_dark.9.png 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 Binary files differnew file mode 100644 index 000000000000..9274bc720c2f --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_bg_disabled_holo_dark.9.png 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 Binary files differnew file mode 100644 index 000000000000..e46155e07064 --- /dev/null +++ b/core/res/res/drawable-mdpi/textfield_bg_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/vpn_connected.png b/core/res/res/drawable-mdpi/vpn_connected.png Binary files differnew file mode 100644 index 000000000000..65fc6db787bf --- /dev/null +++ b/core/res/res/drawable-mdpi/vpn_connected.png diff --git a/core/res/res/drawable-mdpi/vpn_disconnected.png b/core/res/res/drawable-mdpi/vpn_disconnected.png Binary files differnew file mode 100644 index 000000000000..2440c6909ef5 --- /dev/null +++ b/core/res/res/drawable-mdpi/vpn_disconnected.png 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 Binary files differnew file mode 100644 index 000000000000..0fbdbfa061fb --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal.9.png 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 Binary files differnew file mode 100644 index 000000000000..ae9745374304 --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_off.9.png 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 Binary files differnew file mode 100644 index 000000000000..4127d1ee7274 --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_normal_on.9.png 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 Binary files differnew file mode 100644 index 000000000000..525ab8a40f19 --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed.9.png 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 Binary files differnew file mode 100644 index 000000000000..eb05820ded0a --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_off.9.png 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 Binary files differnew file mode 100644 index 000000000000..416b2c7295b0 --- /dev/null +++ b/core/res/res/drawable-xlarge-mdpi/btn_keyboard_key_fulltrans_pressed_on.9.png 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 000000000000..92ceb79fc7f0 --- /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/keyguard_screen_password_landscape.xml b/core/res/res/layout-xlarge/keyguard_screen_password_landscape.xml index 4bc729248c3f..5ea43dc4ad87 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"/> - </RelativeLayout> + <!-- 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"> - <!-- right side: password --> - <LinearLayout - android:layout_width="0dip" - android:layout_height="match_parent" - android:orientation="vertical" - android:layout_weight="1" - android:gravity="center"> + <!-- 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" + /> - <!-- 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" + <!-- 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> - <!-- 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" - /> + </RelativeLayout> - <!-- 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" - /> + <View + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1" + /> + + <!-- 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" + /> + + <!-- 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" + /> - </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 e63fb9bffd3a..8a059f5c1ba0 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/date_picker.xml b/core/res/res/layout/date_picker.xml index e9663b18080d..1649466261c6 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 000000000000..026cbfb8bca1 --- /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/time_picker.xml b/core/res/res/layout/time_picker.xml index 382b2f670c0d..df46db47041c 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 000000000000..ca6fe2d66f4d --- /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 6a2b93fd0e88..0b43a42e7ef4 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 5b0ea305f69d..63d3619a0284 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 de233c8a31e6..b9caeb38d12d 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 /> @@ -2869,6 +2875,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 +2889,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 +3089,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> <!-- ========================= --> diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index 1b47b5483f6e..a30e31689ac9 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" /> @@ -1627,21 +1629,15 @@ <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="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 9a1b42d9b705..46e45dbf6dc0 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 16c80d0e72fd..939e9ef10063 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -489,7 +489,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 +1511,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 +1895,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 b257a7327d75..2f8cffcb3505 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -290,6 +290,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 +984,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 +1016,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 +1250,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 0a35040aa845..fd1d5f19a270 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" - > - - <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> + android:horizontalGap="0px" + android:verticalGap="0px"> - <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 9e9db818ba45..671d87f45a41 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" - > - - <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> + android:horizontalGap="0px" + android:verticalGap="0px"> - <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 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: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="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"/> + <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="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"/> - <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" - android:iconPreview="@drawable/sym_keyboard_feedback_delete" - android:isRepeatable="true"/> + 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: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="."/> - <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_symbols.xml b/core/res/res/xml-xlarge/password_kbd_symbols.xml new file mode 100755 index 000000000000..5ae5577ae186 --- /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 000000000000..26ade76275a9 --- /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/guide_toc.cs b/docs/html/guide/guide_toc.cs index 67f1fec35e44..270d153e4f87 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 05f40238925d..6594568ff883 100644 --- a/docs/html/guide/topics/graphics/2d-graphics.jd +++ b/docs/html/guide/topics/graphics/2d-graphics.jd @@ -17,8 +17,6 @@ parent.link=index.html <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 @@ Notice how the width and height of the button varies with the text, and the back 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 000000000000..c977d51c14da --- /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/resources/resources-data.js b/docs/html/resources/resources-data.js index 221406c459f3..11964da3f537 100644 --- a/docs/html/resources/resources-data.js +++ b/docs/html/resources/resources-data.js @@ -343,7 +343,27 @@ var ANDROID_RESOURCES = [ /////////////////// /// 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 @@ var ANDROID_RESOURCES = [ } }, { - 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 @@ var ANDROID_RESOURCES = [ } }, { + 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,23 +435,23 @@ var ANDROID_RESOURCES = [ } }, { - tags: ['sample', 'gamedev', 'media'], - path: 'samples/JetBoy/index.html', + tags: ['sample', 'new'], + path: 'samples/Honeycomb-Gallery/index.html', title: { - en: 'JetBoy' + en: 'Honeycomb Gallery' }, description: { - en: 'A game that demonstrates the SONiVOX JET interactive music technology, with <code><a href="/reference/android/media/JetPlayer.html">JetPlayer</a></code>.' + en: 'An image gallery application using Honeycomb-specific APIs.' } }, { - tags: ['sample', 'ui', 'newfeature'], - path: 'samples/CubeLiveWallpaper/index.html', + tags: ['sample', 'gamedev', 'media'], + path: 'samples/JetBoy/index.html', title: { - en: 'Live Wallpaper' + en: 'JetBoy' }, 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.' + en: 'A game that demonstrates the SONiVOX JET interactive music technology, with <code><a href="/reference/android/media/JetPlayer.html">JetPlayer</a></code>.' } }, { @@ -446,6 +476,16 @@ var ANDROID_RESOURCES = [ }, { 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 @@ var ANDROID_RESOURCES = [ } }, { + 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 @@ var ANDROID_RESOURCES = [ } }, { + 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 @@ var ANDROID_RESOURCES = [ } }, { - 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 @@ var ANDROID_RESOURCES = [ } }, { - 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 Binary files differnew file mode 100644 index 000000000000..c175d12b5d7e --- /dev/null +++ b/docs/html/resources/samples/images/NfcDemo.png diff --git a/docs/html/resources/samples/images/hcgallery.png b/docs/html/resources/samples/images/hcgallery.png Binary files differnew file mode 100644 index 000000000000..9a80fd77ad9b --- /dev/null +++ b/docs/html/resources/samples/images/hcgallery.png diff --git a/drm/common/IDrmManagerService.cpp b/drm/common/IDrmManagerService.cpp index 75edac6b6f59..ddbd220795e1 100644 --- a/drm/common/IDrmManagerService.cpp +++ b/drm/common/IDrmManagerService.cpp @@ -382,7 +382,7 @@ status_t BpDrmManagerService::setPlaybackStatus( } data.writeInt32(playbackStatus); - data.writeInt32(position); + data.writeInt64(position); remote()->transact(SET_PLAYBACK_STATUS, data, &reply); return reply.readInt32(); @@ -1111,7 +1111,7 @@ status_t BnDrmManagerService::onTransact( } 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/Region.java b/graphics/java/android/graphics/Region.java index e5408068e64f..27ea0f03d97a 100644 --- a/graphics/java/android/graphics/Region.java +++ b/graphics/java/android/graphics/Region.java @@ -287,6 +287,10 @@ public class Region implements Parcelable { region2.mNativeRegion, op.nativeInt); } + public String toString() { + return nativeToString(mNativeRegion); + } + ////////////////////////////////////////////////////////////////////////// public static final Parcelable.Creator<Region> CREATOR @@ -357,6 +361,8 @@ public class Region implements Parcelable { 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 @@ public class Region implements Parcelable { 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 1789891d73e5..74cdf80a9294 100644 --- a/graphics/java/android/renderscript/Allocation.java +++ b/graphics/java/android/renderscript/Allocation.java @@ -268,22 +268,105 @@ public class Allocation extends BaseObj { } } + /** + * 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 @@ public class Allocation extends BaseObj { 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/ScriptC.java b/graphics/java/android/renderscript/ScriptC.java index ff8f09323503..94452834623f 100644 --- a/graphics/java/android/renderscript/ScriptC.java +++ b/graphics/java/android/renderscript/ScriptC.java @@ -56,6 +56,9 @@ public class ScriptC extends Script { 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/private/surfaceflinger/SharedBufferStack.h b/include/private/surfaceflinger/SharedBufferStack.h index 9d589cf9988a..eb599b590e2d 100644 --- a/include/private/surfaceflinger/SharedBufferStack.h +++ b/include/private/surfaceflinger/SharedBufferStack.h @@ -105,7 +105,7 @@ public: 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 @@ public: 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 @@ private: 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 27f65bce8832..30b45f766bc5 100644 --- a/include/ui/Input.h +++ b/include/ui/Input.h @@ -38,6 +38,15 @@ enum { 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 ef1957928117..c6501417713e 100644 --- a/keystore/java/android/security/Credentials.java +++ b/keystore/java/android/security/Credentials.java @@ -29,12 +29,8 @@ import java.security.KeyPair; 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 class Credentials { 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 @@ public class Credentials { 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 c49be9373135..38e0848d5b54 100644 --- a/libs/hwui/Android.mk +++ b/libs/hwui/Android.mk @@ -23,6 +23,7 @@ ifeq ($(USE_OPENGL_RENDERER),true) 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 fde4f966c7b1..bffab958378f 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -73,6 +73,10 @@ void Caches::dumpMemoryUsage() { 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 a11b6bc1ec08..aa0ceb707451 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 @@ public: 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 71ec7609f0d0..62366845e7a1 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 ade85e5b4852..a74a95fc28b8 100644 --- a/libs/hwui/DisplayListRenderer.cpp +++ b/libs/hwui/DisplayListRenderer.cpp @@ -103,6 +103,8 @@ const char* DisplayList::OP_NAMES[] = { "DrawPatch", "DrawColor", "DrawRect", + "DrawRoundRect", + "DrawCircle", "DrawPath", "DrawLines", "DrawText", @@ -332,6 +334,15 @@ void DisplayList::replay(OpenGLRenderer& renderer, uint32_t level) { 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()); } @@ -601,6 +612,21 @@ void DisplayListRenderer::drawRect(float left, float top, float right, float bot 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 05864ec8ad6f..4b727f68fdf1 100644 --- a/libs/hwui/DisplayListRenderer.h +++ b/libs/hwui/DisplayListRenderer.h @@ -110,6 +110,8 @@ public: DrawPatch, DrawColor, DrawRect, + DrawRoundRect, + DrawCircle, DrawPath, DrawLines, DrawText, @@ -270,6 +272,9 @@ public: 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 c080501df338..c43e40dfcedd 100644 --- a/libs/hwui/FontRenderer.cpp +++ b/libs/hwui/FontRenderer.cpp @@ -298,8 +298,10 @@ Font* Font::create(FontRenderer* state, uint32_t fontId, float fontSize, // FontRenderer /////////////////////////////////////////////////////////////////////////////// +static bool sLogFontRendererCreate = true; + FontRenderer::FontRenderer() { - LOGD("Creating FontRenderer"); + if (sLogFontRendererCreate) LOGD("Creating FontRenderer"); mGammaTable = NULL; mInitialized = false; @@ -317,18 +319,24 @@ FontRenderer::FontRenderer() { 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 e6bea786dfdc..a16742982f61 100644 --- a/libs/hwui/LayerRenderer.cpp +++ b/libs/hwui/LayerRenderer.cpp @@ -29,7 +29,6 @@ namespace uirenderer { 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::prepare(bool opaque) { 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 f2fb898b21c7..1e398470a082 100644 --- a/libs/hwui/LayerRenderer.h +++ b/libs/hwui/LayerRenderer.h @@ -51,6 +51,7 @@ public: 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 @@ private: void generateMesh(); Layer* mLayer; - GLuint mPreviousFbo; - }; // class LayerRenderer }; // namespace uirenderer diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 2067acc1803c..9528dbbfdafb 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -200,7 +200,7 @@ void OpenGLRenderer::resume() { glDisable(GL_DITHER); - glBindFramebuffer(GL_FRAMEBUFFER, 0); + glBindFramebuffer(GL_FRAMEBUFFER, getTargetFbo()); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); mCaches.blend = true; @@ -430,18 +430,18 @@ bool OpenGLRenderer::createLayer(sp<Snapshot> snapshot, float left, float top, } 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 @@ void OpenGLRenderer::composeLayer(sp<Snapshot> current, sp<Snapshot> previous) { 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) { @@ -1303,6 +1305,38 @@ void OpenGLRenderer::drawColor(int color, SkXfermode::Mode mode) { 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 +1485,7 @@ void OpenGLRenderer::drawText(const char* text, int bytesCount, int count, 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 +1494,7 @@ void OpenGLRenderer::drawPath(SkPath* path, SkPaint* paint) { 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 +1590,35 @@ void OpenGLRenderer::setupShadow(float radius, float dx, float dy, int color) { // 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 272c5c249b04..a43660b190bd 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -107,6 +107,9 @@ public: 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 +148,27 @@ protected: 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 +346,8 @@ private: 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 999e4eacaba2..11eb953907ca 100644 --- a/libs/hwui/Patch.cpp +++ b/libs/hwui/Patch.cpp @@ -167,10 +167,6 @@ void Patch::updateVertices(const float bitmapWidth, const float bitmapHeight, 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 @@ void Patch::generateRow(TextureVertex*& vertex, float y1, float y2, float v1, fl 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 3184598d48c4..28c302e68de8 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 android { namespace uirenderer { /////////////////////////////////////////////////////////////////////////////// -// Constructors/destructor -/////////////////////////////////////////////////////////////////////////////// - -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 +// Path cache /////////////////////////////////////////////////////////////////////////////// -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 @@ PathTexture* PathCache::get(SkPath* path, SkPaint* paint) { 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 ae2e55dfbe2a..dc67e160fabf 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() { - path = NULL; - join = SkPaint::kDefault_Join; - cap = SkPaint::kDefault_Cap; - style = SkPaint::kFill_Style; - miter = 4.0f; - strokeWidth = 1.0f; +struct PathCacheEntry: public ShapeCacheEntry { + PathCacheEntry(SkPath* path, SkPaint* paint): + ShapeCacheEntry(ShapeCacheEntry::kShapePath, paint) { + this->path = path; } - PathCacheEntry(const PathCacheEntry& entry): - path(entry.path), join(entry.join), cap(entry.cap), - style(entry.style), miter(entry.miter), - strokeWidth(entry.strokeWidth) { + PathCacheEntry(): ShapeCacheEntry() { + path = NULL; } - PathCacheEntry(SkPath* path, SkPaint* paint) { - this->path = path; - join = paint->getStrokeJoin(); - cap = paint->getStrokeCap(); - miter = paint->getStrokeMiter(); - strokeWidth = paint->getStrokeWidth(); - style = paint->getStyle(); + PathCacheEntry(const PathCacheEntry& entry): + ShapeCacheEntry(entry) { + path = entry.path; } - 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 @@ public: */ 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 @@ public: */ 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 6a0d7ea18dfb..2f230b566c82 100644 --- a/libs/hwui/Properties.h +++ b/libs/hwui/Properties.h @@ -48,6 +48,7 @@ enum DebugLevel { #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 @@ enum DebugLevel { #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 000000000000..b78eecba5215 --- /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 000000000000..c8bcfc246aad --- /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 b02f85d74913..b6f2b2a60371 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 @@ static void test_clamp(uint32_t index) { 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 @@ static void test_clamp(uint32_t index) { 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 @@ static void test_clamp4(uint32_t index) { 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 5b1ad15c0cb6..02993fe5bb05 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 float2 f2; volatile float3 f3; volatile float4 f4; -#define TEST_F(fnc, var) \ +volatile int i1; +volatile int2 i2; +volatile int3 i3; +volatile int4 i4; + +#define TEST_FN_FUNC_FN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1); \ + f2 = fnc(f2); \ + f3 = fnc(f3); \ + f4 = fnc(f4); + +#define TEST_FN_FUNC_FN_PFN(fnc) \ + rsDebug("Testing " #fnc, 0); \ + f1 = fnc(f1, (float*) &f1); \ + f2 = fnc(f2, (float2*) &f2); \ + f3 = fnc(f3, (float3*) &f3); \ + f4 = fnc(f4, (float4*) &f4); + +#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); \ - var##1 = fnc(var##1); \ - var##2 = fnc(var##2); \ - var##3 = fnc(var##3); \ - var##4 = fnc(var##4); + f1 = fnc(f1, i1); \ + f2 = fnc(f2, i2); \ + f3 = fnc(f3, i3); \ + f4 = fnc(f4, i4); -#define TEST_FP(fnc, var) \ +#define TEST_FN_FUNC_FN_I(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, i1); \ + f2 = fnc(f2, i1); \ + f3 = fnc(f3, i1); \ + f4 = fnc(f4, i1); -#define TEST_F2(fnc, var) \ +#define TEST_FN_FUNC_FN_FN_FN(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, f1, f1); \ + f2 = fnc(f2, f2, f2); \ + f3 = fnc(f3, f3, f3); \ + f4 = fnc(f4, f4, f4); -static bool test_math(uint32_t index) { +#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 @@ static bool test_math(uint32_t index) { 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 2e0c491c34ef..3acb62460de0 100644 --- a/libs/rs/rsContext.cpp +++ b/libs/rs/rsContext.cpp @@ -253,7 +253,11 @@ void Context::deinitEGL() { 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_ContextDump(Context *rsc, int32_t bits) { } 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 9f730bffe8d3..1fceb663527f 100644 --- a/libs/rs/rsScriptC.cpp +++ b/libs/rs/rsScriptC.cpp @@ -467,7 +467,7 @@ extern const char rs_runtime_lib_bc[]; 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) { @@ -482,7 +482,7 @@ void ScriptCState::runCompiler(Context *rsc, s->mEnviroment.mScriptText, s->mEnviroment.mScriptTextLength, 0) != 0) { LOGE("bcc: FAILS to read bitcode"); - // Handle Fatal Error + return false; } #if 1 @@ -493,14 +493,14 @@ void ScriptCState::runCompiler(Context *rsc, /*"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 +547,7 @@ void ScriptCState::runCompiler(Context *rsc, continue; } LOGE("Invalid version pragma value: %s\n", values[i]); - // Handle Fatal Error + return false; } if (!strcmp(keys[i], "stateVertex")) { @@ -559,7 +559,7 @@ void ScriptCState::runCompiler(Context *rsc, continue; } LOGE("Unrecognized value %s passed to stateVertex", values[i]); - // Handle Fatal Error + return false; } if (!strcmp(keys[i], "stateRaster")) { @@ -571,7 +571,7 @@ void ScriptCState::runCompiler(Context *rsc, continue; } LOGE("Unrecognized value %s passed to stateRaster", values[i]); - // Handle Fatal Error + return false; } if (!strcmp(keys[i], "stateFragment")) { @@ -583,7 +583,7 @@ void ScriptCState::runCompiler(Context *rsc, continue; } LOGE("Unrecognized value %s passed to stateFragment", values[i]); - // Handle Fatal Error + return false; } if (!strcmp(keys[i], "stateStore")) { @@ -595,9 +595,10 @@ void ScriptCState::runCompiler(Context *rsc, continue; } LOGE("Unrecognized value %s passed to stateStore", values[i]); - // Handle Fatal Error + return false; } } + return true; } namespace android { @@ -630,7 +631,11 @@ RsScript rsi_ScriptCCreate(Context *rsc, 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 483481e81b02..612e38a3b5aa 100644 --- a/libs/rs/rsScriptC.h +++ b/libs/rs/rsScriptC.h @@ -81,7 +81,7 @@ public: 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 28c558d9120e..02d33b768abe 100644 --- a/libs/rs/rsScriptC_LibCL.cpp +++ b/libs/rs/rsScriptC_LibCL.cpp @@ -24,26 +24,6 @@ using namespace android; 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 @@ static float SC_log2(float v) { 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 @@ float SC_sincos(float v, float *cosptr) { 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 @@ static ScriptCState::SymbolTable_t gSyms[] = { // 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 @@ static ScriptCState::SymbolTable_t gSyms[] = { { "_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 ab8270f404a8..3c0496d08e3f 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(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_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) CVT_FUNC(char) CVT_FUNC(uchar) @@ -38,341 +42,444 @@ CVT_FUNC(int) 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; \ -} - -#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 DEF_FUNC_2(fnc) \ + 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 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 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; \ -} - -#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 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; \ + 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_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 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 @@ _RS_STATIC float4 __attribute__((overloadable)) powr(float4 v, float4 p) { } 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 @@ _RS_STATIC float4 __attribute__((overloadable)) rootn(float4 v, int4 r) { } 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 @@ _RS_STATIC float4 __attribute__((overloadable)) sincos(float4 v, float4 *cosptr) } 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; \ -} - -#define DEF_UIFUNC_1(fnc) \ -DEF_RIFUNC_1(uchar, char, fnc) \ -DEF_RIFUNC_1(ushort, short, fnc) \ -DEF_RIFUNC_1(uint, int, fnc) - -#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 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 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) - -DEF_UIFUNC_1(abs) -DEF_IFUNC_1(clz) - -DEF_IFUNC_2(min, (v1 < v2 ? v1 : v2)) -DEF_FUNC_2F(min) - -DEF_IFUNC_2(max, (v1 > v2 ? v1 : v2)) -DEF_FUNC_2F(max) + 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 UIN_FUNC_IN(fnc) \ +XN_FUNC_YN(uchar, fnc, char) \ +XN_FUNC_YN(ushort, fnc, short) \ +XN_FUNC_YN(uint, fnc, int) + +#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 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 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) + +UIN_FUNC_IN(abs) +IN_FUNC_IN(clz) + +IN_FUNC_IN_IN_BODY(min, (v1 < v2 ? v1 : v2)) +FN_FUNC_FN_F(min) + +IN_FUNC_IN_IN_BODY(max, (v1 > v2 ? v1 : v2)) +FN_FUNC_FN_F(max) // 6.11.4 @@ -617,7 +726,7 @@ _RS_STATIC float4 __attribute__((overloadable)) clamp(float4 amount, float low, _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 float4 __attribute__((overloadable)) mix(float4 start, float4 stop, f _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 @@ _RS_STATIC float __attribute__((overloadable)) sign(float v) { 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 @@ _RS_STATIC float4 __attribute__((overloadable)) normalize(float4 v) { #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 0f8717fa6c03..a010096507b1 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 af11f97a0ca1..7505d530e0c5 100644 --- a/libs/surfaceflinger_client/SharedBufferStack.cpp +++ b/libs/surfaceflinger_client/SharedBufferStack.cpp @@ -58,7 +58,6 @@ SharedBufferStack::SharedBufferStack() void SharedBufferStack::init(int32_t i) { - inUse = -2; status = NO_ERROR; identity = i; } @@ -199,9 +198,9 @@ String8 SharedBufferBase::dump(char const* prefix) const 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 @@ ssize_t SharedBufferClient::CancelUpdate::operator()() { 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 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() { 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 @@ ssize_t SharedBufferServer::RetireUpdate::operator()() { 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 @@ ssize_t SharedBufferServer::retireAndLock() 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 @@ status_t SharedBufferServer::shrink(int newNumBuffers) 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 1663313f2e3f..f24a71d88d9d 100644 --- a/libs/ui/EGLUtils.cpp +++ b/libs/ui/EGLUtils.cpp @@ -66,12 +66,6 @@ status_t EGLUtils::selectConfigForPixelFormat( 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 @@ status_t EGLUtils::selectConfigForPixelFormat( 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 ce84683375ba..33ef1fc8945c 100644 --- a/libs/ui/GraphicBufferAllocator.cpp +++ b/libs/ui/GraphicBufferAllocator.cpp @@ -61,7 +61,7 @@ void GraphicBufferAllocator::dump(String8& result) const 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/MediaImageItem.java b/media/java/android/media/videoeditor/MediaImageItem.java index b03588fdf462..1c028787bed0 100755 --- a/media/java/android/media/videoeditor/MediaImageItem.java +++ b/media/java/android/media/videoeditor/MediaImageItem.java @@ -93,29 +93,28 @@ public class MediaImageItem extends MediaItem { * * @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 @@ public class MediaImageItem extends MediaItem { 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 @@ public class MediaImageItem extends MediaItem { */ 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 @@ public class MediaImageItem extends MediaItem { 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 @@ public class MediaImageItem extends MediaItem { dos.write(array); tmp += 1; } + mScaledWidth = mNewWidth; mScaledHeight = mNewHeight; scaledImage.recycle(); @@ -204,10 +207,11 @@ public class MediaImageItem extends MediaItem { + "/" + "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 @@ public class MediaImageItem extends MediaItem { 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 @@ public class MediaImageItem extends MediaItem { dos.write(array); tmp += 1; } + mScaledWidth = mNewWidth; mScaledHeight = mNewheight; imageBitmap.recycle(); } + fl.close(); System.gc(); } @@ -286,7 +292,7 @@ public class MediaImageItem extends MediaItem { /** * @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 @@ public class MediaImageItem extends MediaItem { * 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 @@ public class MediaImageItem extends MediaItem { * 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 @@ public class MediaImageItem extends MediaItem { for (int i = 0; i < thumbnailCount; i++) { thumbnailArray[i] = thumbnail; } - return thumbnailArray; - - } - else { + return thumbnailArray; + } 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 @@ public class MediaImageItem extends MediaItem { */ 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 @@ public class MediaImageItem extends MediaItem { 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 772b360590b4..2981b41c0b73 100755 --- a/media/java/android/media/videoeditor/MediaVideoItem.java +++ b/media/java/android/media/videoeditor/MediaVideoItem.java @@ -78,12 +78,9 @@ public class MediaVideoItem extends MediaItem { * * @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 @@ public class MediaVideoItem extends MediaItem { * @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 @@ public class MediaVideoItem extends MediaItem { 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 @@ public class MediaVideoItem extends MediaItem { 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 @@ public class MediaVideoItem extends MediaItem { */ @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 @@ public class MediaVideoItem extends MediaItem { 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 @@ public class MediaVideoItem extends MediaItem { * {@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 @@ public class MediaVideoItem extends MediaItem { 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 @@ public class MediaVideoItem extends MediaItem { if (mFilename != null) { return mMANativeHelper.renderMediaItemPreviewFrame(surface, mFilename,timeMs,mWidth,mHeight); - } - else { + } else { return 0; } } @@ -462,7 +482,7 @@ public class MediaVideoItem extends MediaItem { * 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 @@ public class MediaVideoItem extends MediaItem { * 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 @@ public class MediaVideoItem extends MediaItem { return clipSettings; } - } diff --git a/media/jni/mediaeditor/Android.mk b/media/jni/mediaeditor/Android.mk index 27c41be671d5..0a01fb2e6f78 100755 --- a/media/jni/mediaeditor/Android.mk +++ b/media/jni/mediaeditor/Android.mk @@ -85,6 +85,6 @@ LOCAL_MODULE:= libvideoeditor_jni # 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 ca8c0474d9da..c13f6ff8dcc7 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 e66e4b90fbc3..643f6980f39e 100755 --- a/media/jni/mediaeditor/VideoEditorMain.cpp +++ b/media/jni/mediaeditor/VideoEditorMain.cpp @@ -437,7 +437,7 @@ static int videoEditor_renderPreviewFrame(JNIEnv* pEnv, 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 @@ static int removeAlphafromRGB8888 ( } /** 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 @@ typedef struct } 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 @@ M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL, 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 @@ M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL, 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 @@ M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL, 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 @@ M4OSA_ERR M4MA_generateAudioGraphFile(JNIEnv* pEnv, M4OSA_Char* pInputFileURL, } 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 153b2a66fd0d..65df68c4bf00 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -1295,12 +1295,6 @@ status_t StagefrightRecorder::setupMPEG4Recording( 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 @@ status_t StagefrightRecorder::setupMPEG4Recording( *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/libstagefright/AwesomePlayer.cpp b/media/libstagefright/AwesomePlayer.cpp index 58c4a2e8591e..11ac56ce296e 100644 --- a/media/libstagefright/AwesomePlayer.cpp +++ b/media/libstagefright/AwesomePlayer.cpp @@ -58,6 +58,8 @@ namespace android { 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 @@ void AwesomePlayer::onBufferingUpdate() { // 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 @@ status_t AwesomePlayer::finishSetDataSource_l() { 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 06c4c980681a..a47ee3a04264 100644 --- a/media/libstagefright/MPEG4Writer.cpp +++ b/media/libstagefright/MPEG4Writer.cpp @@ -590,6 +590,7 @@ status_t MPEG4Writer::stop() { 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 @@ status_t MPEG4Writer::stop() { 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 20f16555517a..741aa1ca0124 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 @@ void NuCachedSource2::getDrmInfo(DecryptHandle **handle, DrmManagerClient **clie String8 NuCachedSource2::getUri() { return mSource->getUri(); } + } // namespace android diff --git a/media/libstagefright/httplive/LiveSession.cpp b/media/libstagefright/httplive/LiveSession.cpp index e731080c8046..f20a4cbcca21 100644 --- a/media/libstagefright/httplive/LiveSession.cpp +++ b/media/libstagefright/httplive/LiveSession.cpp @@ -438,8 +438,7 @@ rinse_repeat: 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 " diff --git a/packages/SystemUI/assets/fonts/AndroidClock.ttf b/packages/SystemUI/assets/fonts/AndroidClock.ttf Binary files differindex 39451831c1a0..7b550eeda2d8 100644 --- a/packages/SystemUI/assets/fonts/AndroidClock.ttf +++ b/packages/SystemUI/assets/fonts/AndroidClock.ttf diff --git a/packages/SystemUI/assets/fonts/AndroidClock2.ttf b/packages/SystemUI/assets/fonts/AndroidClock2.ttf Binary files differindex fa0221ebafb0..a95d5482840c 100644 --- a/packages/SystemUI/assets/fonts/AndroidClock2.ttf +++ b/packages/SystemUI/assets/fonts/AndroidClock2.ttf diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png Binary files differnew file mode 100644 index 000000000000..9812339f04c8 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_default.png 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 Binary files differnew file mode 100644 index 000000000000..4f61511af1ae --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_default.png 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 Binary files differnew file mode 100644 index 000000000000..475712560a74 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_ime_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png Binary files differnew file mode 100644 index 000000000000..8436f5a9af1e --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_back_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png Binary files differnew file mode 100644 index 000000000000..60050751fa95 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png Binary files differnew file mode 100644 index 000000000000..83068a9b3f38 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_home_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png Binary files differnew file mode 100644 index 000000000000..e6f2f34a4a65 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_ime_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png Binary files differnew file mode 100644 index 000000000000..2591521f2cc3 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png Binary files differnew file mode 100644 index 000000000000..56a4a1df1d74 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_menu_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png Binary files differnew file mode 100644 index 000000000000..77546575f3a2 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png Binary files differnew file mode 100644 index 000000000000..afc4057471e9 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_recent_pressed.png 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 Binary files differindex dadb0cd3704f..92ffde9988e0 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 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 Binary files differindex 51d7cc245d70..0cd05a30b737 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 diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png Binary files differindex 335960243cfe..993ea5591c8b 100644 --- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png Binary files differnew file mode 100644 index 000000000000..22d6c797fb47 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png Binary files differnew file mode 100644 index 000000000000..24166dae0e23 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_bg_protect.png 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 Binary files differnew file mode 100644 index 000000000000..85d9795d90d3 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_clock_bg.9.png 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 Binary files differnew file mode 100644 index 000000000000..b389a3505cbc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/notify_panel_notify_bg.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/panel_notification.png b/packages/SystemUI/res/drawable-mdpi/panel_notification.png Binary files differnew file mode 100644 index 000000000000..3789f3cc3d9f --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/panel_notification.png diff --git a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png b/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png Binary files differdeleted file mode 100755 index e9589d918b5c..000000000000 --- a/packages/SystemUI/res/drawable-nodpi/notify_panel_bg_protect.png +++ /dev/null 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 000000000000..037132219cb6 --- /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 9da92a79751a..3a50aa957b03 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 0533b6f5e66c..852b72974f37 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 72e2c0bb863e..5a41421d1bf0 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 7f84b21458b5..4cf28eee4e74 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 000000000000..40f2247753b5 --- /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 e97345b1dc72..233cb46f0b85 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 8a477e4f110c..1dbd75980e8e 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 --> 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 000000000000..47e758c58fe6 --- /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 7012ddcbce8d..28f485c1e350 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 @@ public class InputMethodButton extends ImageView { 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 cc200e39d028..a3ccef998099 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 @@ public class InputMethodsPanel extends LinearLayout implements StatusBarPanel, O 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 45a22b61904d..9f48b483dd25 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.View; 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 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, 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 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, 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 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, } else { mShowing = show; setVisibility(show ? View.VISIBLE : View.GONE); - mChoreo.jumpTo(show); } } @@ -118,60 +117,82 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, 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 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, } } + // 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 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, 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 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, 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 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, 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 @@ public class NotificationPanel extends RelativeLayout implements StatusBarPanel, 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 6db74d133372..a3a58edc89da 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 @@ public class TabletStatusBar extends StatusBar implements 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 6cdf67438ed8..000000000000 --- 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 6092e302c9bf..000000000000 --- 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 e69de29bb2d1..000000000000 --- a/packages/VpnServices/MODULE_LICENSE_APACHE2 +++ /dev/null diff --git a/packages/VpnServices/NOTICE b/packages/VpnServices/NOTICE deleted file mode 100644 index c5b1efa7aac7..000000000000 --- 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 6bac1200a17a..000000000000 --- 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 fdcbf640f4dd..000000000000 --- 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 b37790ab55cc..000000000000 --- 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 96d4cc5362c4..000000000000 --- 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 0f05bbc46938..000000000000 --- 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 b907be8b579f..000000000000 --- 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 d96f3e015a04..000000000000 --- 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 905c2652be5d..000000000000 --- 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 8f5053c15cf0..000000000000 --- 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 91824599a958..000000000000 --- 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 7cee16d2fedf..000000000000 --- 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 b15202aae76c..000000000000 --- 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 4a93e0ad7863..000000000000 --- 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 aedb536adf4d..000000000000 --- 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 44f542782a7e..000000000000 --- 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 8b6b4c24663a..000000000000 --- 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 1c7a5889a30b..000000000000 --- 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 74971d6d99cc..000000000000 --- 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 548d8a987e06..000000000000 --- 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 4185291eb7ef..000000000000 --- 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 58f1f58c0c93..000000000000 --- 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 cb80908c4b99..000000000000 --- 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 4790600eba12..000000000000 --- 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 175c7ddc324f..000000000000 --- 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 565d2497eabb..000000000000 --- 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 020188f3ed3d..000000000000 --- 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 f47652ac580b..000000000000 --- 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 80f281709be3..000000000000 --- 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 a22792cb2604..000000000000 --- 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 8a839c307112..000000000000 --- 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 167b6f389e44..000000000000 --- 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 c5b72c4459e0..000000000000 --- 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 bfe6cc88fc8a..000000000000 --- 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 24f9f58323e3..000000000000 --- 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 3aa9c6ea8892..000000000000 --- 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 bd988a1c3d1c..000000000000 --- 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 8666b35a7e37..000000000000 --- 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 208659a40cb4..000000000000 --- 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 3022c9c02494..000000000000 --- 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 cad08e15366a..000000000000 --- 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 ee5a42b51c98..000000000000 --- 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 d82f52a69d45..000000000000 --- 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 eeafd5a1639c..000000000000 --- 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 eb4d930e3f85..5b80a93ab9d5 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 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen || 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 @@ public class PasswordUnlockScreen extends LinearLayout implements KeyguardScreen 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 16c042d646e6..11ad4e468a9a 100644 --- a/services/audioflinger/AudioFlinger.cpp +++ b/services/audioflinger/AudioFlinger.cpp @@ -5443,19 +5443,21 @@ void AudioFlinger::EffectModule::process() // 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 8e9a5a4aa98f..2e832568cf90 100644 --- a/services/input/InputReader.cpp +++ b/services/input/InputReader.cpp @@ -744,7 +744,7 @@ SwitchInputMapper::~SwitchInputMapper() { } 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 775747ca67cf..98d627d300dc 100644 --- a/services/input/tests/InputReader_test.cpp +++ b/services/input/tests/InputReader_test.cpp @@ -1484,7 +1484,7 @@ TEST_F(SwitchInputMapperTest, GetSources) { 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 2321e30f3f5c..bd3c554a5be5 100644 --- a/services/java/com/android/server/ConnectivityService.java +++ b/services/java/com/android/server/ConnectivityService.java @@ -32,6 +32,7 @@ import android.net.NetworkStateTracker; 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 @@ public class ConnectivityService extends IConnectivityManager.Stub { mSettingsObserver.observe(mContext); loadGlobalProxy(); + + VpnManager.startVpnService(context); } diff --git a/services/java/com/android/server/InputMethodManagerService.java b/services/java/com/android/server/InputMethodManagerService.java index 4d406209e74b..48c21b28d063 100644 --- a/services/java/com/android/server/InputMethodManagerService.java +++ b/services/java/com/android/server/InputMethodManagerService.java @@ -118,7 +118,6 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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"; @@ -576,7 +575,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (!allowsImplicitlySelectedSubtypes || enabledSubtypes.size() > 0) { return enabledSubtypes; } else { - return getApplicableSubtypesLocked(mRes, imi.getSubtypes()); + return getApplicableSubtypesLocked(mRes, getSubtypes(imi)); } } } @@ -1015,10 +1014,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } 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) { @@ -1544,6 +1542,15 @@ public class InputMethodManagerService extends IInputMethodManager.Stub & 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 +1647,12 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } 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); } @@ -1681,7 +1688,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub ArrayList<String> subtypes = immis.get(i).second; if (subtypes != null && subtypes.size() == 0) { ArrayList<InputMethodSubtype> applicableSubtypes = - getApplicableSubtypesLocked(mRes, imi.getSubtypes()); + getApplicableSubtypesLocked(mRes, getSubtypes(imi)); final int numSubtypes = applicableSubtypes.size(); for (int j = 0; j < numSubtypes; ++j) { subtypes.add(String.valueOf(applicableSubtypes.get(j).hashCode())); @@ -1711,11 +1718,11 @@ public class InputMethodManagerService extends IInputMethodManager.Stub if (property == null) { continue; } - ArrayList<InputMethodSubtype> subtypes = property.getSubtypes(); CharSequence label = property.loadLabel(pm); if (showSubtypes && enabledSubtypeSet.size() > 0) { - for (int j = 0; j < subtypes.size(); ++j) { - InputMethodSubtype subtype = subtypes.get(j); + final int subtypeCount = property.getSubtypeCount(); + for (int j = 0; j < subtypeCount; ++j) { + InputMethodSubtype subtype = property.getSubtypeAt(j); if (enabledSubtypeSet.contains(String.valueOf(subtype.hashCode()))) { CharSequence title; int nameResId = subtype.getNameResId(); @@ -1791,7 +1798,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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 +1923,10 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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 +1974,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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 +2120,13 @@ public class InputMethodManagerService extends IInputMethodManager.Stub // 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 +2204,7 @@ public class InputMethodManagerService extends IInputMethodManager.Stub } } else { mCurrentSubtype = - mMethodMap.get(lastInputMethodId).getSubtypes().get(subtypeId); + getSubtypes(mMethodMap.get(lastInputMethodId)).get(subtypeId); } } return mCurrentSubtype; @@ -2320,8 +2327,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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); @@ -2561,9 +2569,9 @@ public class InputMethodManagerService extends IInputMethodManager.Stub 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/WindowManagerService.java b/services/java/com/android/server/WindowManagerService.java index 3e930aeb085d..2af291dadd32 100644 --- a/services/java/com/android/server/WindowManagerService.java +++ b/services/java/com/android/server/WindowManagerService.java @@ -583,7 +583,7 @@ public class WindowManagerService extends IWindowManager.Stub 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 @@ public class WindowManagerService extends IWindowManager.Stub // 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 @@ public class WindowManagerService extends IWindowManager.Stub 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 2ef85d5feaa1..9e9a4f21a2d3 100755 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -6817,6 +6817,9 @@ public final class ActivityManagerService extends ActivityManagerNative 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 418e7f8d0d05..3abfc12bcbf3 100644 --- a/services/sensorservice/RotationVectorSensor.cpp +++ b/services/sensorservice/RotationVectorSensor.cpp @@ -34,9 +34,9 @@ static inline T clamp(T v) { 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 b7c951274564..17699f8a4e74 100644 --- a/services/sensorservice/RotationVectorSensor.h +++ b/services/sensorservice/RotationVectorSensor.h @@ -38,9 +38,9 @@ class RotationVectorSensor : public SensorInterface { 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 fde68f6e07f6..37307391fd9f 100644 --- a/services/surfaceflinger/Layer.cpp +++ b/services/surfaceflinger/Layer.cpp @@ -691,22 +691,6 @@ void Layer::unlockPageFlip( } } -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 5444d2f1945d..290811982eac 100644 --- a/services/surfaceflinger/Layer.h +++ b/services/surfaceflinger/Layer.h @@ -75,7 +75,6 @@ public: 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 0c1fcf912493..464841b3962e 100644 --- a/services/surfaceflinger/LayerBase.cpp +++ b/services/surfaceflinger/LayerBase.cpp @@ -273,10 +273,6 @@ void LayerBase::unlockPageFlip( } } -void LayerBase::finishPageFlip() -{ -} - void LayerBase::invalidate() { if ((android_atomic_or(1, &mInvalidate)&1) == 0) { @@ -534,6 +530,12 @@ void LayerBase::dump(String8& result, char* buffer, size_t SIZE) const 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 @@ void LayerBaseClient::dump(String8& result, char* buffer, size_t SIZE) const 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 f6c49fc24339..1a34f52ad317 100644 --- a/services/surfaceflinger/LayerBase.h +++ b/services/surfaceflinger/LayerBase.h @@ -174,11 +174,6 @@ public: 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 @@ public: /** 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 @@ public: 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 f5835c90a524..694af70cf8fd 100644 --- a/services/surfaceflinger/SurfaceFlinger.cpp +++ b/services/surfaceflinger/SurfaceFlinger.cpp @@ -394,14 +394,10 @@ bool SurfaceFlinger::threadLoop() 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; @@ -926,17 +922,6 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty) } } -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()); @@ -1497,8 +1482,13 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 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); @@ -1508,6 +1498,24 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 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, @@ -1533,6 +1541,9 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 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", @@ -1540,6 +1551,9 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args) 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 eabdc645941a..6dd91ac707f9 100644 --- a/services/surfaceflinger/SurfaceFlinger.h +++ b/services/surfaceflinger/SurfaceFlinger.h @@ -314,7 +314,6 @@ private: 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 c1434245acce..a3d3781d085a 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.text.TextUtils; 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 @@ public abstract class DataConnection extends HierarchicalStateMachine { 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); + } + + 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)); - 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])); } 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/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java index b2d2a98e32ee..39a4614ed46b 100644 --- a/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java +++ b/tests/DumpRenderTree/src/com/android/dumprendertree/FileFilter.java @@ -122,6 +122,8 @@ public class FileFilter { 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 a3466e27e597..9c4fa975bec0 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.util.Log; 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 @@ public class TestShellActivity extends Activity implements LayoutTestController setDefaultWebSettings(mWebView); mIsGeolocationPermissionSet = false; mPendingGeolocationPermissionCallbacks = null; + CookieManager.getInstance().removeAllCookie(); } private long[] getDrawWebViewTime(WebView view, int count) { diff --git a/tests/HwAccelerationTest/AndroidManifest.xml b/tests/HwAccelerationTest/AndroidManifest.xml index 691aff2866c3..1d67964dc26b 100644 --- a/tests/HwAccelerationTest/AndroidManifest.xml +++ b/tests/HwAccelerationTest/AndroidManifest.xml @@ -25,6 +25,15 @@ android:hardwareAccelerated="true"> <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 +62,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 000000000000..a820f5f2c43f --- /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/ShapesActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShapesActivity.java new file mode 100644 index 000000000000..536a669cba19 --- /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 000000000000..c8ae75bfb701 --- /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 fedccb0d8795..6bf3eddee551 100644 --- a/vpn/java/android/net/vpn/IVpnService.aidl +++ b/vpn/java/android/net/vpn/IVpnService.aidl @@ -24,10 +24,11 @@ import android.net.vpn.VpnProfile; */ 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 @@ interface IVpnService { 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 ce40b5d0c122..02486bbab611 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 @@ import android.util.Log; * {@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 @@ public class VpnManager { 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 @@ public class VpnManager { 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 @@ public class VpnManager { } } - /** - * 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 index 289ee458a0be..289ee458a0be 100644 --- a/packages/VpnServices/src/com/android/server/vpn/DaemonProxy.java +++ b/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 index 50e0de18ccd9..50e0de18ccd9 100644 --- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecPskService.java +++ b/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 index 663b0e860f06..663b0e860f06 100644 --- a/packages/VpnServices/src/com/android/server/vpn/L2tpIpsecService.java +++ b/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 index 784a366f5b30..784a366f5b30 100644 --- a/packages/VpnServices/src/com/android/server/vpn/L2tpService.java +++ b/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 index de12710c7707..de12710c7707 100644 --- a/packages/VpnServices/src/com/android/server/vpn/PptpService.java +++ b/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 index 3c4ec7d8c41a..3c4ec7d8c41a 100644 --- a/packages/VpnServices/src/com/android/server/vpn/VpnConnectingError.java +++ b/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 index 499195fd67af..499195fd67af 100644 --- a/packages/VpnServices/src/com/android/server/vpn/VpnDaemons.java +++ b/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 index a61842325627..4966c060e52d 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.os.SystemProperties; 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 @@ import java.net.UnknownHostException; /** * 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 @@ abstract class VpnService<E extends VpnProfile> implements Serializable { 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 @@ abstract class VpnService<E extends VpnProfile> implements Serializable { 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 @@ abstract class VpnService<E extends VpnProfile> implements Serializable { return mState; } + boolean isIdle() { + return (mState == VpnState.IDLE); + } + synchronized boolean onConnect(String username, String password) { try { setState(VpnState.CONNECTING); @@ -216,21 +214,12 @@ abstract class VpnService<E extends VpnProfile> implements Serializable { 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 @@ abstract class VpnService<E extends VpnProfile> implements Serializable { 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 @@ abstract class VpnService<E extends VpnProfile> implements Serializable { } } - 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 000000000000..c474ff9bd830 --- /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 f96a5ae65e96..3cde949f204c 100644 --- a/wifi/java/android/net/wifi/SupplicantStateTracker.java +++ b/wifi/java/android/net/wifi/SupplicantStateTracker.java @@ -31,7 +31,7 @@ import android.util.Log; * 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 @@ class SupplicantStateTracker extends HierarchicalStateMachine { 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 @@ class SupplicantStateTracker extends HierarchicalStateMachine { 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 @@ class SupplicantStateTracker extends HierarchicalStateMachine { @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 @@ class SupplicantStateTracker extends HierarchicalStateMachine { @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 090ad3b6ad2a..ce3826167c4b 100644 --- a/wifi/java/android/net/wifi/WifiMonitor.java +++ b/wifi/java/android/net/wifi/WifiMonitor.java @@ -42,7 +42,8 @@ public class WifiMonitor { 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 @@ public class WifiMonitor { * <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 @@ public class WifiMonitor { 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 @@ public class WifiMonitor { 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 @@ public class WifiMonitor { // 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 @@ public class WifiMonitor { 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 df21399e226c..4d0acdd7044c 100644 --- a/wifi/java/android/net/wifi/WifiStateMachine.java +++ b/wifi/java/android/net/wifi/WifiStateMachine.java @@ -212,8 +212,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { 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; @@ -1383,11 +1383,12 @@ public class WifiStateMachine extends HierarchicalStateMachine { } /** - * 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); } /** @@ -1515,7 +1516,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { 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: @@ -2067,7 +2068,7 @@ public class WifiStateMachine extends HierarchicalStateMachine { 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: @@ -2300,8 +2301,8 @@ public class WifiStateMachine extends HierarchicalStateMachine { 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 */ |