diff options
54 files changed, 626 insertions, 194 deletions
diff --git a/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..bd353ae --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png Binary files differnew file mode 100644 index 0000000..d127b3c --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_disabled_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_focused_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..1d1a589 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_focused_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_focused_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_focused_holo_light.9.png Binary files differnew file mode 100644 index 0000000..1d1a589 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_focused_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_pressed_holo_dark.9.png b/core/res/res/drawable-hdpi/btn_group_pressed_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..8922fa4 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/btn_group_pressed_holo_light.9.png b/core/res/res/drawable-hdpi/btn_group_pressed_holo_light.9.png Binary files differnew file mode 100644 index 0000000..53cf2f3 --- /dev/null +++ b/core/res/res/drawable-hdpi/btn_group_pressed_holo_light.9.png diff --git a/core/res/res/drawable-hdpi/divider_vertical_holo_dark.9.png b/core/res/res/drawable-hdpi/divider_vertical_holo_dark.9.png Binary files differindex deacb73..c039428 100644 --- a/core/res/res/drawable-hdpi/divider_vertical_holo_dark.9.png +++ b/core/res/res/drawable-hdpi/divider_vertical_holo_dark.9.png diff --git a/core/res/res/drawable-hdpi/divider_vertical_holo_light.9.png b/core/res/res/drawable-hdpi/divider_vertical_holo_light.9.png Binary files differindex cd2c826..7c4a29f 100644 --- a/core/res/res/drawable-hdpi/divider_vertical_holo_light.9.png +++ b/core/res/res/drawable-hdpi/divider_vertical_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..aa04cc9 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_disabled_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png Binary files differnew file mode 100644 index 0000000..25aefd2 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_disabled_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_focused_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_focused_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..b77cc78 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_focused_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_focused_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_focused_holo_light.9.png Binary files differnew file mode 100644 index 0000000..aa00c75 --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_focused_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_pressed_holo_dark.9.png b/core/res/res/drawable-mdpi/btn_group_pressed_holo_dark.9.png Binary files differnew file mode 100644 index 0000000..e35333b --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_pressed_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/btn_group_pressed_holo_light.9.png b/core/res/res/drawable-mdpi/btn_group_pressed_holo_light.9.png Binary files differnew file mode 100644 index 0000000..878fdda --- /dev/null +++ b/core/res/res/drawable-mdpi/btn_group_pressed_holo_light.9.png diff --git a/core/res/res/drawable-mdpi/divider_vertical_holo_dark.9.png b/core/res/res/drawable-mdpi/divider_vertical_holo_dark.9.png Binary files differindex 4c6968c..c039428 100644 --- a/core/res/res/drawable-mdpi/divider_vertical_holo_dark.9.png +++ b/core/res/res/drawable-mdpi/divider_vertical_holo_dark.9.png diff --git a/core/res/res/drawable-mdpi/divider_vertical_holo_light.9.png b/core/res/res/drawable-mdpi/divider_vertical_holo_light.9.png Binary files differindex 7ddf1b6..7c4a29f 100644 --- a/core/res/res/drawable-mdpi/divider_vertical_holo_light.9.png +++ b/core/res/res/drawable-mdpi/divider_vertical_holo_light.9.png diff --git a/core/res/res/drawable-nodpi/background_holo_dark.png b/core/res/res/drawable-nodpi/background_holo_dark.png Binary files differnew file mode 100644 index 0000000..f2ff75a --- /dev/null +++ b/core/res/res/drawable-nodpi/background_holo_dark.png diff --git a/core/res/res/drawable-nodpi/background_holo_light.png b/core/res/res/drawable-nodpi/background_holo_light.png Binary files differnew file mode 100644 index 0000000..04f52ae --- /dev/null +++ b/core/res/res/drawable-nodpi/background_holo_light.png diff --git a/core/res/res/drawable/group_button_background_holo_dark.xml b/core/res/res/drawable/group_button_background_holo_dark.xml index 8e6675a..fa00785 100644 --- a/core/res/res/drawable/group_button_background_holo_dark.xml +++ b/core/res/res/drawable/group_button_background_holo_dark.xml @@ -19,10 +19,10 @@ <item android:state_window_focused="false" android:drawable="@color/transparent" /> <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> - <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_dark" /> - <item android:state_focused="true" android:state_enabled="false" android:drawable="@color/group_button_background_focused_holo_dark" /> - <item android:state_focused="true" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_dark" /> - <item android:state_focused="false" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_dark" /> - <item android:state_focused="true" android:drawable="@color/group_button_background_focused_holo_dark" /> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/btn_group_disabled_holo_dark" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/btn_group_disabled_holo_dark" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_dark" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_dark" /> + <item android:state_focused="true" android:drawable="@drawable/btn_group_focused_holo_dark" /> <item android:drawable="@color/transparent" /> </selector> diff --git a/core/res/res/drawable/group_button_background_holo_light.xml b/core/res/res/drawable/group_button_background_holo_light.xml index 94b3b5a..1e74ec7 100644 --- a/core/res/res/drawable/group_button_background_holo_light.xml +++ b/core/res/res/drawable/group_button_background_holo_light.xml @@ -19,10 +19,10 @@ <item android:state_window_focused="false" android:drawable="@color/transparent" /> <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> - <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_light" /> - <item android:state_focused="true" android:state_enabled="false" android:drawable="@color/group_button_background_focused_holo_light" /> - <item android:state_focused="true" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_light" /> - <item android:state_focused="false" android:state_pressed="true" android:drawable="@color/group_button_background_pressed_holo_light" /> - <item android:state_focused="true" android:drawable="@color/group_button_background_focused_holo_light" /> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/btn_group_disabled_holo_light" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/btn_group_disabled_holo_light" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_light" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/btn_group_pressed_holo_light" /> + <item android:state_focused="true" android:drawable="@drawable/btn_group_focused_holo_light" /> <item android:drawable="@color/transparent" /> </selector> diff --git a/core/res/res/drawable/item_background.xml b/core/res/res/drawable/item_background.xml new file mode 100644 index 0000000..a1c9ff8 --- /dev/null +++ b/core/res/res/drawable/item_background.xml @@ -0,0 +1,29 @@ +<?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:drawable="@color/transparent" /> + + <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_disabled" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_background_disabled" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition" /> + <item android:state_focused="true" android:drawable="@drawable/list_selector_background_focused" /> + <item android:drawable="@color/transparent" /> + +</selector> diff --git a/core/res/res/drawable/item_background_holo_dark.xml b/core/res/res/drawable/item_background_holo_dark.xml new file mode 100644 index 0000000..f119ec0 --- /dev/null +++ b/core/res/res/drawable/item_background_holo_dark.xml @@ -0,0 +1,28 @@ +<?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:drawable="@color/transparent" /> + + <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_dark" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_disabled_holo_dark" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_dark" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_dark" /> + <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" /> + <item android:drawable="@color/transparent" /> +</selector> diff --git a/core/res/res/drawable/item_background_holo_light.xml b/core/res/res/drawable/item_background_holo_light.xml new file mode 100644 index 0000000..d3d278a --- /dev/null +++ b/core/res/res/drawable/item_background_holo_light.xml @@ -0,0 +1,28 @@ +<?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:drawable="@color/transparent" /> + + <!-- Even though these two point to the same resource, have two states so the drawable will invalidate itself when coming out of pressed state. --> + <item android:state_focused="true" android:state_enabled="false" android:state_pressed="true" android:drawable="@drawable/list_selector_disabled_holo_light" /> + <item android:state_focused="true" android:state_enabled="false" android:drawable="@drawable/list_selector_disabled_holo_light" /> + <item android:state_focused="true" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_light" /> + <item android:state_focused="false" android:state_pressed="true" android:drawable="@drawable/list_selector_background_transition_holo_light" /> + <item android:state_focused="true" android:drawable="@drawable/list_focused_holo" /> + <item android:drawable="@color/transparent" /> +</selector> diff --git a/core/res/res/layout/action_menu_item_layout.xml b/core/res/res/layout/action_menu_item_layout.xml index 1f3117b..94fcc2f 100644 --- a/core/res/res/layout/action_menu_item_layout.xml +++ b/core/res/res/layout/action_menu_item_layout.xml @@ -18,6 +18,8 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center" + android:addStatesFromChildren="true" + android:background="?attr/selectableItemBackground" android:minWidth="64dip" android:minHeight="?attr/actionBarSize" android:paddingLeft="12dip" @@ -33,9 +35,9 @@ android:layout_height="wrap_content" android:layout_gravity="center" android:visibility="gone" - android:background="?attr/groupButtonBackground" android:textAppearance="?attr/textAppearanceMedium" style="?attr/buttonStyleSmall" + android:background="@null" android:paddingLeft="4dip" android:paddingRight="4dip" /> </com.android.internal.view.menu.ActionMenuItemView> diff --git a/core/res/res/layout/action_mode_close_item.xml b/core/res/res/layout/action_mode_close_item.xml index 0505f18..bc69890 100644 --- a/core/res/res/layout/action_mode_close_item.xml +++ b/core/res/res/layout/action_mode_close_item.xml @@ -20,7 +20,8 @@ android:layout_marginTop="12dip" android:layout_marginBottom="12dip" android:gravity="center" - android:showDividers="end"> + android:showDividers="end" + android:background="?android:attr/selectableItemBackground"> <Button android:id="@+id/action_mode_close_button" android:text="@string/action_mode_done" android:paddingLeft="16dip" diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 3f4635a..d5f1610 100755 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -571,6 +571,9 @@ <!-- Drawable for group button backgrounds --> <attr name="groupButtonBackground" format="reference" /> + <!-- Background drawable for standalone items that need focus/pressed states. --> + <attr name="selectableItemBackground" format="reference" /> + <!-- SearchView dropdown background --> <attr name="searchDropdownBackground" format="reference" /> </declare-styleable> diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml index 774c02d..21b810e 100644 --- a/core/res/res/values/colors.xml +++ b/core/res/res/values/colors.xml @@ -132,10 +132,10 @@ <color name="link_text_holo_light">#0000ee</color> <!-- Group buttons --> - <color name="group_button_background_pressed_holo_dark">#46c5c1ff</color> - <color name="group_button_background_focused_holo_dark">#2699cc00</color> + <color name="group_button_dialog_pressed_holo_dark">#46c5c1ff</color> + <color name="group_button_dialog_focused_holo_dark">#2699cc00</color> - <color name="group_button_background_pressed_holo_light">#ffffffff</color> - <color name="group_button_background_focused_holo_light">#4699cc00</color> + <color name="group_button_dialog_pressed_holo_light">#ffffffff</color> + <color name="group_button_dialog_focused_holo_light">#4699cc00</color> </resources> diff --git a/core/res/res/values/styles.xml b/core/res/res/values/styles.xml index 781dd2c..c441f5a 100644 --- a/core/res/res/values/styles.xml +++ b/core/res/res/values/styles.xml @@ -1250,15 +1250,19 @@ <item name="android:minHeight">48dip</item> <item name="android:paddingLeft">32dip</item> <item name="android:paddingRight">32dip</item> + <item name="android:paddingTop">4dip</item> + <item name="android:paddingBottom">4dip</item> </style> <style name="Widget.Holo.Button.Small"> <item name="android:background">@android:drawable/btn_default_holo_dark</item> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> <item name="android:textColor">@android:color/primary_text_holo_dark</item> - <item name="android:minHeight">40dip</item> + <item name="android:minHeight">48dip</item> <item name="android:paddingLeft">24dip</item> <item name="android:paddingRight">24dip</item> + <item name="android:paddingTop">4dip</item> + <item name="android:paddingBottom">4dip</item> </style> <style name="Widget.Holo.Button.Inset"> @@ -1279,6 +1283,7 @@ <style name="Widget.Holo.ButtonGroup" parent="Widget.ButtonGroup"> <item name="divider">?android:attr/dividerVertical</item> <item name="showDividers">middle</item> + <item name="android:background">@android:drawable/btn_default_holo_dark</item> </style> <style name="Widget.Holo.ButtonGroup.AlertDialog"> @@ -1483,6 +1488,7 @@ <style name="Widget.Holo.ActionButton.Overflow"> <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_dark</item> + <item name="android:background">?android:attr/selectableItemBackground</item> </style> <style name="Widget.Holo.ActionButton.TextButton" parent="Widget.Holo.ButtonBar.Button"> @@ -1529,14 +1535,18 @@ <item name="android:minHeight">48dip</item> <item name="android:paddingLeft">32dip</item> <item name="android:paddingRight">32dip</item> + <item name="android:paddingTop">4dip</item> + <item name="android:paddingBottom">4dip</item> </style> <style name="Widget.Holo.Light.Button.Small"> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> <item name="android:textColor">@android:color/primary_text_holo_light</item> - <item name="android:minHeight">40dip</item> + <item name="android:minHeight">48dip</item> <item name="android:paddingLeft">24dip</item> <item name="android:paddingRight">24dip</item> + <item name="android:paddingTop">4dip</item> + <item name="android:paddingBottom">4dip</item> </style> <style name="Widget.Holo.Light.Button.Inset"> @@ -1554,6 +1564,7 @@ </style> <style name="Widget.Holo.Light.ButtonGroup" parent="Widget.Holo.ButtonGroup"> + <item name="android:background">@android:drawable/btn_default_holo_light</item> </style> <style name="Widget.Holo.Light.ButtonGroup.AlertDialog"> @@ -1737,6 +1748,7 @@ <style name="Widget.Holo.Light.ActionButton.Overflow"> <item name="android:src">@android:drawable/ic_menu_moreoverflow_holo_light</item> + <item name="android:background">?android:attr/selectableItemBackground</item> </style> <style name="Widget.Holo.Light.ActionBarView_TabView" parent="Widget.ActionBarView_TabView"> diff --git a/core/res/res/values/themes.xml b/core/res/res/values/themes.xml index 7f6da2a..552e7e5 100644 --- a/core/res/res/values/themes.xml +++ b/core/res/res/values/themes.xml @@ -90,6 +90,7 @@ <item name="buttonStyleToggle">@android:style/Widget.Button.Toggle</item> <item name="groupButtonBackground">@null</item> + <item name="selectableItemBackground">@android:drawable/item_background</item> <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> @@ -569,7 +570,7 @@ <style name="Theme.IconMenu"> <!-- Menu/item attributes --> <item name="android:itemTextAppearance">@android:style/TextAppearance.Widget.IconMenu.Item</item> - <item name="android:itemBackground">@android:drawable/menu_selector</item> + <item name="android:selectableItemBackground">@android:drawable/menu_selector</item> <item name="android:itemIconDisabledAlpha">?android:attr/disabledAlpha</item> <item name="android:horizontalDivider">@android:drawable/divider_horizontal_dark</item> <item name="android:verticalDivider">@android:drawable/divider_vertical_dark</item> @@ -638,7 +639,7 @@ <item name="colorForeground">@android:color/bright_foreground_holo_dark</item> <item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_dark</item> <item name="colorBackground">@android:color/background_holo_dark</item> - <item name="colorBackgroundCacheHint">?android:attr/colorBackground</item> + <item name="colorBackgroundCacheHint">@android:color/transparent</item> <item name="disabledAlpha">0.5</item> <item name="backgroundDimAmount">0.6</item> @@ -698,6 +699,7 @@ <item name="buttonStyleToggle">@android:style/Widget.Holo.Button.Toggle</item> <item name="groupButtonBackground">@android:drawable/group_button_background_holo_dark</item> + <item name="selectableItemBackground">@android:drawable/item_background_holo_dark</item> <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> @@ -730,7 +732,7 @@ <item name="galleryItemBackground">@android:drawable/gallery_item_background</item> <!-- Window attributes --> - <item name="windowBackground">@android:drawable/screen_background_holo_dark</item> + <item name="windowBackground">@android:drawable/background_holo_dark</item> <item name="windowFrame">@null</item> <item name="windowNoTitle">false</item> <item name="windowFullscreen">false</item> @@ -871,7 +873,7 @@ <item name="colorForeground">@android:color/bright_foreground_holo_light</item> <item name="colorForegroundInverse">@android:color/bright_foreground_inverse_holo_light</item> <item name="colorBackground">@android:color/background_holo_light</item> - <item name="colorBackgroundCacheHint">?android:attr/colorBackground</item> + <item name="colorBackgroundCacheHint">@android:color/transparent</item> <item name="disabledAlpha">0.5</item> <item name="backgroundDimAmount">0.6</item> @@ -931,6 +933,7 @@ <item name="buttonStyleToggle">@android:style/Widget.Holo.Light.Button.Toggle</item> <item name="groupButtonBackground">@android:drawable/group_button_background_holo_light</item> + <item name="selectableItemBackground">@android:drawable/item_background_holo_light</item> <!-- List attributes --> <item name="listPreferredItemHeight">64dip</item> @@ -963,7 +966,7 @@ <item name="galleryItemBackground">@android:drawable/gallery_item_background</item> <!-- Window attributes --> - <item name="windowBackground">@android:drawable/screen_background_holo_light</item> + <item name="windowBackground">@android:drawable/background_holo_light</item> <item name="windowFrame">@null</item> <item name="windowNoTitle">false</item> <item name="windowFullscreen">false</item> @@ -1146,6 +1149,8 @@ <item name="android:windowActionModeOverlay">true</item> <item name="android:colorBackgroundCacheHint">@null</item> + + <item name="android:groupButtonBackground">?android:attr/selectableItemBackground</item> <item name="textAppearance">@android:style/TextAppearance.Holo</item> <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Inverse</item> @@ -1196,6 +1201,8 @@ <item name="android:colorBackgroundCacheHint">@null</item> + <item name="android:groupButtonBackground">?android:attr/selectableItemBackground</item> + <item name="textAppearance">@android:style/TextAppearance.Holo.Light</item> <item name="textAppearanceInverse">@android:style/TextAppearance.Holo.Light.Inverse</item> </style> diff --git a/docs/html/resources/resources_toc.cs b/docs/html/resources/resources_toc.cs index a1711b5..a2c94fe 100644 --- a/docs/html/resources/resources_toc.cs +++ b/docs/html/resources/resources_toc.cs @@ -85,6 +85,7 @@ </li><?cs /if ?> + <li> <h2><span class="en">More</span> </h2> diff --git a/docs/html/sdk/sdk_toc.cs b/docs/html/sdk/sdk_toc.cs index fdf4438..d202b50 100644 --- a/docs/html/sdk/sdk_toc.cs +++ b/docs/html/sdk/sdk_toc.cs @@ -1,5 +1,5 @@ <?cs if:!sdk.redirect ?> -<ul><?cs +<ul><?cs if:android.whichdoc == "online" ?> <li> <h2> @@ -35,7 +35,7 @@ </a></li> </ul> - </li><?cs + </li><?cs /if ?> <li> <h2> @@ -61,13 +61,13 @@ </li> </ul> <ul> - <li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a> <span class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>sdk/android-2.2.html">Android 2.2 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-2.1.html">Android 2.1 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-1.6.html">Android 1.6 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-1.5.html">Android 1.5 Platform</a></li> <li class="toggle-list"> <div><a href="#" onclick="toggle(this.parentNode.parentNode,true); return false;">Older Platforms</a></div> - <ul> + <ul> <li><a href="<?cs var:toroot ?>sdk/android-2.0.1.html">Android 2.0.1 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-2.0.html">Android 2.0 Platform</a></li> <li><a href="<?cs var:toroot ?>sdk/android-1.1.html">Android 1.1 Platform</a></li> @@ -75,8 +75,7 @@ </li> </ul> <ul> - <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r7</a> - <span class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>sdk/tools-notes.html">SDK Tools, r7</a></li> <li><a href="<?cs var:toroot ?>sdk/win-usb.html">USB Driver for Windows, r3</a> </li> @@ -116,8 +115,7 @@ <span style="display:none" class="zh-TW"></span> </h2> <ul> - <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r4b</a> - <span class="new">new!</span></li> + <li><a href="<?cs var:toroot ?>sdk/ndk/index.html">Android NDK, r4b</a></li> </ul> </li> <li> diff --git a/docs/html/videos/index.jd b/docs/html/videos/index.jd index 157c077..0274095 100644 --- a/docs/html/videos/index.jd +++ b/docs/html/videos/index.jd @@ -2,7 +2,7 @@ videos=true page.title=Videos @jd:body -<script src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js" type="text/javascript"></script>
+<script src="http://swfobject.googlecode.com/svn/trunk/swfobject/swfobject.js" type="text/javascript"></script> <script src="{@docRoot}assets/jquery-history.js" type="text/javascript"></script> <script type="text/javascript"> // for debugging in FF, so other browsers ignore the console commands. @@ -33,32 +33,32 @@ var playlists = { */ var playlistsWithTitleInDescription = "734A052F802C96B9"; -/* This 'featured' object defines the Feature Videos list. +/* This 'featured' object defines the Feature Videos list. * Each playlist ID is paired with a custom video description. */ var featured = { -// Android 2.0 Release - 'opZ69P-0Jbc' : "The Android 2.0 platform adds exciting new user features and developer APIs. Here's an introduction to what's new.", -// How to Make your Android UI Fast.. - 'N6YdwzAvwOA' : "Make your user interface fast, with more efficient AdapterViews, better bitmap scaling, faster redrawing, ViewStub layouts, fewer Views, and more.", -// How Do I Code Thee? - 'GARMe7Km_gk' : "If you'd like to augment your Android applications with pieces written in JavaScript or native code, watch this video." +// Android UI design patterns + 'M1ZBjlCRfz0' : "The Android user experience team provides suggestions for how to make your applications more useable and engaging.", +// The world of ListView + 'wDBM6wVEO70' : "ListView is a common widget that's customizable, but can be tricky to polish, so this talk shows how you can provide the best performance.", +// Debugging Arts of the Ninja Masters + 'Dgnx0E7m1GQ' : "The Android SDK includes tools to debug your apps like a ninja. Enter the dojo and become a master at debugging your apps." }; -
+ /* When an event on the browser history occurs (back, forward, load), - * load the video found in the URL hash - */
-$(window).history(function(e, hash) {
- if (location.href.indexOf("#v=") != -1) {
- videoId = location.href.split("#v=");
- clickVideo(videoId[1]); // click the link with a matching class
- }
+ * load the video found in the URL hash + */ +$(window).history(function(e, hash) { + if (location.href.indexOf("#v=") != -1) { + videoId = location.href.split("#v="); + clickVideo(videoId[1]); // click the link with a matching class + } }); /* Load a video into the player box. * @param id The YouTube video ID * @param title The video title to display in the player box (character escaped) - * @param autoplay Whether to automatically play the video + * @param autoplay Whether to automatically play the video */ function loadVideo(id, title, autoplay) { if($("." + id).hasClass("noplay")) { @@ -66,51 +66,51 @@ function loadVideo(id, title, autoplay) { autoplay = false; $("." + id).removeClass("noplay"); } - swfobject.embedSWF('http://www.youtube.com/v/' + id + '&rel=1&border=0&fs=1&autoplay=' + + swfobject.embedSWF('http://www.youtube.com/v/' + id + '&rel=1&border=0&fs=1&autoplay=' + (autoplay?1:0), 'player', '500', '334', '9.0.0', false, false, {allowfullscreen: 'true'}); $("#videoPlayerTitle").html("<h2>" + unescape(title) + "</h2>"); -
+ $.history.add('v=' + id); // add the current video to the browser history - document.getElementById("doc-content").scrollTop = 0; // scroll the window to the top + document.getElementById("doc-content").scrollTop = 0; // scroll the window to the top } /* Draw all videos from a playlist into a 'videoPreviews' list * @param data The feed data returned from the youtube request */ -function renderPlaylist(data) { +function renderPlaylist(data) { var MAX_DESC_LENGTH = 390; // the length at which we will trim the description var feed = data.feed; var entries = feed.entry || []; var playlistId = feed.yt$playlistId.$t; - + var ul = $('<ul class="videoPreviews" />'); - + // Loop through each entry (each video) and add it to the 'videoPreviews' list for (var i = 0; i < entries.length; i++) { var entry = entries[i]; - + var title = entry.title.$t; var id = entry.media$group.yt$videoid.$t; var thumbUrl = entry.media$group.media$thumbnail[0].url; var fullDescription = entry.media$group.media$description.$t; var playerUrl = entry.media$group.media$content[0].url; - + // Check whether this playlist includes the video title inside the description meta-data, so we can remove it if (playlistsWithTitleInDescription.indexOf(playlistId) != -1) { var lines = fullDescription.split("\n"); // If the first line includes the first 17 chars from the title, let's use the title from the description instead (because it's a more complete title) // This accounts for, literally, "Google I/O 2009 -", which is (so far) the min AND max for properly identifying a title in the only playlist with titles in the description - if (lines[0].indexOf(title.slice(0,16)) != -1) { - h3Title = "<h3>" + lines[0] + "</h3>"; + if (lines[0].indexOf(title.slice(0,16)) != -1) { + h3Title = "<h3>" + lines[0] + "</h3>"; if (lines[2].length < 30) lines = lines.slice(3); // also, if the second line is very short (the speaker name), slice it out too else lines = lines.slice(1); // otherwise, slice after the first line } fullDescription = lines.join(""); - } - + } + var shortDescription = fullDescription.substr(0, MAX_DESC_LENGTH); shortDescription += shortDescription.length == MAX_DESC_LENGTH ? "..." : ""; // add ellipsis if we've chopped the description - + var img = $('<img src="' + thumbUrl + '" width="120" height="90"/>'); var a = $('<a class="' + id + '" href="#" onclick="loadVideo(\'' + id + '\',\'' + escape(title) + '\',true); return setSelected(this);" />'); var pShortDescription = $('<p class="short">' + shortDescription + '</p>'); @@ -118,19 +118,19 @@ function renderPlaylist(data) { var h3Title = "<h3>" + title + "</h3>"; var pToggle = "<p class='toggle'><a href='#' onclick='return toggleDescription(this)'><span class='more'>more</span><span class='less'>less</span></a></p>"; var li = $('<li/>'); - + li.append(a); a.append(img).append(h3Title).append(pShortDescription); - + // Add the full description and "more/less" toggle, if necessary if (fullDescription.length > MAX_DESC_LENGTH) { a.append(pFullDescription); li.append(pToggle); } - + ul.append(li); } - + // Now add the 'videoPreviews' list to the page, and be sure we put it in the right tab // This is the part that allows us to put multiple playlists in one tab for (var x in playlists) { @@ -141,13 +141,13 @@ function renderPlaylist(data) { break; } } - } + } } -/* Draw a featured video into the existing 'videoPreviews' list +/* Draw a featured video into the existing 'videoPreviews' list * @param data The video data returned from the youtube request */ -function renderFeatured(data) { +function renderFeatured(data) { var MAX_TITLE_LENGTH = 48; var entry = data.entry || []; var id = entry.media$group.yt$videoid.$t; @@ -155,15 +155,15 @@ function renderFeatured(data) { var title = entry.title.$t; var thumbUrl = entry.media$group.media$thumbnail[0].url; var playerUrl = entry.media$group.media$content[0].url; - + var ellipsis = title.length > MAX_TITLE_LENGTH ? "..." : ""; - + var h3Title = "<h3>"+ title.substr(0,MAX_TITLE_LENGTH) + ellipsis + "</h3>"; var img = $('<img src="' + thumbUrl + '" width="120" height="90"/>'); var p = $('<p>' + description + '</p>'); var a = $('<a class="' + id + '" href="#" onclick="loadVideo(\'' + id + '\',\'' + title + '\',true); return setSelected(this);" />'); var li = $("<li/>"); - + a.append(h3Title).append(img).append(p); li.append(a); @@ -175,8 +175,8 @@ function showPlaylists() { for (var x in playlists) { var ids = playlists[x].ids; for (var i in ids) { - var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/playlists/" - + ids[i] + + var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/playlists/" + + ids[i] + "?v=2&alt=json-in-script&callback=renderPlaylist'><\/script>"; $("body").append(script); } @@ -186,14 +186,14 @@ function showPlaylists() { /* Request the featured videos from YouTube */ function showFeatured() { for (var id in featured) { - var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/videos/" - + id + + var script = "<script type='text/javascript' src='http://gdata.youtube.com/feeds/api/videos/" + + id + "?v=2&alt=json-in-script&callback=renderFeatured'><\/script>"; $("body").append(script); } } -/* Reveal a tab (playlist) box +/* Reveal a tab (playlist) box * @param name The name of the tab */ function showBox(name) { @@ -202,7 +202,7 @@ function showBox(name) { return false; } -/* Highlight a video thumbnail, including all duplicates that there may be +/* Highlight a video thumbnail, including all duplicates that there may be * @param link The link <a> object that was clicked */ function setSelected(link) { @@ -220,8 +220,8 @@ function setSelected(link) { return false; } -/* Reveal and hide the long/short descriptions for a video in the playlist - * @param link The link <a> object that was clicked +/* Reveal and hide the long/short descriptions for a video in the playlist + * @param link The link <a> object that was clicked */ function toggleDescription(link) { var aToggle = $(link); @@ -238,9 +238,9 @@ function toggleDescription(link) { } /* Add actions to the page onload event so that we load a video right away */ -addLoadEvent(function () {
- // if there's a video url in the hash, click that video
- if (location.href.indexOf("#v=") != -1) {
+addLoadEvent(function () { + // if there's a video url in the hash, click that video + if (location.href.indexOf("#v=") != -1) { var videoId = location.href.split("#v="); clickVideo(videoId[1]); } else { // otherwise, click the default video @@ -251,20 +251,20 @@ addLoadEvent(function () { var clickVideoAttempts = 0; // Used with clickVideo() -/* Click a video in order to load it and select it +/* Click a video in order to load it and select it * @param videoId The ID of the video to click */ function clickVideo(videoId) { if ($("." + videoId).length != 0) { // if we find the video, click it and return - $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
+ $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo) $("." + videoId + ":first").click(); return; } else { // if we don't find it, increment clickVideoAttempts console.log("video NOT found: " + videoId); clickVideoAttempts++; } - - // if we don't find it after 20 attempts (2 seconds), click the first feature video
+ + // if we don't find it after 20 attempts (2 seconds), click the first feature video if (clickVideoAttempts > 10) { console.log("video never found, clicking default..."); clickVideoAttempts = 0; @@ -278,15 +278,15 @@ function clickVideo(videoId) { function clickDefaultVideo() { if ($("#mainBodyRight .videoPreviews a:first").length != 0) { var videoId = $("#mainBodyRight .videoPreviews a:first").attr("class"); - $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo)
+ $("." + videoId).addClass("noplay"); // add class to indicate we should NOT autoplay (class removed by loadVideo) $("." + videoId + ":first").click(); return; } else { // if we don't find it, increment clickVideoAttempts console.log("default video NOT found"); clickVideoAttempts++; } - - // if we don't find it after 50 attempts (5 seconds), just fail
+ + // if we don't find it after 50 attempts (5 seconds), just fail if (clickVideoAttempts > 50) { console.log("default video never found..."); } else { // try again after 100 milliseconds @@ -296,8 +296,8 @@ function clickDefaultVideo() { </script> <div id="mainBodyFixed"> - - <div id="mainBodyLeft" class="videoPlayer" > + + <div id="mainBodyLeft" class="videoPlayer" > <div id="videoPlayerBox"> <div id="videoBorder"> <div id="videoPlayerTitle"></div> @@ -307,32 +307,32 @@ function clickDefaultVideo() { </div> </div> </div><!-- end mainBodyLeft --> - + <div id="mainBodyRight" class="videoPlayer"> <h2>Featured Videos</h2> <ul class="videoPreviews"></ul> </div><!-- end mainBodyRight --> - + <ul id="videoTabs"> <li id="aboutTab" class="selected"><a onclick="return showBox('about');" href="#">About the Platform</a></li> <li id="developertipsTab"><a onclick="return showBox('developertips');" href="#">Developer Tips</a></li> <li id="googleioTab"><a onclick="return showBox('googleio');" href="#">Google I/O Sessions</a></li> <li id="developersandboxTab"><a onclick="return showBox('developersandbox');" href="#">Developer Sandbox</a></li> </ul> - + <div id="videos"> <div id="aboutBox" class="selected"></div> <div id="developertipsBox"></div> <div id="googleioBox"></div> <div id="developersandboxBox"></div> </div> - + </div><!-- end mainBodyFixed --> - + <script type="text/javascript"> // Initialization actions showFeatured(); // load featured videos showPlaylists(); // load playlists </script> - + diff --git a/libs/hwui/Caches.cpp b/libs/hwui/Caches.cpp index a4def0b..e0094d8 100644 --- a/libs/hwui/Caches.cpp +++ b/libs/hwui/Caches.cpp @@ -43,7 +43,7 @@ Caches::Caches(): Singleton<Caches>(), blend(false), lastSrcMode(GL_ZERO), glBindBuffer(GL_ARRAY_BUFFER, meshBuffer); glBufferData(GL_ARRAY_BUFFER, sizeof(gMeshVertices), gMeshVertices, GL_STATIC_DRAW); - currentBuffer = meshBuffer; + mCurrentBuffer = meshBuffer; } /** @@ -57,9 +57,9 @@ void Caches::bindMeshBuffer() { * Binds the specified VBO. */ void Caches::bindMeshBuffer(const GLuint buffer) { - if (currentBuffer != buffer) { + if (mCurrentBuffer != buffer) { glBindBuffer(GL_ARRAY_BUFFER, buffer); - currentBuffer = buffer; + mCurrentBuffer = buffer; } } @@ -67,9 +67,9 @@ void Caches::bindMeshBuffer(const GLuint buffer) { * Unbinds the VBO used to render simple textured quads. */ void Caches::unbindMeshBuffer() { - if (currentBuffer) { + if (mCurrentBuffer) { glBindBuffer(GL_ARRAY_BUFFER, 0); - currentBuffer = 0; + mCurrentBuffer = 0; } } diff --git a/libs/hwui/Caches.h b/libs/hwui/Caches.h index 79644a5..aff5366 100644 --- a/libs/hwui/Caches.h +++ b/libs/hwui/Caches.h @@ -79,7 +79,9 @@ class Caches: public Singleton<Caches> { friend class Singleton<Caches>; - CacheLogger logger; + CacheLogger mlogger; + + GLuint mCurrentBuffer; public: void bindMeshBuffer(); @@ -92,7 +94,6 @@ public: Program* currentProgram; GLuint meshBuffer; - GLuint currentBuffer; TextureCache textureCache; LayerCache layerCache; diff --git a/libs/hwui/OpenGLRenderer.cpp b/libs/hwui/OpenGLRenderer.cpp index 7495a06..8592511 100644 --- a/libs/hwui/OpenGLRenderer.cpp +++ b/libs/hwui/OpenGLRenderer.cpp @@ -644,7 +644,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, float left, float top, SkPaint } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -661,7 +661,7 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, SkMatrix* matrix, SkPaint* pai } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); @@ -677,9 +677,10 @@ void OpenGLRenderer::drawBitmap(SkBitmap* bitmap, } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); const float width = texture->width; const float height = texture->height; @@ -711,9 +712,10 @@ void OpenGLRenderer::drawPatch(SkBitmap* bitmap, const int32_t* xDivs, const int } glActiveTexture(GL_TEXTURE0); - const Texture* texture = mCaches.textureCache.get(bitmap); + Texture* texture = mCaches.textureCache.get(bitmap); if (!texture) return; const AutoTexture autoCleanup(texture); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); int alpha; SkXfermode::Mode mode; @@ -1046,7 +1048,7 @@ void OpenGLRenderer::setupTextureAlpha8(GLuint texture, uint32_t width, uint32_t // Build and use the appropriate shader useProgram(mCaches.programCache.get(description)); - bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, textureUnit); + bindTexture(texture, textureUnit); glUniform1i(mCaches.currentProgram->getUniform("sampler"), textureUnit); int texCoordsSlot = mCaches.currentProgram->getAttrib("texCoords"); @@ -1220,11 +1222,13 @@ void OpenGLRenderer::setupColorRect(float left, float top, float right, float bo } void OpenGLRenderer::drawTextureRect(float left, float top, float right, float bottom, - const Texture* texture, SkPaint* paint) { + Texture* texture, SkPaint* paint) { int alpha; SkXfermode::Mode mode; getAlphaAndMode(paint, &alpha, &mode); + setTextureWrapModes(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE); + drawTextureMesh(left, top, right, bottom, texture->id, alpha / 255.0f, mode, texture->blend, (GLvoid*) NULL, (GLvoid*) gMeshTextureOffset, GL_TRIANGLE_STRIP, gMeshCount); @@ -1263,7 +1267,7 @@ void OpenGLRenderer::drawTextureMesh(float left, float top, float right, float b } // Texture - bindTexture(texture, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_EDGE, 0); + bindTexture(texture); glUniform1i(mCaches.currentProgram->getUniform("sampler"), 0); // Always premultiplied @@ -1380,11 +1384,29 @@ SkXfermode::Mode OpenGLRenderer::getXfermode(SkXfermode* mode) { return mode->fMode; } -void OpenGLRenderer::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { +void OpenGLRenderer::bindTexture(GLuint texture, GLuint textureUnit) { glActiveTexture(gTextureUnits[textureUnit]); glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); +} + +void OpenGLRenderer::setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT, + GLuint textureUnit) { + bool bound = false; + if (wrapS != texture->wrapS) { + glActiveTexture(gTextureUnits[textureUnit]); + glBindTexture(GL_TEXTURE_2D, texture->id); + bound = true; + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + texture->wrapS = wrapS; + } + if (wrapT != texture->wrapT) { + if (!bound) { + glActiveTexture(gTextureUnits[textureUnit]); + glBindTexture(GL_TEXTURE_2D, texture->id); + } + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + texture->wrapT = wrapT; + } } }; // namespace uirenderer diff --git a/libs/hwui/OpenGLRenderer.h b/libs/hwui/OpenGLRenderer.h index b7615fe..07188d4 100644 --- a/libs/hwui/OpenGLRenderer.h +++ b/libs/hwui/OpenGLRenderer.h @@ -231,7 +231,7 @@ private: * @param paint The paint containing the alpha, blending mode, etc. */ void drawTextureRect(float left, float top, float right, float bottom, - const Texture* texture, SkPaint* paint); + Texture* texture, SkPaint* paint); /** * Draws a textured mesh with the specified texture. If the indices are omitted, @@ -360,9 +360,11 @@ private: inline void getAlphaAndMode(SkPaint* paint, int* alpha, SkXfermode::Mode* mode); /** - * Binds the specified texture with the specified wrap modes. + * Binds the specified texture to the specified texture unit. */ - inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit = 0); + inline void bindTexture(GLuint texture, GLuint textureUnit = 0); + inline void setTextureWrapModes(Texture* texture, GLenum wrapS, GLenum wrapT, + GLuint textureUnit = 0); /** * Enable or disable blending as necessary. This function sets the appropriate diff --git a/libs/hwui/Patch.cpp b/libs/hwui/Patch.cpp index 253a19b..3d21431 100644 --- a/libs/hwui/Patch.cpp +++ b/libs/hwui/Patch.cpp @@ -26,8 +26,6 @@ namespace android { namespace uirenderer { -class Caches; - /////////////////////////////////////////////////////////////////////////////// // Constructors/destructor /////////////////////////////////////////////////////////////////////////////// diff --git a/libs/hwui/SkiaShader.cpp b/libs/hwui/SkiaShader.cpp index fa85d20..e7e1187 100644 --- a/libs/hwui/SkiaShader.cpp +++ b/libs/hwui/SkiaShader.cpp @@ -63,11 +63,17 @@ void SkiaShader::setupProgram(Program* program, const mat4& modelView, const Sna GLuint* textureUnit) { } -void SkiaShader::bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { +void SkiaShader::bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit) { glActiveTexture(gTextureUnitsMap[textureUnit]); - glBindTexture(GL_TEXTURE_2D, texture); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + glBindTexture(GL_TEXTURE_2D, texture->id); + if (wrapS != texture->wrapS) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapS); + texture->wrapS = wrapS; + } + if (wrapT != texture->wrapT) { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapT); + texture->wrapT = wrapT; + } } void SkiaShader::computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView) { @@ -86,7 +92,7 @@ SkiaBitmapShader::SkiaBitmapShader(SkBitmap* bitmap, SkShader* key, SkShader::Ti } void SkiaBitmapShader::describe(ProgramDescription& description, const Extensions& extensions) { - const Texture* texture = mTextureCache->get(mBitmap); + Texture* texture = mTextureCache->get(mBitmap); if (!texture) return; mTexture = texture; @@ -114,7 +120,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, GLuint textureSlot = (*textureUnit)++; glActiveTexture(gTextureUnitsMap[textureSlot]); - const Texture* texture = mTexture; + Texture* texture = mTexture; mTexture = NULL; if (!texture) return; const AutoTexture autoCleanup(texture); @@ -126,7 +132,7 @@ void SkiaBitmapShader::setupProgram(Program* program, const mat4& modelView, computeScreenSpaceMatrix(textureTransform, modelView); // Uniforms - bindTexture(texture->id, mWrapS, mWrapT, textureSlot); + bindTexture(texture, mWrapS, mWrapT, textureSlot); glUniform1i(program->getUniform("bitmapSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("textureTransform"), 1, GL_FALSE, &textureTransform.data[0]); @@ -198,7 +204,7 @@ void SkiaLinearGradientShader::setupProgram(Program* program, const mat4& modelV computeScreenSpaceMatrix(screenSpace, modelView); // Uniforms - bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); + bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot); glUniform1i(program->getUniform("gradientSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } @@ -291,7 +297,7 @@ void SkiaSweepGradientShader::setupProgram(Program* program, const mat4& modelVi computeScreenSpaceMatrix(screenSpace, modelView); // Uniforms - bindTexture(texture->id, gTileModes[mTileX], gTileModes[mTileY], textureSlot); + bindTexture(texture, gTileModes[mTileX], gTileModes[mTileY], textureSlot); glUniform1i(program->getUniform("gradientSampler"), textureSlot); glUniformMatrix4fv(program->getUniform("screenSpace"), 1, GL_FALSE, &screenSpace.data[0]); } diff --git a/libs/hwui/SkiaShader.h b/libs/hwui/SkiaShader.h index 011991a..4cd1b8b 100644 --- a/libs/hwui/SkiaShader.h +++ b/libs/hwui/SkiaShader.h @@ -97,7 +97,7 @@ struct SkiaShader { void computeScreenSpaceMatrix(mat4& screenSpace, const mat4& modelView); protected: - inline void bindTexture(GLuint texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit); + inline void bindTexture(Texture* texture, GLenum wrapS, GLenum wrapT, GLuint textureUnit); Type mType; SkShader* mKey; @@ -138,7 +138,7 @@ private: } SkBitmap* mBitmap; - const Texture* mTexture; + Texture* mTexture; GLenum mWrapS; GLenum mWrapT; }; // struct SkiaBitmapShader diff --git a/libs/hwui/Texture.h b/libs/hwui/Texture.h index 817f143..755074d 100644 --- a/libs/hwui/Texture.h +++ b/libs/hwui/Texture.h @@ -29,6 +29,8 @@ struct Texture { Texture() { cleanup = false; bitmapSize = 0; + wrapS = GL_CLAMP_TO_EDGE; + wrapT = GL_CLAMP_TO_EDGE; } /** @@ -59,6 +61,12 @@ struct Texture { * Optional, size of the original bitmap. */ uint32_t bitmapSize; + + /** + * Last wrap modes set on this texture. Defaults to GL_CLAMP_TO_EDGE. + */ + GLenum wrapS; + GLenum wrapT; }; // struct Texture class AutoTexture { diff --git a/libs/ui/InputDispatcher.cpp b/libs/ui/InputDispatcher.cpp index 629234b..4c86ebe 100644 --- a/libs/ui/InputDispatcher.cpp +++ b/libs/ui/InputDispatcher.cpp @@ -1163,7 +1163,10 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime, // If the pointer is not currently down, then ignore the event. if (! mTempTouchState.down) { - LOGI("Dropping event because the pointer is not down."); +#if DEBUG_INPUT_DISPATCHER_POLICY + LOGD("Dropping event because the pointer is not down or we previously " + "dropped the pointer down event."); +#endif injectionResult = INPUT_EVENT_INJECTION_FAILED; goto Failed; } @@ -2775,7 +2778,7 @@ void InputDispatcher::dumpDispatchStateLocked(String8& dump) { dump.append(INDENT "ActiveConnections:\n"); for (size_t i = 0; i < mActiveConnections.size(); i++) { const Connection* connection = mActiveConnections[i]; - dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u" + dump.appendFormat(INDENT2 "%d: '%s', status=%s, outboundQueueLength=%u, " "inputState.isNeutral=%s\n", i, connection->getInputChannelName(), connection->getStatusLabel(), connection->outboundQueue.count(), diff --git a/media/java/android/media/videoeditor/VideoEditorTestImpl.java b/media/java/android/media/videoeditor/VideoEditorTestImpl.java index f4842b5..505b93e 100644 --- a/media/java/android/media/videoeditor/VideoEditorTestImpl.java +++ b/media/java/android/media/videoeditor/VideoEditorTestImpl.java @@ -1155,12 +1155,18 @@ public class VideoEditorTestImpl implements VideoEditor { private void removeAdjacentTransitions(MediaItem mediaItem) { final Transition beginTransition = mediaItem.getBeginTransition(); if (beginTransition != null) { + if (beginTransition.getAfterMediaItem() != null) { + beginTransition.getAfterMediaItem().setEndTransition(null); + } beginTransition.invalidate(); mTransitions.remove(beginTransition); } final Transition endTransition = mediaItem.getEndTransition(); if (endTransition != null) { + if (endTransition.getBeforeMediaItem() != null) { + endTransition.getBeforeMediaItem().setBeginTransition(null); + } endTransition.invalidate(); mTransitions.remove(endTransition); } diff --git a/media/libmediaplayerservice/StagefrightRecorder.cpp b/media/libmediaplayerservice/StagefrightRecorder.cpp index ec2449d..913d953 100644 --- a/media/libmediaplayerservice/StagefrightRecorder.cpp +++ b/media/libmediaplayerservice/StagefrightRecorder.cpp @@ -165,7 +165,8 @@ status_t StagefrightRecorder::setVideoSize(int width, int height) { status_t StagefrightRecorder::setVideoFrameRate(int frames_per_second) { LOGV("setVideoFrameRate: %d", frames_per_second); - if (frames_per_second <= 0 || frames_per_second > 30) { + if ((frames_per_second <= 0 && frames_per_second != -1) || + frames_per_second > 120) { LOGE("Invalid video frame rate: %d", frames_per_second); return BAD_VALUE; } @@ -960,7 +961,7 @@ void StagefrightRecorder::clipVideoFrameRate() { "enc.vid.fps.min", mVideoEncoder); int maxFrameRate = mEncoderProfiles->getVideoEncoderParamByName( "enc.vid.fps.max", mVideoEncoder); - if (mFrameRate < minFrameRate) { + if (mFrameRate < minFrameRate && mFrameRate != -1) { LOGW("Intended video encoding frame rate (%d fps) is too small" " and will be set to (%d fps)", mFrameRate, minFrameRate); mFrameRate = minFrameRate; @@ -1035,6 +1036,10 @@ void StagefrightRecorder::clipVideoFrameHeight() { } status_t StagefrightRecorder::setupCameraSource(sp<CameraSource> *cameraSource) { + status_t err = OK; + if ((err = checkVideoEncoderCapabilities()) != OK) { + return err; + } Size videoSize; videoSize.width = mVideoWidth; videoSize.height = mVideoHeight; @@ -1050,6 +1055,18 @@ status_t StagefrightRecorder::setupCameraSource(sp<CameraSource> *cameraSource) } CHECK(*cameraSource != NULL); + // When frame rate is not set, the actual frame rate will be set to + // the current frame rate being used. + if (mFrameRate == -1) { + int32_t frameRate = 0; + CHECK ((*cameraSource)->getFormat()->findInt32( + kKeySampleRate, &frameRate)); + LOGI("Frame rate is not explicitly set. Use the current frame " + "rate (%d fps)", frameRate); + mFrameRate = frameRate; + } + + CHECK(mFrameRate != -1); return OK; } @@ -1371,7 +1388,7 @@ status_t StagefrightRecorder::reset() { mVideoHeight = 144; mAuxVideoWidth = 176; mAuxVideoHeight = 144; - mFrameRate = 20; + mFrameRate = -1; mVideoBitRate = 192000; mAuxVideoBitRate = 192000; mSampleRate = 8000; diff --git a/media/libstagefright/CameraSource.cpp b/media/libstagefright/CameraSource.cpp index 95afb1d8..159d937 100644 --- a/media/libstagefright/CameraSource.cpp +++ b/media/libstagefright/CameraSource.cpp @@ -313,6 +313,20 @@ status_t CameraSource::configureCamera( } if (frameRate != -1) { + CHECK(frameRate > 0 && frameRate <= 120); + const char* supportedFrameRates = + params->get(CameraParameters::KEY_SUPPORTED_PREVIEW_FRAME_RATES); + CHECK(supportedFrameRates != NULL); + LOGV("Supported frame rates: %s", supportedFrameRates); + char buf[4]; + snprintf(buf, 4, "%d", frameRate); + if (strstr(supportedFrameRates, buf) == NULL) { + LOGE("Requested frame rate (%d) is not supported: %s", + frameRate, supportedFrameRates); + return BAD_VALUE; + } + + // The frame rate is supported, set the camera to the requested value. params->setPreviewFrameRate(frameRate); isCameraParamChanged = true; } else { // frameRate == -1 @@ -517,6 +531,7 @@ status_t CameraSource::init( mMeta->setInt32(kKeyHeight, mVideoSize.height); mMeta->setInt32(kKeyStride, mVideoSize.width); mMeta->setInt32(kKeySliceHeight, mVideoSize.height); + mMeta->setInt32(kKeySampleRate, mVideoFrameRate); return OK; } diff --git a/media/libstagefright/OMXCodec.cpp b/media/libstagefright/OMXCodec.cpp index 2e368b6..2520f46 100644 --- a/media/libstagefright/OMXCodec.cpp +++ b/media/libstagefright/OMXCodec.cpp @@ -156,19 +156,15 @@ static const CodecInfo kDecoderInfo[] = { // { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.Nvidia.mp3.decoder" }, // { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.TI.MP3.decode" }, { MEDIA_MIMETYPE_AUDIO_MPEG, "MP3Decoder" }, -// { MEDIA_MIMETYPE_AUDIO_MPEG, "OMX.PV.mp3dec" }, // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.TI.AMR.decode" }, // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amr.decoder" }, { MEDIA_MIMETYPE_AUDIO_AMR_NB, "AMRNBDecoder" }, -// { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.PV.amrdec" }, // { MEDIA_MIMETYPE_AUDIO_AMR_NB, "OMX.Nvidia.amrwb.decoder" }, { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.TI.WBAMR.decode" }, { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBDecoder" }, -// { MEDIA_MIMETYPE_AUDIO_AMR_WB, "OMX.PV.amrdec" }, // { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.Nvidia.aac.decoder" }, { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.decode" }, { MEDIA_MIMETYPE_AUDIO_AAC, "AACDecoder" }, -// { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacdec" }, { MEDIA_MIMETYPE_AUDIO_G711_ALAW, "G711Decoder" }, { MEDIA_MIMETYPE_AUDIO_G711_MLAW, "G711Decoder" }, // { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.decode" }, @@ -177,20 +173,17 @@ static const CodecInfo kDecoderInfo[] = { { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.Decoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Decoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Decoder" }, -// { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4dec" }, // { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.decode" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.decoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.decoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Decoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Decoder" }, -// { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263dec" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.decode" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.decoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.decoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.Decoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Decoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "AVCDecoder" }, -// { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcdec" }, { MEDIA_MIMETYPE_AUDIO_VORBIS, "VorbisDecoder" }, { MEDIA_MIMETYPE_VIDEO_VPX, "VPXDecoder" }, }; @@ -202,28 +195,24 @@ static const CodecInfo kEncoderInfo[] = { { MEDIA_MIMETYPE_AUDIO_AMR_WB, "AMRWBEncoder" }, { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.TI.AAC.encode" }, { MEDIA_MIMETYPE_AUDIO_AAC, "AACEncoder" }, -// { MEDIA_MIMETYPE_AUDIO_AAC, "OMX.PV.aacenc" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.7x30.video.encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.qcom.video.encoder.mpeg4" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.TI.Video.encoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.Nvidia.mp4.encoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.SEC.MPEG4.Encoder" }, { MEDIA_MIMETYPE_VIDEO_MPEG4, "M4vH263Encoder" }, -// { MEDIA_MIMETYPE_VIDEO_MPEG4, "OMX.PV.mpeg4enc" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.7x30.video.encoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.qcom.video.encoder.h263" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.TI.Video.encoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.Nvidia.h263.encoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "OMX.SEC.H263.Encoder" }, { MEDIA_MIMETYPE_VIDEO_H263, "M4vH263Encoder" }, -// { MEDIA_MIMETYPE_VIDEO_H263, "OMX.PV.h263enc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.7x30.video.encoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.qcom.video.encoder.avc" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.TI.Video.encoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.Nvidia.h264.encoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.SEC.AVC.Encoder" }, { MEDIA_MIMETYPE_VIDEO_AVC, "AVCEncoder" }, -// { MEDIA_MIMETYPE_VIDEO_AVC, "OMX.PV.avcenc" }, }; #undef OPTIONAL @@ -318,16 +307,15 @@ static void InitOMXParams(T *params) { } static bool IsSoftwareCodec(const char *componentName) { - if (!strncmp("OMX.PV.", componentName, 7)) { - return true; + if (!strncmp("OMX.", componentName, 4)) { + return false; } - return false; + return true; } // A sort order in which non-OMX components are first, -// followed by software codecs, i.e. OMX.PV.*, followed -// by all the others. +// followed by software codecs, and followed by all the others. static int CompareSoftwareCodecsFirst( const String8 *elem1, const String8 *elem2) { bool isNotOMX1 = strncmp(elem1->string(), "OMX.", 4); @@ -368,9 +356,6 @@ uint32_t OMXCodec::getComponentQuirks( quirks |= kDecoderLiesAboutNumberOfChannels; } - if (!strcmp(componentName, "OMX.PV.avcdec")) { - quirks |= kWantsNALFragments; - } if (!strcmp(componentName, "OMX.TI.MP3.decode")) { quirks |= kNeedsFlushBeforeDisable; quirks |= kDecoderLiesAboutNumberOfChannels; @@ -3881,17 +3866,8 @@ void OMXCodec::initOutputFormat(const sp<MetaData> &inputFormat) { CHECK(!"Unknown compression format."); } - if (!strcmp(mComponentName, "OMX.PV.avcdec")) { - // This component appears to be lying to me. - mOutputFormat->setInt32( - kKeyWidth, (video_def->nFrameWidth + 15) & -16); - mOutputFormat->setInt32( - kKeyHeight, (video_def->nFrameHeight + 15) & -16); - } else { - mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); - mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); - } - + mOutputFormat->setInt32(kKeyWidth, video_def->nFrameWidth); + mOutputFormat->setInt32(kKeyHeight, video_def->nFrameHeight); mOutputFormat->setInt32(kKeyColorFormat, video_def->eColorFormat); break; } diff --git a/opengl/java/android/opengl/GLSurfaceView.java b/opengl/java/android/opengl/GLSurfaceView.java index 41207f7..c937b06 100644 --- a/opengl/java/android/opengl/GLSurfaceView.java +++ b/opengl/java/android/opengl/GLSurfaceView.java @@ -530,7 +530,6 @@ public class GLSurfaceView extends SurfaceView implements SurfaceHolder.Callback @Override protected void onDetachedFromWindow() { super.onDetachedFromWindow(); - mGLThread.requestExitAndWait(); } // ---------------------------------------------------------------------- diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_panel_recents_bg.9.png b/packages/SystemUI/res/drawable-mdpi/sysbar_panel_recents_bg.9.png Binary files differnew file mode 100644 index 0000000..85726d2 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_panel_recents_bg.9.png diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml index 429fdf2..dbe4167 100644 --- a/packages/SystemUI/res/layout-xlarge/status_bar.xml +++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml @@ -146,7 +146,7 @@ android:background="@drawable/ic_sysbar_icon_bg" systemui:keyCode="3" /> - <ImageButton android:id="@+id/recent" + <ImageButton android:id="@+id/recent_apps" android:layout_width="wrap_content" android:layout_height="match_parent" android:src="@drawable/ic_sysbar_recent" diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_recent.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_recent.xml new file mode 100644 index 0000000..2f9e0d7 --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_recent.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 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. +*/ +--> + +<com.android.systemui.statusbar.tablet.RecentAppsPanel + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:background="@drawable/sysbar_panel_recents_bg" + android:orientation="vertical"> + + <TextView android:id="@+id/recents_no_recents" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:text="@string/recent_tasks_empty" + android:gravity="center_horizontal|center_vertical" + android:visibility="gone"> + </TextView> + + <HorizontalScrollView android:id="@+id/scroll_view" + android:layout_width="match_parent" + android:layout_height="wrap_content"> + + <LinearLayout android:id="@+id/recents_container" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:gravity="right" + android:orientation="horizontal" + /> + + </HorizontalScrollView> + +</com.android.systemui.statusbar.tablet.RecentAppsPanel> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java new file mode 100644 index 0000000..6797958 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/RecentAppsPanel.java @@ -0,0 +1,167 @@ +/* + * 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.systemui.statusbar.tablet; + +import java.util.ArrayList; +import java.util.List; + +import android.app.ActivityManager; +import android.bluetooth.BluetoothAdapter; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.drawable.Drawable; +import android.media.AudioManager; +import android.net.wifi.WifiManager; +import android.util.AttributeSet; +import android.util.Log; +import android.view.View; +import android.view.ViewGroup; +import android.view.View.OnClickListener; +import android.widget.BaseAdapter; +import android.widget.Gallery; +import android.widget.HorizontalScrollView; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; +import android.widget.Toast; + +import com.android.systemui.R; + +public class RecentAppsPanel extends LinearLayout implements StatusBarPanel, OnClickListener { + private static final String TAG = "RecentAppsPanel"; + private static final boolean DEBUG = TabletStatusBarService.DEBUG; + private static final int MAX_RECENT_TASKS = 20; + private static final float ITEM_WIDTH = 75; + private static final float ITEM_HEIGHT = 75; + private TabletStatusBarService mBar; + private TextView mNoRecents; + private LinearLayout mRecentsContainer; + private float mDensity; + private HorizontalScrollView mScrollView; + + public boolean isInContentArea(int x, int y) { + final int l = getPaddingLeft(); + final int r = getWidth() - getPaddingRight(); + final int t = getPaddingTop(); + final int b = getHeight() - getPaddingBottom(); + return x >= l && x < r && y >= t && y < b; + } + + public void setBar(TabletStatusBarService bar) { + mBar = bar; + } + + public RecentAppsPanel(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public RecentAppsPanel(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + mDensity = getResources().getDisplayMetrics().density; + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + mNoRecents = (TextView) findViewById(R.id.recents_no_recents); + mRecentsContainer = (LinearLayout) findViewById(R.id.recents_container); + mScrollView = (HorizontalScrollView) findViewById(R.id.scroll_view); + mScrollView.setHorizontalFadingEdgeEnabled(true); + } + + @Override + protected void onVisibilityChanged(View changedView, int visibility) { + super.onVisibilityChanged(changedView, visibility); + Log.v(TAG, "onVisibilityChanged(" + changedView + ", " + visibility + ")"); + if (visibility == View.VISIBLE && changedView == this) { + refreshIcons(); + mRecentsContainer.setScrollbarFadingEnabled(true); + mRecentsContainer.scrollTo(0, 0); + } + } + + private void refreshIcons() { + mRecentsContainer.removeAllViews(); + final Context context = getContext(); + final PackageManager pm = context.getPackageManager(); + final ActivityManager am = (ActivityManager) + context.getSystemService(Context.ACTIVITY_SERVICE); + final List<ActivityManager.RecentTaskInfo> recentTasks = + am.getRecentTasks(MAX_RECENT_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE); + + ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN) + .addCategory(Intent.CATEGORY_HOME) + .resolveActivityInfo(pm, 0); + + int numTasks = recentTasks.size(); + final int width = (int) (mDensity * ITEM_WIDTH + 0.5f); + final int height = (int) (mDensity * ITEM_HEIGHT + 0.5f); + ViewGroup.LayoutParams layoutParams = new ViewGroup.LayoutParams(width, height); + for (int i = 0; i < numTasks; ++i) { + final ActivityManager.RecentTaskInfo info = recentTasks.get(i); + + Intent intent = new Intent(info.baseIntent); + if (info.origActivity != null) { + intent.setComponent(info.origActivity); + } + + // Exclude home activity. + if (homeInfo != null + && homeInfo.packageName.equals(intent.getComponent().getPackageName()) + && homeInfo.name.equals(intent.getComponent().getClassName())) { + continue; + } + + intent.setFlags((intent.getFlags()&~Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED) + | Intent.FLAG_ACTIVITY_NEW_TASK); + final ResolveInfo resolveInfo = pm.resolveActivity(intent, 0); + if (resolveInfo != null) { + final ActivityInfo activityInfo = resolveInfo.activityInfo; + final String title = activityInfo.loadLabel(pm).toString(); + Drawable icon = activityInfo.loadIcon(pm); + + if (title != null && title.length() > 0 && icon != null) { + ImageView imageView = new ImageView(mContext); + imageView.setScaleType(ImageView.ScaleType.FIT_XY); + imageView.setLayoutParams(layoutParams); + imageView.setOnClickListener(this); + imageView.setTag(intent); + imageView.setImageDrawable(icon); + mRecentsContainer.addView(imageView); + } + } + } + + int views = mRecentsContainer.getChildCount(); + mNoRecents.setVisibility(views == 0 ? View.VISIBLE : View.GONE); + mRecentsContainer.setVisibility(views > 0 ? View.VISIBLE : View.GONE); + } + + public void onClick(View v) { + Intent intent = (Intent) v.getTag(); + if (DEBUG) Log.v(TAG, "Starting activity " + intent); + getContext().startActivity(intent); + mBar.animateCollapse(); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java index 9fb29ac..7234557 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java @@ -67,8 +67,11 @@ public class TabletStatusBarService extends StatusBarService { public static final int MSG_CLOSE_NOTIFICATION_PANEL = 1001; public static final int MSG_OPEN_SYSTEM_PANEL = 1010; public static final int MSG_CLOSE_SYSTEM_PANEL = 1011; - + public static final int MSG_OPEN_RECENTS_PANEL = 1020; + public static final int MSG_CLOSE_RECENTS_PANEL = 1021; + private static final int MAX_IMAGE_LEVEL = 10000; + private static final boolean USE_2D_RECENTS = true; int mIconSize; @@ -76,7 +79,7 @@ public class TabletStatusBarService extends StatusBarService { // tracking all current notifications private NotificationData mNotns = new NotificationData(); - + TabletStatusBarView mStatusBarView; ImageView mNotificationTrigger; NotificationIconArea mNotificationIconArea; @@ -110,6 +113,7 @@ public class TabletStatusBarService extends StatusBarService { int mDisabled = 0; boolean mNotificationsOn = true; + private RecentAppsPanel mRecentsPanel; protected void addPanelWindows() { final Context context = mContext; @@ -118,6 +122,7 @@ public class TabletStatusBarService extends StatusBarService { final int barHeight= res.getDimensionPixelSize( com.android.internal.R.dimen.status_bar_height); + // Notification Panel mNotificationPanel = (NotificationPanel)View.inflate(context, R.layout.sysbar_panel_notifications, null); mNotificationPanel.setVisibility(View.GONE); @@ -139,11 +144,11 @@ public class TabletStatusBarService extends StatusBarService { WindowManagerImpl.getDefault().addView(mNotificationPanel, lp); + // System Panel mSystemPanel = (SystemPanel) View.inflate(context, R.layout.sysbar_panel_system, null); mSystemPanel.setVisibility(View.GONE); mSystemPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_SYSTEM_PANEL, - mSystemPanel)); - + mSystemPanel)); mStatusBarView.setIgnoreChildren(1, mSystemInfo, mSystemPanel); lp = new WindowManager.LayoutParams( @@ -159,6 +164,31 @@ public class TabletStatusBarService extends StatusBarService { WindowManagerImpl.getDefault().addView(mSystemPanel, lp); mSystemPanel.setBar(this); + + + // Recents Panel + if (USE_2D_RECENTS) { + mRecentsPanel = (RecentAppsPanel) View.inflate(context, R.layout.sysbar_panel_recent, + null); + mRecentsPanel.setVisibility(View.GONE); + mRecentsPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_RECENTS_PANEL, + mRecentsPanel)); + mStatusBarView.setIgnoreChildren(2, mRecentButton, mRecentsPanel); + + lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, + PixelFormat.TRANSLUCENT); + lp.gravity = Gravity.BOTTOM | Gravity.LEFT; + lp.setTitle("RecentsPanel"); + lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard; + + WindowManagerImpl.getDefault().addView(mRecentsPanel, lp); + mRecentsPanel.setBar(this); + } } @Override @@ -181,12 +211,13 @@ public class TabletStatusBarService extends StatusBarService { mBarContents = sb.findViewById(R.id.bar_contents); mCurtains = sb.findViewById(R.id.lights_out); mSystemInfo = sb.findViewById(R.id.systemInfo); + mRecentButton = sb.findViewById(R.id.recent_apps); // mSystemInfo.setOnClickListener(mOnClickListener); mSystemInfo.setOnLongClickListener(new SetLightsOnListener(false)); mSystemInfo.setOnTouchListener(new ClockTouchListener()); - mRecentButton = sb.findViewById(R.id.recent); + mRecentButton = sb.findViewById(R.id.recent_apps); mRecentButton.setOnClickListener(mOnClickListener); SetLightsOnListener on = new SetLightsOnListener(true); @@ -231,7 +262,7 @@ public class TabletStatusBarService extends StatusBarService { mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content); mPile.removeAllViews(); - + ScrollView scroller = (ScrollView)mPile.getParent(); scroller.setFillViewport(true); @@ -277,6 +308,13 @@ public class TabletStatusBarService extends StatusBarService { case MSG_CLOSE_SYSTEM_PANEL: if (DEBUG) Slog.d(TAG, "closing system panel"); mSystemPanel.setVisibility(View.GONE); + case MSG_OPEN_RECENTS_PANEL: + if (DEBUG) Slog.d(TAG, "opening recents panel"); + if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.VISIBLE); + break; + case MSG_CLOSE_RECENTS_PANEL: + if (DEBUG) Slog.d(TAG, "closing recents panel"); + if (mRecentsPanel != null) mRecentsPanel.setVisibility(View.GONE); break; } } @@ -315,7 +353,7 @@ public class TabletStatusBarService extends StatusBarService { mSignalMeter.setImageResource(R.drawable.sysbar_wifimini); // adjust to permyriad mSignalMeter.setImageLevel(level * (MAX_IMAGE_LEVEL / 100)); - mSignalIcon.setImageResource(isWifi ? R.drawable.ic_sysbar_wifi_mini + mSignalIcon.setImageResource(isWifi ? R.drawable.ic_sysbar_wifi_mini : R.drawable.ic_sysbar_wifi_mini); // XXX } } @@ -362,7 +400,7 @@ public class TabletStatusBarService extends StatusBarService { public void updateNotification(IBinder key, StatusBarNotification notification) { if (DEBUG) Slog.d(TAG, "updateNotification(" + key + " -> " + notification + ") // TODO"); - + final NotificationData.Entry oldEntry = mNotns.findByKey(key); if (oldEntry == null) { Slog.w(TAG, "updateNotification for unknown key: " + key); @@ -527,6 +565,8 @@ public class TabletStatusBarService extends StatusBarService { mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL); mHandler.removeMessages(MSG_CLOSE_SYSTEM_PANEL); mHandler.sendEmptyMessage(MSG_CLOSE_SYSTEM_PANEL); + mHandler.removeMessages(MSG_CLOSE_RECENTS_PANEL); + mHandler.sendEmptyMessage(MSG_CLOSE_RECENTS_PANEL); } public void setLightsOn(boolean on) { @@ -665,7 +705,7 @@ public class TabletStatusBarService extends StatusBarService { mIconLayout.setVisibility(View.VISIBLE); // TODO: animation refreshNotificationTrigger(); } else { - int msg = (mNotificationPanel.getVisibility() == View.GONE) + int msg = (mNotificationPanel.getVisibility() == View.GONE) ? MSG_OPEN_NOTIFICATION_PANEL : MSG_CLOSE_NOTIFICATION_PANEL; mHandler.removeMessages(msg); @@ -677,7 +717,7 @@ public class TabletStatusBarService extends StatusBarService { public void onClickSystemInfo() { if (DEBUG) Slog.d(TAG, "clicked system info"); if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { - int msg = (mSystemPanel.getVisibility() == View.GONE) + int msg = (mSystemPanel.getVisibility() == View.GONE) ? MSG_OPEN_SYSTEM_PANEL : MSG_CLOSE_SYSTEM_PANEL; mHandler.removeMessages(msg); @@ -687,11 +727,21 @@ public class TabletStatusBarService extends StatusBarService { public void onClickRecentButton() { if (DEBUG) Slog.d(TAG, "clicked recent apps"); - Intent intent = new Intent(); - intent.setClass(mContext, RecentApplicationsActivity.class); - intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK - | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); - mContext.startActivity(intent); + if (mRecentsPanel == null) { + Intent intent = new Intent(); + intent.setClass(mContext, RecentApplicationsActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + mContext.startActivity(intent); + } else { + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { + int msg = (mRecentsPanel.getVisibility() == View.GONE) + ? MSG_OPEN_RECENTS_PANEL + : MSG_CLOSE_RECENTS_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + } } private class NotificationClicker implements View.OnClickListener { @@ -835,7 +885,7 @@ public class TabletStatusBarService extends StatusBarService { final String _pkg = sbn.pkg; final String _tag = sbn.tag; final int _id = sbn.id; - vetoButton.setOnClickListener(new View.OnClickListener() { + vetoButton.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { try { mBarService.onNotificationClear(_pkg, _tag, _id); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java index d836e4a..15866fe 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java @@ -26,8 +26,8 @@ import android.widget.FrameLayout; public class TabletStatusBarView extends FrameLayout { private Handler mHandler; - private View[] mIgnoreChildren = new View[2]; - private View[] mPanels = new View[2]; + private View[] mIgnoreChildren = new View[3]; + private View[] mPanels = new View[3]; private int[] mPos = new int[2]; public TabletStatusBarView(Context context) { @@ -44,9 +44,11 @@ public class TabletStatusBarView extends FrameLayout { mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_NOTIFICATION_PANEL); mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_SYSTEM_PANEL); mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_SYSTEM_PANEL); + mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_RECENTS_PANEL); + mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_RECENTS_PANEL); - for (int i=0; i<mPanels.length; i++) { - if (mPanels[i].getVisibility() == View.VISIBLE) { + for (int i=0; i < mPanels.length; i++) { + if (mPanels[i] != null && mPanels[i].getVisibility() == View.VISIBLE) { if (eventInside(mIgnoreChildren[i], ev)) { return true; } diff --git a/services/java/com/android/server/am/ActivityStack.java b/services/java/com/android/server/am/ActivityStack.java index f52d322..463493b 100644 --- a/services/java/com/android/server/am/ActivityStack.java +++ b/services/java/com/android/server/am/ActivityStack.java @@ -2139,7 +2139,7 @@ public class ActivityStack { // being started, which means not bringing it to the front // if the caller is not itself in the front. ActivityRecord curTop = topRunningNonDelayedActivityLocked(notTop); - if (curTop.task != taskTop.task) { + if (curTop != null && curTop.task != taskTop.task) { r.intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT); boolean callerAtFront = sourceRecord == null || curTop.task == sourceRecord.task; diff --git a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java index 2db1071..02eaa7c 100644 --- a/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java +++ b/tests/HwAccelerationTest/src/com/android/test/hwui/ShadersActivity.java @@ -51,27 +51,28 @@ public class ShadersActivity extends Activity { private LinearGradient mHorGradient; private LinearGradient mDiagGradient; private LinearGradient mVertGradient; + private Bitmap mTexture; ShadersView(Context c) { super(c); - Bitmap texture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1); - mTexWidth = texture.getWidth(); - mTexHeight = texture.getHeight(); + mTexture = BitmapFactory.decodeResource(c.getResources(), R.drawable.sunset1); + mTexWidth = mTexture.getWidth(); + mTexHeight = mTexture.getHeight(); mDrawWidth = mTexWidth * 2.2f; mDrawHeight = mTexHeight * 1.2f; - mRepeatShader = new BitmapShader(texture, Shader.TileMode.REPEAT, + mRepeatShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); - mTranslatedShader = new BitmapShader(texture, Shader.TileMode.REPEAT, + mTranslatedShader = new BitmapShader(mTexture, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT); Matrix m1 = new Matrix(); m1.setTranslate(mTexWidth / 2.0f, mTexHeight / 2.0f); m1.postRotate(45, 0, 0); mTranslatedShader.setLocalMatrix(m1); - mScaledShader = new BitmapShader(texture, Shader.TileMode.MIRROR, + mScaledShader = new BitmapShader(mTexture, Shader.TileMode.MIRROR, Shader.TileMode.MIRROR); Matrix m2 = new Matrix(); m2.setScale(0.5f, 0.5f); @@ -98,6 +99,7 @@ public class ShadersActivity extends Activity { protected void onDraw(Canvas canvas) { super.onDraw(canvas); //canvas.drawRGB(255, 255, 255); + canvas.drawBitmap(mTexture, 0.0f, 0.0f, null); // Bitmap shaders canvas.save(); |
