diff options
Diffstat (limited to 'packages/SystemUI')
264 files changed, 6204 insertions, 1517 deletions
diff --git a/packages/SystemUI/Android.mk b/packages/SystemUI/Android.mk index 4c83768..2c13069 100644 --- a/packages/SystemUI/Android.mk +++ b/packages/SystemUI/Android.mk @@ -3,11 +3,16 @@ include $(CLEAR_VARS) LOCAL_MODULE_TAGS := optional -LOCAL_SRC_FILES := $(call all-subdir-java-files) +LOCAL_SRC_FILES := $(call all-subdir-java-files) \ + ../../../ex/carousel/java/com/android/ex/carousel/carousel.rs LOCAL_JAVA_LIBRARIES := services +LOCAL_STATIC_JAVA_LIBRARIES := android-common-carousel + LOCAL_PACKAGE_NAME := SystemUI LOCAL_CERTIFICATE := platform +LOCAL_PROGUARD_FLAG_FILES := proguard.flags + include $(BUILD_PACKAGE) diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml index 0fccbe7..6057023 100644 --- a/packages/SystemUI/AndroidManifest.xml +++ b/packages/SystemUI/AndroidManifest.xml @@ -5,6 +5,9 @@ > <uses-permission android:name="android.permission.STATUS_BAR_SERVICE" /> + <uses-permission android:name="android.permission.BLUETOOTH" /> + <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" /> + <uses-permission android:name="android.permission.GET_TASKS" /> <application android:persistent="true" @@ -13,7 +16,12 @@ android:icon="@drawable/ic_launcher_settings"> <service - android:name=".statusbar.StatusBarService" + android:name=".statusbar.PhoneStatusBarService" + android:exported="false" + /> + + <service + android:name=".statusbar.tablet.TabletStatusBarService" android:exported="false" /> @@ -21,5 +29,12 @@ android:excludeFromRecents="true"> </activity> + <activity android:name=".recent.RecentApplicationsActivity" + android:theme="@android:style/Theme.NoTitleBar" + android:excludeFromRecents="true" + android:launchMode="singleInstance" + android:exported="true"> + </activity> + </application> </manifest> diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags new file mode 100644 index 0000000..5e48461 --- /dev/null +++ b/packages/SystemUI/proguard.flags @@ -0,0 +1,6 @@ +-keep class com.android.systemui.statusbar.tablet.TabletStatusBarService { + public void notificationIconsClicked(android.view.View); + public void systemInfoClicked(android.view.View); + public void recentButtonClicked(android.view.View); + public void toggleLightsOut(android.view.View); +} diff --git a/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml b/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml new file mode 100644 index 0000000..5b6778e --- /dev/null +++ b/packages/SystemUI/res/anim/hydraulic_brake_interpolator.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/anim/ease_out_interpolator.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<decelerateInterpolator + xmlns:android="http://schemas.android.com/apk/res/android" + android:factor="10.0" /> diff --git a/packages/SystemUI/res/anim/lights_out_in.xml b/packages/SystemUI/res/anim/lights_out_in.xml new file mode 100644 index 0000000..8154ec0 --- /dev/null +++ b/packages/SystemUI/res/anim/lights_out_in.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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <translate android:fromYDelta="100%p" android:toYDelta="0" + android:duration="@android:integer/config_mediumAnimTime" + android:interpolator="@anim/hydraulic_brake_interpolator" + /> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/lights_out_out.xml b/packages/SystemUI/res/anim/lights_out_out.xml new file mode 100644 index 0000000..b4bc55a --- /dev/null +++ b/packages/SystemUI/res/anim/lights_out_out.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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <translate android:toYDelta="100%p" android:fromYDelta="0" + android:duration="@android:integer/config_mediumAnimTime" + android:interpolator="@anim/hydraulic_brake_interpolator" + /> + <alpha android:toAlpha="0.0" android:fromAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/navigation_in.xml b/packages/SystemUI/res/anim/navigation_in.xml new file mode 100644 index 0000000..630fd72 --- /dev/null +++ b/packages/SystemUI/res/anim/navigation_in.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/navigation_out.xml b/packages/SystemUI/res/anim/navigation_out.xml new file mode 100644 index 0000000..4717e47 --- /dev/null +++ b/packages/SystemUI/res/anim/navigation_out.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <alpha android:toAlpha="0.0" android:fromAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/notification_buttons_in.xml b/packages/SystemUI/res/anim/notification_buttons_in.xml new file mode 100644 index 0000000..630fd72 --- /dev/null +++ b/packages/SystemUI/res/anim/notification_buttons_in.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/notification_buttons_out.xml b/packages/SystemUI/res/anim/notification_buttons_out.xml new file mode 100644 index 0000000..4717e47 --- /dev/null +++ b/packages/SystemUI/res/anim/notification_buttons_out.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <alpha android:toAlpha="0.0" android:fromAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/notification_icons_in.xml b/packages/SystemUI/res/anim/notification_icons_in.xml new file mode 100644 index 0000000..630fd72 --- /dev/null +++ b/packages/SystemUI/res/anim/notification_icons_in.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/notification_icons_out.xml b/packages/SystemUI/res/anim/notification_icons_out.xml new file mode 100644 index 0000000..4717e47 --- /dev/null +++ b/packages/SystemUI/res/anim/notification_icons_out.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <alpha android:toAlpha="0.0" android:fromAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/recent_app_enter.xml b/packages/SystemUI/res/anim/recent_app_enter.xml new file mode 100644 index 0000000..4947eee --- /dev/null +++ b/packages/SystemUI/res/anim/recent_app_enter.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<!-- Special window zoom animation: this is the element that enters the screen, + it starts at 200% and scales down. Goes with zoom_exit.xml. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:anim/decelerate_interpolator"> + <scale android:fromXScale="0.25" android:toXScale="1.0" + android:fromYScale="0.25" android:toYScale="1.0" + android:pivotX="0%p" android:pivotY="0%p" + android:duration="500" /> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="500"/> +</set> diff --git a/packages/SystemUI/res/anim/recent_app_leave.xml b/packages/SystemUI/res/anim/recent_app_leave.xml new file mode 100644 index 0000000..3d83988 --- /dev/null +++ b/packages/SystemUI/res/anim/recent_app_leave.xml @@ -0,0 +1,30 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<!-- Special window zoom animation: this is the element that enters the screen, + it starts at 200% and scales down. Goes with zoom_exit.xml. --> +<set xmlns:android="http://schemas.android.com/apk/res/android" + android:interpolator="@android:anim/decelerate_interpolator"> + <scale android:fromXScale="1.0" android:toXScale="0.25" + android:fromYScale="1.0" android:toYScale="0.25" + android:pivotX="0%p" android:pivotY="0%p" + android:duration="500" /> + <alpha android:fromAlpha="1.0" android:toAlpha="0.0" + android:duration="500"/> +</set> diff --git a/packages/SystemUI/res/anim/status_bar_in.xml b/packages/SystemUI/res/anim/status_bar_in.xml new file mode 100644 index 0000000..460fe50 --- /dev/null +++ b/packages/SystemUI/res/anim/status_bar_in.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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <translate android:fromYDelta="-100%p" android:toYDelta="0" + android:duration="@android:integer/config_longAnimTime" + android:interpolator="@anim/hydraulic_brake_interpolator" + /> + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/status_bar_out.xml b/packages/SystemUI/res/anim/status_bar_out.xml new file mode 100644 index 0000000..6572ab4 --- /dev/null +++ b/packages/SystemUI/res/anim/status_bar_out.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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <translate android:toYDelta="-100%p" android:fromYDelta="0" + android:duration="@android:integer/config_longAnimTime" + android:interpolator="@anim/hydraulic_brake_interpolator" + /> + <alpha android:toAlpha="0.0" android:fromAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/system_in.xml b/packages/SystemUI/res/anim/system_in.xml new file mode 100644 index 0000000..630fd72 --- /dev/null +++ b/packages/SystemUI/res/anim/system_in.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <alpha android:fromAlpha="0.0" android:toAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/anim/system_out.xml b/packages/SystemUI/res/anim/system_out.xml new file mode 100644 index 0000000..4717e47 --- /dev/null +++ b/packages/SystemUI/res/anim/system_out.xml @@ -0,0 +1,22 @@ +<?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. +--> + +<set xmlns:android="http://schemas.android.com/apk/res/android" + > + <alpha android:toAlpha="0.0" android:fromAlpha="1.0" + android:duration="@android:integer/config_longAnimTime" + /> +</set> diff --git a/packages/SystemUI/res/drawable-hdpi/alert_bar_background_normal.9.png b/packages/SystemUI/res/drawable-hdpi/alert_bar_background_normal.9.png Binary files differnew file mode 100644 index 0000000..bc127bd --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/alert_bar_background_normal.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/alert_bar_background_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/alert_bar_background_pressed.9.png Binary files differnew file mode 100644 index 0000000..59af804 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/alert_bar_background_pressed.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/battery_0.png b/packages/SystemUI/res/drawable-hdpi/battery_0.png Binary files differnew file mode 100644 index 0000000..f4103a8 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/battery_0.png diff --git a/packages/SystemUI/res/drawable-hdpi/battery_100.png b/packages/SystemUI/res/drawable-hdpi/battery_100.png Binary files differnew file mode 100644 index 0000000..061cbe5 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/battery_100.png diff --git a/packages/SystemUI/res/drawable-hdpi/battery_20.png b/packages/SystemUI/res/drawable-hdpi/battery_20.png Binary files differnew file mode 100644 index 0000000..0064027 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/battery_20.png diff --git a/packages/SystemUI/res/drawable-hdpi/battery_40.png b/packages/SystemUI/res/drawable-hdpi/battery_40.png Binary files differnew file mode 100644 index 0000000..10de0e7 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/battery_40.png diff --git a/packages/SystemUI/res/drawable-hdpi/battery_60.png b/packages/SystemUI/res/drawable-hdpi/battery_60.png Binary files differnew file mode 100644 index 0000000..aa2b8ef --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/battery_60.png diff --git a/packages/SystemUI/res/drawable-hdpi/battery_80.png b/packages/SystemUI/res/drawable-hdpi/battery_80.png Binary files differnew file mode 100644 index 0000000..fe231f0 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/battery_80.png diff --git a/packages/SystemUI/res/drawable-hdpi/button_frame_default.9.png b/packages/SystemUI/res/drawable-hdpi/button_frame_default.9.png Binary files differnew file mode 100644 index 0000000..d809b84 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/button_frame_default.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/button_frame_pressed.9.png b/packages/SystemUI/res/drawable-hdpi/button_frame_pressed.9.png Binary files differnew file mode 100644 index 0000000..5cc007c --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/button_frame_pressed.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png b/packages/SystemUI/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png Binary files differdeleted file mode 100644 index d21aad2..0000000 --- a/packages/SystemUI/res/drawable-hdpi/divider_horizontal_dark_opaque.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/divider_horizontal_light_opaque.9.png b/packages/SystemUI/res/drawable-hdpi/divider_horizontal_light_opaque.9.png Binary files differdeleted file mode 100644 index f70f079..0000000 --- a/packages/SystemUI/res/drawable-hdpi/divider_horizontal_light_opaque.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/dots_empty.png b/packages/SystemUI/res/drawable-hdpi/dots_empty.png Binary files differnew file mode 100644 index 0000000..31e7654 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/dots_empty.png diff --git a/packages/SystemUI/res/drawable-hdpi/dots_full.png b/packages/SystemUI/res/drawable-hdpi/dots_full.png Binary files differnew file mode 100644 index 0000000..8c5c604 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/dots_full.png diff --git a/packages/SystemUI/res/drawable-hdpi/signal_0.png b/packages/SystemUI/res/drawable-hdpi/signal_0.png Binary files differnew file mode 100644 index 0000000..00e36c4 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/signal_0.png diff --git a/packages/SystemUI/res/drawable-hdpi/signal_100.png b/packages/SystemUI/res/drawable-hdpi/signal_100.png Binary files differnew file mode 100644 index 0000000..96e52ff --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/signal_100.png diff --git a/packages/SystemUI/res/drawable-hdpi/signal_20.png b/packages/SystemUI/res/drawable-hdpi/signal_20.png Binary files differnew file mode 100644 index 0000000..c0f652a --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/signal_20.png diff --git a/packages/SystemUI/res/drawable-hdpi/signal_40.png b/packages/SystemUI/res/drawable-hdpi/signal_40.png Binary files differnew file mode 100644 index 0000000..995dd8e --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/signal_40.png diff --git a/packages/SystemUI/res/drawable-hdpi/signal_60.png b/packages/SystemUI/res/drawable-hdpi/signal_60.png Binary files differnew file mode 100644 index 0000000..51e31ba --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/signal_60.png diff --git a/packages/SystemUI/res/drawable-hdpi/signal_80.png b/packages/SystemUI/res/drawable-hdpi/signal_80.png Binary files differnew file mode 100644 index 0000000..afa656e --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/signal_80.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png b/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png Binary files differindex 2d3eb30..89daee1 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_notify_alarm.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png Binary files differindex e8fbc9e..96dc085 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png Binary files differindex 18c77df..1e4bbf5 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_bluetooth_connected.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png Binary files differindex 818e292..bdc8c27 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_1x.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png Binary files differindex 95866b1..d0d1345 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_3g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png Binary files differindex 016b30b..4211b8c 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png Binary files differindex ec672eb..d5ece7a 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png Binary files differindex 27bab73..6687b40 100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_connected_h.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_1x.png Binary files differindex 0e6849b..ba24082 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_1x.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_1x.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_3g.png Binary files differindex a86a324..5af2b05 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_3g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_3g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_e.png Binary files differindex 24902d6..9909b09 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_e.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_g.png Binary files differindex 4160a95..0e02b8d 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_h.png Binary files differindex d459ee3..f84ad32 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_h.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_connected_h.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_1x.png Binary files differindex 7b64751..d80a8ce 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_1x.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_1x.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_3g.png Binary files differindex d82930c..31c976a 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_3g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_3g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_e.png Binary files differindex 8096846..ae90cc8 100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_e.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_g.png Binary files differindex e94e146..a487f29 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_h.png Binary files differindex 8805a40..816085b 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_h.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_in_h.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_1x.png Binary files differindex 07545d5..0132019 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_1x.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_1x.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_3g.png Binary files differindex 7629cef..3903545 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_3g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_3g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_e.png Binary files differindex 28578c6..ed099ff 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_e.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_g.png Binary files differindex d9f7a30..c930e4c 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_h.png Binary files differindex 505ccd4..407a06c 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_h.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_inandout_h.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_1x.png Binary files differindex 783c2b6..6141f72 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_1x.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_1x.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_3g.png Binary files differindex 001eaea..d44a4cf 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_3g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_3g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_e.png Binary files differindex cbae7dc..54ebd9b 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_e.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_g.png Binary files differindex 11f3a5c..2fe0bbf 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_h.png Binary files differindex eb42294..e58e019 100644..100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_h.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_fully_out_h.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_1x.png Binary files differindex 66fb60e..00a29a4 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_1x.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_1x.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png Binary files differindex 07ea499..11ee0f2 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_3g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_e.png Binary files differindex e39767a..fc135fc 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_e.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_g.png Binary files differindex 47c1fca..3d33a62 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_h.png Binary files differindex ac80dce..f36e1eb 100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_h.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_in_h.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_1x.png Binary files differindex f88091b..ef5dbf4 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_1x.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_1x.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png Binary files differindex 95bb3cd..dba9675 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_3g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_e.png Binary files differindex 0ef4701..2e5d82e 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_e.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_g.png Binary files differindex 31b926b..0985a09 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_h.png Binary files differindex ed02984..7a32c43 100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_h.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_inandout_h.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_1x.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_1x.png Binary files differindex 0ee5b08..b622556 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_1x.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_1x.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png Binary files differindex cac7802..04ec59e 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_3g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_e.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_e.png Binary files differindex df6e195..a47b982 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_e.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_e.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_g.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_g.png Binary files differindex 4a2f867..9d90e71 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_g.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_g.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_h.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_h.png Binary files differindex 2b4628f..920f290 100755 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_h.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_data_out_h.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png Binary files differindex c43fc3b..9003d67 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_gps_acquiring.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0.png Binary files differindex 1ef75d3..95ba181 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0_fully.png Binary files differindex 1ef75d3..95ba181 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0_fully.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_0_fully.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1.png Binary files differindex a7dc07e..adf668d 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1_fully.png Binary files differindex f1f4c4e..adf668d 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1_fully.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_1_fully.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2.png Binary files differindex 918a476..7bf6b51 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2_fully.png Binary files differindex 6e34e66..7bf6b51 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2_fully.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_2_fully.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3.png Binary files differindex 5b2acc6..78738ac 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3_fully.png Binary files differindex 3664ab4..78738ac 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3_fully.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_3_fully.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4.png Binary files differindex f1ff548..ac88143 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4_fully.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4_fully.png Binary files differindex b4fa481..ac88143 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4_fully.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_r_signal_4_fully.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png Binary files differindex 5a741bb..bdd37e1 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_silent.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png Binary files differindex 7ff375a..21c1c08 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_ringer_vibrate.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png Binary files differindex 01c7e2a..7a419f1 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_flightmode.png diff --git a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png Binary files differindex 03d2147..1adc05a 100644 --- a/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png +++ b/packages/SystemUI/res/drawable-hdpi/stat_sys_signal_null.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_back_default.png b/packages/SystemUI/res/drawable-hdpi/status_bar_back_default.png Binary files differnew file mode 100644 index 0000000..a9f9540 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_back_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_back_pressed.png b/packages/SystemUI/res/drawable-hdpi/status_bar_back_pressed.png Binary files differnew file mode 100644 index 0000000..b8aa190 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_back_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png Binary files differdeleted file mode 100644 index 87d1944..0000000 --- a/packages/SystemUI/res/drawable-hdpi/status_bar_close_on.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_expand_default.png b/packages/SystemUI/res/drawable-hdpi/status_bar_expand_default.png Binary files differnew file mode 100644 index 0000000..92fc7f8 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_expand_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_expand_pressed.png b/packages/SystemUI/res/drawable-hdpi/status_bar_expand_pressed.png Binary files differnew file mode 100644 index 0000000..77f09ac --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_expand_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_home_default.png b/packages/SystemUI/res/drawable-hdpi/status_bar_home_default.png Binary files differnew file mode 100644 index 0000000..cb951dd --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_home_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_home_pressed.png b/packages/SystemUI/res/drawable-hdpi/status_bar_home_pressed.png Binary files differnew file mode 100644 index 0000000..a835ad5 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_home_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_icon_tray.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_icon_tray.9.png Binary files differnew file mode 100644 index 0000000..e1f041c --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_icon_tray.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_item_app_background_normal.9.png b/packages/SystemUI/res/drawable-hdpi/status_bar_item_app_background_normal.9.png Binary files differnew file mode 100644 index 0000000..4fbfa4f --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_item_app_background_normal.9.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_menu_default.png b/packages/SystemUI/res/drawable-hdpi/status_bar_menu_default.png Binary files differnew file mode 100644 index 0000000..14779cf --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_menu_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_menu_pressed.png b/packages/SystemUI/res/drawable-hdpi/status_bar_menu_pressed.png Binary files differnew file mode 100644 index 0000000..6c3d4c9 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_menu_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png Binary files differnew file mode 100644 index 0000000..df532b8 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_normal.png diff --git a/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png Binary files differnew file mode 100644 index 0000000..118c01b --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/status_bar_veto_pressed.png diff --git a/packages/SystemUI/res/drawable-hdpi/statusbar_background.9.png b/packages/SystemUI/res/drawable-hdpi/statusbar_background.9.png Binary files differdeleted file mode 100644 index 98e5487..0000000 --- a/packages/SystemUI/res/drawable-hdpi/statusbar_background.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-hdpi/system_panel_airplane_default.png b/packages/SystemUI/res/drawable-hdpi/system_panel_airplane_default.png Binary files differnew file mode 100644 index 0000000..e375ee9 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/system_panel_airplane_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/system_panel_brightness_default.png b/packages/SystemUI/res/drawable-hdpi/system_panel_brightness_default.png Binary files differnew file mode 100644 index 0000000..f62502b --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/system_panel_brightness_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/system_panel_orientation_default.png b/packages/SystemUI/res/drawable-hdpi/system_panel_orientation_default.png Binary files differnew file mode 100644 index 0000000..e887fb8 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/system_panel_orientation_default.png diff --git a/packages/SystemUI/res/drawable-hdpi/system_panel_orientation_locked.png b/packages/SystemUI/res/drawable-hdpi/system_panel_orientation_locked.png Binary files differnew file mode 100644 index 0000000..58159d5 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/system_panel_orientation_locked.png diff --git a/packages/SystemUI/res/drawable-hdpi/system_panel_sound_default.png b/packages/SystemUI/res/drawable-hdpi/system_panel_sound_default.png Binary files differnew file mode 100644 index 0000000..6e857b5 --- /dev/null +++ b/packages/SystemUI/res/drawable-hdpi/system_panel_sound_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/divider_horizontal_dark_opaque.9.png b/packages/SystemUI/res/drawable-mdpi/alert_bar_background_normal.9.png Binary files differindex 9444f0d..258de13 100644 --- a/packages/SystemUI/res/drawable-mdpi/divider_horizontal_dark_opaque.9.png +++ b/packages/SystemUI/res/drawable-mdpi/alert_bar_background_normal.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/alert_bar_background_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/alert_bar_background_pressed.9.png Binary files differnew file mode 100644 index 0000000..258de13 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/alert_bar_background_pressed.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png b/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png Binary files differdeleted file mode 100644 index 60bbe6c..0000000 --- a/packages/SystemUI/res/drawable-mdpi/battery_low_battery.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/button_frame_default.9.png b/packages/SystemUI/res/drawable-mdpi/button_frame_default.9.png Binary files differnew file mode 100644 index 0000000..7ab1f26 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/button_frame_default.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/button_frame_pressed.9.png b/packages/SystemUI/res/drawable-mdpi/button_frame_pressed.9.png Binary files differnew file mode 100644 index 0000000..08f7a4d --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/button_frame_pressed.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/divider_horizontal_light_opaque.9.png b/packages/SystemUI/res/drawable-mdpi/divider_horizontal_light_opaque.9.png Binary files differdeleted file mode 100644 index f70f079..0000000 --- a/packages/SystemUI/res/drawable-mdpi/divider_horizontal_light_opaque.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/dots_empty.png b/packages/SystemUI/res/drawable-mdpi/dots_empty.png Binary files differnew file mode 100644 index 0000000..22ada41 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/dots_empty.png diff --git a/packages/SystemUI/res/drawable-mdpi/dots_full.png b/packages/SystemUI/res/drawable-mdpi/dots_full.png Binary files differnew file mode 100644 index 0000000..2a346d6 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/dots_full.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_off.png Binary files differnew file mode 100644 index 0000000..d897ba6 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_off.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png Binary files differnew file mode 100644 index 0000000..0296b5b --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_airplane_on.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png Binary files differnew file mode 100644 index 0000000..6c5a79b --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_back.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_mini.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_mini.png Binary files differnew file mode 100644 index 0000000..9ababb7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_mini.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_on.png Binary files differnew file mode 100644 index 0000000..668b472 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_battery_on.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_off.png Binary files differnew file mode 100644 index 0000000..e463ba4 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_off.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_on.png Binary files differnew file mode 100644 index 0000000..1239d50 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_bluetooth_on.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png Binary files differnew file mode 100644 index 0000000..97fa5fc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_auto.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_auto.png Binary files differnew file mode 100644 index 0000000..37a1533 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_auto.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_low.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_low.png Binary files differnew file mode 100644 index 0000000..8a55e3a --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_brightness_low.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_close.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_close.png Binary files differnew file mode 100644 index 0000000..53abcbc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_close.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_default_bg.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_default_bg.png Binary files differnew file mode 100644 index 0000000..3e82d4e --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_default_bg.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_off.png Binary files differnew file mode 100644 index 0000000..dc2ed34 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_off.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_on.png Binary files differnew file mode 100644 index 0000000..1e39fdc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_gps_on.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png Binary files differnew file mode 100644 index 0000000..ed813dc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_home.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png Binary files differnew file mode 100644 index 0000000..bf33c94 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_ime_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lightsout.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lightsout.png Binary files differnew file mode 100644 index 0000000..8a07acc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_lightsout.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png Binary files differnew file mode 100644 index 0000000..d7775f2 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_menu.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_open.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_open.png Binary files differnew file mode 100644 index 0000000..b7d624e --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_open.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_press_bg.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_press_bg.png Binary files differnew file mode 100644 index 0000000..0958393 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_press_bg.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png Binary files differnew file mode 100644 index 0000000..178af73 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_recent.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png Binary files differnew file mode 100644 index 0000000..adaadf7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_lanscape.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png Binary files differnew file mode 100644 index 0000000..fdc0ac7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_off_portrait.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png Binary files differnew file mode 100644 index 0000000..4517d1b --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_rotate_on.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_off.png Binary files differnew file mode 100644 index 0000000..bd11e86 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_off.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_on.png Binary files differnew file mode 100644 index 0000000..1b3ba2f --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_sound_on.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_mini.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_mini.png Binary files differnew file mode 100644 index 0000000..ffbd2d3 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_mini.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_off.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_off.png Binary files differnew file mode 100644 index 0000000..87acc14 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_off.png diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png Binary files differnew file mode 100644 index 0000000..bbb1c74 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_wifi_on.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_back_default.png b/packages/SystemUI/res/drawable-mdpi/status_bar_back_default.png Binary files differnew file mode 100644 index 0000000..5c57802 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_back_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_back_pressed.png b/packages/SystemUI/res/drawable-mdpi/status_bar_back_pressed.png Binary files differnew file mode 100644 index 0000000..a2527b3 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_back_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_expand_default.png b/packages/SystemUI/res/drawable-mdpi/status_bar_expand_default.png Binary files differnew file mode 100644 index 0000000..ce64926 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_expand_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_expand_pressed.png b/packages/SystemUI/res/drawable-mdpi/status_bar_expand_pressed.png Binary files differnew file mode 100644 index 0000000..c63c426 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_expand_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_home_default.png b/packages/SystemUI/res/drawable-mdpi/status_bar_home_default.png Binary files differnew file mode 100644 index 0000000..f219ded --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_home_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_home_pressed.png b/packages/SystemUI/res/drawable-mdpi/status_bar_home_pressed.png Binary files differnew file mode 100644 index 0000000..9e64fe8 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_home_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_icon_tray.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_icon_tray.9.png Binary files differnew file mode 100644 index 0000000..502acce --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_icon_tray.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_item_app_background_normal.9.png b/packages/SystemUI/res/drawable-mdpi/status_bar_item_app_background_normal.9.png Binary files differnew file mode 100644 index 0000000..c079615 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_item_app_background_normal.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_menu_default.png b/packages/SystemUI/res/drawable-mdpi/status_bar_menu_default.png Binary files differnew file mode 100644 index 0000000..bf3a755 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_menu_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_menu_pressed.png b/packages/SystemUI/res/drawable-mdpi/status_bar_menu_pressed.png Binary files differnew file mode 100644 index 0000000..15e21d73 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_menu_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_recent_default.png b/packages/SystemUI/res/drawable-mdpi/status_bar_recent_default.png Binary files differnew file mode 100644 index 0000000..4dd8dc7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_recent_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_recent_pressed.png b/packages/SystemUI/res/drawable-mdpi/status_bar_recent_pressed.png Binary files differnew file mode 100644 index 0000000..350a3e9 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_recent_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_veto_normal.png b/packages/SystemUI/res/drawable-mdpi/status_bar_veto_normal.png Binary files differnew file mode 100644 index 0000000..3b7c9c7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_veto_normal.png diff --git a/packages/SystemUI/res/drawable-mdpi/status_bar_veto_pressed.png b/packages/SystemUI/res/drawable-mdpi/status_bar_veto_pressed.png Binary files differnew file mode 100644 index 0000000..3b7c9c7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/status_bar_veto_pressed.png diff --git a/packages/SystemUI/res/drawable-mdpi/statusbar_background.9.png b/packages/SystemUI/res/drawable-mdpi/statusbar_background.9.png Binary files differdeleted file mode 100644 index 4b5dbe3..0000000 --- a/packages/SystemUI/res/drawable-mdpi/statusbar_background.9.png +++ /dev/null diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png Binary files differnew file mode 100644 index 0000000..ff75a51 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_0.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png Binary files differnew file mode 100644 index 0000000..66ab4c6 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_10.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png Binary files differnew file mode 100644 index 0000000..3b50500 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_100.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png Binary files differnew file mode 100644 index 0000000..9119065 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_20.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png Binary files differnew file mode 100644 index 0000000..296f19f --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_30.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png Binary files differnew file mode 100644 index 0000000..9daab23 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_40.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png Binary files differnew file mode 100644 index 0000000..62d24c4 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_50.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png Binary files differnew file mode 100644 index 0000000..eea927a --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_60.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png Binary files differnew file mode 100644 index 0000000..6816088 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_70.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png Binary files differnew file mode 100644 index 0000000..b7dd9bb --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_80.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png Binary files differnew file mode 100644 index 0000000..6e36f53 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_battery_90.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png Binary files differnew file mode 100644 index 0000000..8eb0f29 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_100.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png Binary files differnew file mode 100644 index 0000000..adcc6b9 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_batterymini_red.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_hidenotification_handle.png b/packages/SystemUI/res/drawable-mdpi/sysbar_hidenotification_handle.png Binary files differnew file mode 100644 index 0000000..e43edd7 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_hidenotification_handle.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_minimeter_bg.png b/packages/SystemUI/res/drawable-mdpi/sysbar_minimeter_bg.png Binary files differnew file mode 100644 index 0000000..0d265fc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_minimeter_bg.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_panel_bg.9.png b/packages/SystemUI/res/drawable-mdpi/sysbar_panel_bg.9.png Binary files differnew file mode 100644 index 0000000..77e034b --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_panel_bg.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png Binary files differnew file mode 100644 index 0000000..7469372 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_0.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png Binary files differnew file mode 100644 index 0000000..6625d9a --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_10.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png Binary files differnew file mode 100644 index 0000000..b2e763b --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_100.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png Binary files differnew file mode 100644 index 0000000..fb66362 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_20.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png Binary files differnew file mode 100644 index 0000000..a87d94e --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_30.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png Binary files differnew file mode 100644 index 0000000..8e229d5 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_40.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png Binary files differnew file mode 100644 index 0000000..fe989d4 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_50.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png Binary files differnew file mode 100644 index 0000000..aac57dc --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_60.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png Binary files differnew file mode 100644 index 0000000..2281968 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_70.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png Binary files differnew file mode 100644 index 0000000..7177ae1 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_80.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png Binary files differnew file mode 100644 index 0000000..7f60480 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signal_90.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_signalmini_100.png b/packages/SystemUI/res/drawable-mdpi/sysbar_signalmini_100.png Binary files differnew file mode 100644 index 0000000..a5eaa63 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_signalmini_100.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_off.9.png b/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_off.9.png Binary files differnew file mode 100644 index 0000000..94849d8 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_off.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_on.9.png b/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_on.9.png Binary files differnew file mode 100644 index 0000000..f11058c --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/sysbar_toggle_bg_on.9.png diff --git a/packages/SystemUI/res/drawable-mdpi/system_panel_airplane_default.png b/packages/SystemUI/res/drawable-mdpi/system_panel_airplane_default.png Binary files differnew file mode 100644 index 0000000..eb87532 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/system_panel_airplane_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/system_panel_brightness_default.png b/packages/SystemUI/res/drawable-mdpi/system_panel_brightness_default.png Binary files differnew file mode 100644 index 0000000..3bfc83e --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/system_panel_brightness_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/system_panel_orientation_default.png b/packages/SystemUI/res/drawable-mdpi/system_panel_orientation_default.png Binary files differnew file mode 100644 index 0000000..0d8479c --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/system_panel_orientation_default.png diff --git a/packages/SystemUI/res/drawable-mdpi/system_panel_orientation_locked.png b/packages/SystemUI/res/drawable-mdpi/system_panel_orientation_locked.png Binary files differnew file mode 100644 index 0000000..8f1d26c --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/system_panel_orientation_locked.png diff --git a/packages/SystemUI/res/drawable-mdpi/system_panel_sound_default.png b/packages/SystemUI/res/drawable-mdpi/system_panel_sound_default.png Binary files differnew file mode 100644 index 0000000..22636d6 --- /dev/null +++ b/packages/SystemUI/res/drawable-mdpi/system_panel_sound_default.png diff --git a/packages/SystemUI/res/drawable/alert_bar_background.xml b/packages/SystemUI/res/drawable/alert_bar_background.xml new file mode 100644 index 0000000..24b6aa3 --- /dev/null +++ b/packages/SystemUI/res/drawable/alert_bar_background.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" + android:drawable="@drawable/alert_bar_background_pressed" /> + <item + android:drawable="@drawable/alert_bar_background_normal" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/button_frame.xml b/packages/SystemUI/res/drawable/button_frame.xml new file mode 100644 index 0000000..5db39a5 --- /dev/null +++ b/packages/SystemUI/res/drawable/button_frame.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/button_frame_pressed" /> + <item android:drawable="@drawable/button_frame_default" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml b/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml new file mode 100644 index 0000000..d8ba2a8 --- /dev/null +++ b/packages/SystemUI/res/drawable/ic_sysbar_icon_bg.xml @@ -0,0 +1,21 @@ +<?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_pressed="true" android:drawable="@drawable/ic_sysbar_press_bg" /> + <item android:drawable="@drawable/ic_sysbar_default_bg" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/recent_overlay.png b/packages/SystemUI/res/drawable/recent_overlay.png Binary files differnew file mode 100644 index 0000000..4dfa3d9 --- /dev/null +++ b/packages/SystemUI/res/drawable/recent_overlay.png diff --git a/packages/SystemUI/res/drawable/recent_rez_border.png b/packages/SystemUI/res/drawable/recent_rez_border.png Binary files differnew file mode 100644 index 0000000..ad025f5 --- /dev/null +++ b/packages/SystemUI/res/drawable/recent_rez_border.png diff --git a/packages/SystemUI/res/drawable/status_bar_back.xml b/packages/SystemUI/res/drawable/status_bar_back.xml new file mode 100644 index 0000000..92bf147 --- /dev/null +++ b/packages/SystemUI/res/drawable/status_bar_back.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/status_bar_back_pressed" /> + <item android:drawable="@drawable/status_bar_back_default" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/status_bar_expand.xml b/packages/SystemUI/res/drawable/status_bar_expand.xml new file mode 100644 index 0000000..f966920 --- /dev/null +++ b/packages/SystemUI/res/drawable/status_bar_expand.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/status_bar_expand_pressed" /> + <item android:drawable="@drawable/status_bar_expand_default" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/status_bar_home.xml b/packages/SystemUI/res/drawable/status_bar_home.xml new file mode 100644 index 0000000..0011711 --- /dev/null +++ b/packages/SystemUI/res/drawable/status_bar_home.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/status_bar_home_pressed" /> + <item android:drawable="@drawable/status_bar_home_default" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/status_bar_menu.xml b/packages/SystemUI/res/drawable/status_bar_menu.xml new file mode 100644 index 0000000..aa7286e --- /dev/null +++ b/packages/SystemUI/res/drawable/status_bar_menu.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/status_bar_menu_pressed" /> + <item android:drawable="@drawable/status_bar_menu_default" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/status_bar_recent.xml b/packages/SystemUI/res/drawable/status_bar_recent.xml new file mode 100755 index 0000000..d708455 --- /dev/null +++ b/packages/SystemUI/res/drawable/status_bar_recent.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- 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. +--> + +<selector xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:state_pressed="true" android:drawable="@drawable/status_bar_recent_pressed" /> + <item android:drawable="@drawable/status_bar_recent_default" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/status_bar_veto.xml b/packages/SystemUI/res/drawable/status_bar_veto.xml new file mode 100644 index 0000000..6e1b681 --- /dev/null +++ b/packages/SystemUI/res/drawable/status_bar_veto.xml @@ -0,0 +1,21 @@ +<?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_pressed="true" android:drawable="@drawable/status_bar_veto_pressed" /> + <item android:drawable="@drawable/status_bar_veto_normal" /> +</selector> + diff --git a/packages/SystemUI/res/drawable/sysbar_battery.xml b/packages/SystemUI/res/drawable/sysbar_battery.xml new file mode 100644 index 0000000..9551bf0 --- /dev/null +++ b/packages/SystemUI/res/drawable/sysbar_battery.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/drawable/stat_sys_battery.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<level-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:maxLevel="01" android:drawable="@drawable/sysbar_battery_0" /> + <item android:maxLevel="10" android:drawable="@drawable/sysbar_battery_10" /> + <item android:maxLevel="20" android:drawable="@drawable/sysbar_battery_20" /> + <item android:maxLevel="30" android:drawable="@drawable/sysbar_battery_30" /> + <item android:maxLevel="40" android:drawable="@drawable/sysbar_battery_40" /> + <item android:maxLevel="50" android:drawable="@drawable/sysbar_battery_50" /> + <item android:maxLevel="60" android:drawable="@drawable/sysbar_battery_60" /> + <item android:maxLevel="70" android:drawable="@drawable/sysbar_battery_70" /> + <item android:maxLevel="80" android:drawable="@drawable/sysbar_battery_80" /> + <item android:maxLevel="90" android:drawable="@drawable/sysbar_battery_90" /> + <item android:maxLevel="101" android:drawable="@drawable/sysbar_battery_100" /> +</level-list> diff --git a/packages/SystemUI/res/drawable/sysbar_batterymini.xml b/packages/SystemUI/res/drawable/sysbar_batterymini.xml new file mode 100644 index 0000000..c7300e6 --- /dev/null +++ b/packages/SystemUI/res/drawable/sysbar_batterymini.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/drawable/stat_sys_battery.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<clip xmlns:android="http://schemas.android.com/apk/res/android" + android:clipOrientation="horizontal" + android:maxLevel="100" + android:gravity="left"> + <level-list> + <item android:maxLevel="1500" android:drawable="@drawable/sysbar_batterymini_red" /> + <item android:maxLevel="10000" android:drawable="@drawable/sysbar_batterymini_100" /> + </level-list> +</clip> diff --git a/packages/SystemUI/res/drawable/sysbar_signal.xml b/packages/SystemUI/res/drawable/sysbar_signal.xml new file mode 100644 index 0000000..9561c37 --- /dev/null +++ b/packages/SystemUI/res/drawable/sysbar_signal.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/drawable/stat_sys_battery.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<level-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:maxLevel="01" android:drawable="@drawable/sysbar_signal_0" /> + <item android:maxLevel="10" android:drawable="@drawable/sysbar_signal_10" /> + <item android:maxLevel="20" android:drawable="@drawable/sysbar_signal_20" /> + <item android:maxLevel="30" android:drawable="@drawable/sysbar_signal_30" /> + <item android:maxLevel="40" android:drawable="@drawable/sysbar_signal_40" /> + <item android:maxLevel="50" android:drawable="@drawable/sysbar_signal_50" /> + <item android:maxLevel="60" android:drawable="@drawable/sysbar_signal_60" /> + <item android:maxLevel="70" android:drawable="@drawable/sysbar_signal_70" /> + <item android:maxLevel="80" android:drawable="@drawable/sysbar_signal_80" /> + <item android:maxLevel="90" android:drawable="@drawable/sysbar_signal_90" /> + <item android:maxLevel="101" android:drawable="@drawable/sysbar_signal_100" /> +</level-list> diff --git a/packages/SystemUI/res/drawable/sysbar_signalmini.xml b/packages/SystemUI/res/drawable/sysbar_signalmini.xml new file mode 100644 index 0000000..598bf10 --- /dev/null +++ b/packages/SystemUI/res/drawable/sysbar_signalmini.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/drawable/stat_sys_battery.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<clip xmlns:android="http://schemas.android.com/apk/res/android" + android:clipOrientation="horizontal" + android:gravity="right" + android:maxLevel="10000" + android:drawable="@drawable/sysbar_signalmini_100" /> diff --git a/packages/SystemUI/res/drawable/sysbar_wifi.xml b/packages/SystemUI/res/drawable/sysbar_wifi.xml new file mode 100644 index 0000000..9561c37 --- /dev/null +++ b/packages/SystemUI/res/drawable/sysbar_wifi.xml @@ -0,0 +1,33 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/drawable/stat_sys_battery.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<level-list xmlns:android="http://schemas.android.com/apk/res/android"> + <item android:maxLevel="01" android:drawable="@drawable/sysbar_signal_0" /> + <item android:maxLevel="10" android:drawable="@drawable/sysbar_signal_10" /> + <item android:maxLevel="20" android:drawable="@drawable/sysbar_signal_20" /> + <item android:maxLevel="30" android:drawable="@drawable/sysbar_signal_30" /> + <item android:maxLevel="40" android:drawable="@drawable/sysbar_signal_40" /> + <item android:maxLevel="50" android:drawable="@drawable/sysbar_signal_50" /> + <item android:maxLevel="60" android:drawable="@drawable/sysbar_signal_60" /> + <item android:maxLevel="70" android:drawable="@drawable/sysbar_signal_70" /> + <item android:maxLevel="80" android:drawable="@drawable/sysbar_signal_80" /> + <item android:maxLevel="90" android:drawable="@drawable/sysbar_signal_90" /> + <item android:maxLevel="101" android:drawable="@drawable/sysbar_signal_100" /> +</level-list> diff --git a/packages/SystemUI/res/drawable/sysbar_wifimini.xml b/packages/SystemUI/res/drawable/sysbar_wifimini.xml new file mode 100644 index 0000000..ca6c9ed --- /dev/null +++ b/packages/SystemUI/res/drawable/sysbar_wifimini.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* //device/apps/common/res/drawable/stat_sys_battery.xml +** +** Copyright 2007, The Android Open Source Project +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ +--> + +<clip xmlns:android="http://schemas.android.com/apk/res/android" + android:clipOrientation="horizontal" + android:gravity="right" + android:maxLevel="100" + android:drawable="@drawable/sysbar_signalmini_100" /> diff --git a/packages/SystemUI/res/layout-xlarge/status_bar.xml b/packages/SystemUI/res/layout-xlarge/status_bar.xml new file mode 100644 index 0000000..494dfa8 --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/status_bar.xml @@ -0,0 +1,190 @@ +<?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. +--> + +<!-- android:background="@drawable/status_bar_closed_default_background" --> +<com.android.systemui.statusbar.tablet.TabletStatusBarView + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" + android:background="@drawable/status_bar_background" + > + <RelativeLayout + android:id="@+id/bar_contents" + android:layout_width="match_parent" + android:layout_height="match_parent" + > + + <ImageView + android:id="@+id/expand" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:src="@drawable/ic_sysbar_open" + android:background="@drawable/ic_sysbar_icon_bg" + android:paddingLeft="6dip" + android:onClick="notificationIconsClicked" + /> + + <LinearLayout + android:id="@+id/notificationButtons" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_toRightOf="@+id/expand" + android:layout_toLeftOf="@+id/systemInfo" + android:gravity="center_vertical" + android:orientation="horizontal" + android:visibility="gone" + > + + <TextView android:id="@+id/do_not_disturb" + style="?android:attr/textAppearance" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right|center_vertical" + android:layout_marginTop="2dip" + android:layout_marginBottom="1dip" + android:layout_marginRight="10dip" + android:padding="6dip" + android:textSize="14sp" + android:text="@string/status_bar_do_not_disturb_button" + /> + + <TextView android:id="@+id/clear_all_button" + style="?android:attr/textAppearance" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="right|center_vertical" + android:layout_marginTop="2dip" + android:layout_marginBottom="1dip" + android:layout_marginRight="10dip" + android:padding="6dip" + android:textSize="14sp" + android:text="@string/status_bar_clear_all_button" + /> + + </LinearLayout> + + <com.android.systemui.statusbar.tablet.NotificationIconArea + android:id="@+id/notificationIcons" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_toRightOf="@+id/expand" + android:layout_toLeftOf="@+id/systemInfo" + android:gravity="center_vertical" + android:orientation="horizontal" + > + <view + class="com.android.systemui.statusbar.tablet.NotificationIconArea$IconLayout" + android:id="@+id/icons" + android:layout_width="wrap_content" + android:layout_height="@*android:dimen/status_bar_icon_size" + android:layout_marginLeft="8dip" + /> + <view + class="com.android.systemui.statusbar.tablet.NotificationIconArea$DraggerView" + android:id="@+id/handle" + android:layout_width="32dip" + android:layout_height="match_parent" + android:background="@drawable/sysbar_hidenotification_handle" + android:layout_marginLeft="8dip" + /> + <com.android.systemui.statusbar.tablet.InputMethodButton + android:id="@+id/imeButton" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_marginLeft="8dip" + android:src="@drawable/ic_sysbar_ime_default" + android:background="@drawable/ic_sysbar_icon_bg" + android:visibility="visible" + /> + </com.android.systemui.statusbar.tablet.NotificationIconArea> + + + <FrameLayout + android:id="@+id/ticker" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_alignParentLeft="true" + android:layout_toLeftOf="@+id/systemInfo" + android:paddingLeft="6dip" + android:gravity="center_vertical" + android:animateLayoutChanges="true" + /> + + <include layout="@layout/status_bar_center" + android:layout_width="256dip" + android:layout_height="match_parent" + android:layout_centerInParent="true" + /> + + <LinearLayout + android:id="@+id/navigationArea" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_alignParentRight="true" + android:orientation="horizontal" + > + <com.android.systemui.statusbar.KeyButtonView android:id="@+id/menu" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:src="@drawable/ic_sysbar_menu" + android:background="@drawable/ic_sysbar_icon_bg" + android:paddingLeft="4dip" + android:paddingRight="4dip" + systemui:keyCode="82" + /> + <ImageButton android:id="@+id/recent" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:src="@drawable/ic_sysbar_recent" + android:background="@drawable/ic_sysbar_icon_bg" + android:paddingLeft="4dip" + android:paddingRight="4dip" + android:onClick="recentButtonClicked" + /> + <com.android.systemui.statusbar.KeyButtonView android:id="@+id/home" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:paddingLeft="4dip" + android:paddingRight="4dip" + android:src="@drawable/ic_sysbar_home" + android:background="@drawable/ic_sysbar_icon_bg" + systemui:keyCode="3" + /> + <com.android.systemui.statusbar.KeyButtonView android:id="@+id/back" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:paddingLeft="4dip" + android:paddingRight="4dip" + android:src="@drawable/ic_sysbar_back" + android:background="@drawable/ic_sysbar_icon_bg" + systemui:keyCode="4" + /> + </LinearLayout> + </RelativeLayout> + + <!-- It's curtains for you. --> + <ImageView + android:id="@+id/lights_out" + android:src="@drawable/ic_sysbar_lightsout" + android:gravity="center" + android:background="#FF000000" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:visibility="invisible" + android:clickable="true" + /> +</com.android.systemui.statusbar.tablet.TabletStatusBarView> + diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_center.xml b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml new file mode 100644 index 0000000..2d74672 --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/status_bar_center.xml @@ -0,0 +1,73 @@ +<?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. +--> + +<!-- Center of status bar: System info display, system info panel trigger --> +<RelativeLayout android:id="@+id/systemInfo" + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_centerInParent="true" + android:clickable="true" + android:onClick="systemInfoClicked" + > + <com.android.systemui.statusbar.Clock + style="@*android:style/TextAppearance.StatusBar.Icon" + android:id="@+id/clock" + android:layout_width="64dip" + android:layout_height="48dip" + android:layout_centerInParent="true" + android:singleLine="true" + android:gravity="center" + android:textSize="16sp" + android:textStyle="bold" + android:padding="2dip" + /> + <ImageView + android:id="@+id/battery" + android:layout_width="64dip" + android:layout_height="16dip" + android:layout_toLeftOf="@id/clock" + android:layout_centerInParent="true" + android:background="@drawable/sysbar_minimeter_bg" + /> + <ImageView + android:id="@+id/signal" + android:layout_width="64dip" + android:layout_height="16dip" + android:layout_toRightOf="@id/clock" + android:layout_centerInParent="true" + android:background="@drawable/sysbar_minimeter_bg" + /> + <ImageView + android:id="@+id/battery_icon" + android:layout_height="30dip" + android:layout_width="30dip" + android:layout_toLeftOf="@id/battery" + android:layout_centerInParent="true" + android:src="@drawable/ic_sysbar_battery_mini" + /> + <ImageView + android:id="@+id/signal_icon" + android:layout_height="30dip" + android:layout_width="30dip" + android:layout_toRightOf="@id/signal" + android:layout_centerInParent="true" + android:src="@drawable/ic_sysbar_wifi_mini" + /> +</RelativeLayout> + + diff --git a/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml b/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml new file mode 100644 index 0000000..049a1cc --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/status_bar_latest_event.xml @@ -0,0 +1,38 @@ +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="65sp" + android:orientation="vertical" + android:background="@android:drawable/status_bar_item_background" + > + + <ImageButton + android:id="@+id/veto" + android:layout_width="wrap_content" + android:layout_height="match_parent" + android:layout_centerVertical="true" + android:layout_alignParentRight="true" + android:src="@drawable/status_bar_veto" + android:scaleType="center" + android:background="@null" + android:paddingLeft="16dip" + android:paddingRight="16dip" + /> + + <com.android.systemui.statusbar.LatestItemView android:id="@+id/content" + android:layout_alignParentTop="true" + android:layout_toLeftOf="@id/veto" + android:layout_width="match_parent" + android:layout_height="64sp" + android:focusable="true" + android:clickable="true" + android:paddingRight="6sp" + /> + + <View + android:layout_width="match_parent" + android:layout_height="1sp" + android:layout_alignParentBottom="true" + android:background="@android:drawable/divider_horizontal_dark" + /> + +</RelativeLayout> diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml new file mode 100644 index 0000000..80c9a49 --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_notifications.xml @@ -0,0 +1,49 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 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. +*/ +--> + +<!-- android:background="@drawable/status_bar_closed_default_background" --> +<com.android.systemui.statusbar.tablet.NotificationPanel + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:background="#FF000000" + android:orientation="vertical" + > + + <ScrollView + android:id="@+id/notificationScroller" + android:layout_height="wrap_content" + android:layout_width="match_parent" + > + <LinearLayout + android:id="@+id/content" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center_horizontal|bottom" + android:animationCache="false" + android:orientation="vertical" + android:background="@drawable/status_bar_background" + android:clickable="true" + android:focusable="true" + android:descendantFocusability="afterDescendants" + > + </LinearLayout> + </ScrollView> +</com.android.systemui.statusbar.tablet.NotificationPanel> diff --git a/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml new file mode 100644 index 0000000..7e469f7 --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/sysbar_panel_system.xml @@ -0,0 +1,208 @@ +<?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.SystemPanel + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="wrap_content" + android:layout_width="match_parent" + android:background="@drawable/sysbar_panel_bg" + android:orientation="vertical" + android:paddingLeft="70dip" + android:paddingRight="120dip" + > + + <!-- top row: quick settings buttons --> + <LinearLayout + android:layout_width="match_parent" + android:layout_height="64dip" + android:orientation="horizontal" + android:gravity="center" + > + <ImageButton android:id="@+id/brightness" + android:layout_width="90dip" + android:layout_height="64dip" + android:src="@drawable/ic_sysbar_brightness" + android:background="@drawable/sysbar_toggle_bg_off" + /> + <ImageButton android:id="@+id/sound" + android:layout_width="90dip" + android:layout_height="64dip" + android:layout_marginLeft="8dip" + android:src="@drawable/ic_sysbar_sound_on" + android:background="@drawable/sysbar_toggle_bg_off" + /> + <ImageButton android:id="@+id/orientation" + android:layout_width="90dip" + android:layout_height="64dip" + android:layout_marginLeft="8dip" + android:src="@drawable/ic_sysbar_rotate_on" + android:background="@drawable/sysbar_toggle_bg_off" + /> + <ImageButton android:id="@+id/airplane" + android:layout_width="90dip" + android:layout_height="64dip" + android:layout_marginLeft="8dip" + android:src="@drawable/ic_sysbar_airplane_on" + android:background="@drawable/sysbar_toggle_bg_off" + /> + <ImageButton android:id="@+id/gps" + android:layout_width="90dip" + android:layout_height="64dip" + android:layout_marginLeft="8dip" + android:src="@drawable/ic_sysbar_gps_on" + android:background="@drawable/sysbar_toggle_bg_off" + /> + <ImageButton android:id="@+id/bluetooth" + android:layout_width="90dip" + android:layout_height="64dip" + android:layout_marginLeft="8dip" + android:src="@drawable/ic_sysbar_bluetooth_on" + android:background="@drawable/sysbar_toggle_bg_off" + /> + </LinearLayout> + + <!-- main row: meters, clock --> + <RelativeLayout + android:padding="8dip" + android:layout_width="match_parent" + android:layout_height="192dip" + > + <RelativeLayout + android:layout_width="256dip" + android:layout_height="192dip" + android:layout_alignParentLeft="true" + android:layout_marginLeft="48dip" + > + <ImageView android:id="@+id/battery_meter" + android:layout_width="256dip" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:scaleType="centerCrop" + android:src="@drawable/sysbar_battery" + /> + <TextView android:id="@+id/battery_info" + style="@style/TextAppearance.StatusBar.SystemPanel" + android:layout_width="match_parent" + android:layout_height="24dip" + android:gravity="center" + android:layout_above="@id/battery_meter" + /> + </RelativeLayout> + + <com.android.systemui.statusbar.Clock + style="@style/TextAppearance.StatusBar.SystemPanel" + android:id="@+id/clock" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:singleLine="true" + android:textSize="50sp" + android:textStyle="normal" + android:textColor="#FFFFFFFF" + android:layout_centerHorizontal="true" + android:layout_alignParentBottom="true" + /> + + <RelativeLayout + android:layout_width="256dip" + android:layout_height="192dip" + android:layout_alignParentRight="true" + android:layout_marginRight="48dip" + > + <ImageView android:id="@+id/signal_meter" + android:layout_width="256dip" + android:layout_height="wrap_content" + android:layout_alignParentBottom="true" + android:scaleType="centerCrop" + android:src="@drawable/sysbar_signal" + /> + + <TextView android:id="@+id/signal_info" + style="@style/TextAppearance.StatusBar.SystemPanel" + android:layout_width="match_parent" + android:layout_height="24dip" + android:gravity="center" + android:layout_above="@id/signal_meter" + /> + </RelativeLayout> + + <ImageView + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_alignParentLeft="true" + android:layout_alignParentBottom="true" + android:layout_marginBottom="8dip" + android:layout_marginLeft="8dip" + android:src="@drawable/ic_sysbar_battery_on" + /> + <ImageView + android:layout_height="wrap_content" + android:layout_width="wrap_content" + android:layout_alignParentRight="true" + android:layout_alignParentBottom="true" + android:layout_marginBottom="8dip" + android:layout_marginRight="8dip" + android:src="@drawable/ic_sysbar_wifi_on" + /> + </RelativeLayout> + + <!-- bottom row: transient indicators, settings button --> + <View + android:layout_width="match_parent" + android:layout_height="1sp" + android:background="@android:drawable/divider_horizontal_dark" + /> + <RelativeLayout + android:layout_width="match_parent" + android:layout_height="48dip" + > + <LinearLayout + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentLeft="true" + android:orientation="horizontal" + > + <!-- TODO: alarm --> + <!-- TODO: sync --> + <TextView android:id="@+id/date" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + /> + </LinearLayout> + + <TextView android:id="@+id/settings_button" + style="@style/TextAppearance.StatusBar.TextButton" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_alignParentRight="true" + android:layout_centerVertical="true" + android:paddingRight="32dip" + android:paddingLeft="32dip" + android:textSize="20sp" + android:text="@string/system_panel_settings_button" + /> + <View + android:layout_height="match_parent" + android:layout_width="1sp" + android:layout_toLeftOf="@id/settings_button" + android:background="@*android:drawable/divider_vertical_dark" + /> + + </RelativeLayout> +</com.android.systemui.statusbar.tablet.SystemPanel> diff --git a/packages/SystemUI/res/layout-xlarge/ticker.xml b/packages/SystemUI/res/layout-xlarge/ticker.xml new file mode 100644 index 0000000..c8d855f --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/ticker.xml @@ -0,0 +1,53 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + android:background="#ff000000" + > + + <LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_weight="1" + android:layout_gravity="center_vertical" + android:orientation="vertical" + android:paddingLeft="12dp" + > + + <TextView android:id="@+id/title" + xmlns:android="http://schemas.android.com/apk/res/android" + android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textStyle="bold" + android:maxLines="1" + /> + <TextView android:id="@+id/subtitle" + xmlns:android="http://schemas.android.com/apk/res/android" + android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:maxLines="1" + /> + </LinearLayout> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout-xlarge/ticker_compat.xml b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml new file mode 100644 index 0000000..79c7543 --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/ticker_compat.xml @@ -0,0 +1,36 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + * Copyright (C) 2010 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="horizontal" + android:background="#ff000000" + > + + <TextView android:id="@+id/text" + android:textAppearance="@*android:style/TextAppearance.StatusBar.Ticker" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_gravity="center_vertical" + android:layout_marginLeft="12dp" + android:gravity="center_vertical" + android:maxLines="2" + /> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout-xlarge/ticker_icon.xml b/packages/SystemUI/res/layout-xlarge/ticker_icon.xml new file mode 100644 index 0000000..9efa987 --- /dev/null +++ b/packages/SystemUI/res/layout-xlarge/ticker_icon.xml @@ -0,0 +1,25 @@ +<?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. +--> + +<ImageView + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="30dp" + android:layout_height="30dp" + android:layout_gravity="center" + android:layout_marginLeft="6dp" + /> + diff --git a/packages/SystemUI/res/layout/intruder_alert.xml b/packages/SystemUI/res/layout/intruder_alert.xml new file mode 100644 index 0000000..ba4a774 --- /dev/null +++ b/packages/SystemUI/res/layout/intruder_alert.xml @@ -0,0 +1,58 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* apps/common/assets/default/default/skins/StatusBar.xml +** +** Copyright 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. +*/ +--> + +<!-- android:background="@drawable/status_bar_closed_default_background" --> +<FrameLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_height="32dip" + android:layout_width="match_parent" + android:paddingLeft="8dip" + android:paddingRight="8dip" + > + + <LinearLayout + android:id="@+id/intruder_alert_content" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center" + android:animationCache="false" + android:orientation="horizontal" + android:background="@drawable/alert_bar_background" + android:clickable="true" + android:focusable="true" + android:descendantFocusability="afterDescendants" + > + + <ImageView + android:id="@+id/alertIcon" + android:layout_width="25dip" + android:layout_height="25dip" + android:layout_marginLeft="6dip" + android:layout_marginRight="8dip" + /> + <TextView + android:id="@+id/alertText" + android:textAppearance="@style/TextAppearance.StatusBar.IntruderAlert" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:singleLine="true" + /> + </LinearLayout> +</FrameLayout> diff --git a/packages/SystemUI/res/layout/recent_apps_activity.xml b/packages/SystemUI/res/layout/recent_apps_activity.xml new file mode 100644 index 0000000..ec661e8 --- /dev/null +++ b/packages/SystemUI/res/layout/recent_apps_activity.xml @@ -0,0 +1,55 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <!-- Title --> + <TextView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:gravity="center" + android:textAppearance="?android:attr/textAppearanceSmall" + android:textColor="#80FFFFFF" + android:textStyle="bold" + android:singleLine="true" + android:text="@string/recent_tasks_title" + android:visibility="gone"/> + + <!-- This is only intended to be visible when carousel is invisible --> + <TextView + android:id="@+id/no_applications_message" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:layout_gravity="center" + android:textAppearance="?android:attr/textAppearanceSmall" + android:text="@string/recent_tasks_empty" + android:visibility="gone"/> + + <com.android.systemui.recent.RecentApplicationsCarouselView + android:id="@+id/carousel" + android:layout_width="match_parent" + android:layout_height="0dip" + android:layout_weight="1"> + </com.android.systemui.recent.RecentApplicationsCarouselView> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/recents_detail_view.xml b/packages/SystemUI/res/layout/recents_detail_view.xml new file mode 100644 index 0000000..879d0f2 --- /dev/null +++ b/packages/SystemUI/res/layout/recents_detail_view.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** Copyright 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. +*/ +--> + +<LinearLayout + xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical"> + + <!-- Application Title --> + <TextView android:id="@+id/app_title" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceMedium" + android:singleLine="true"/> + + <!-- Application Details --> + <TextView + android:id="@+id/app_description" + android:layout_width="wrap_content" + android:layout_height="wrap_content" + android:textAppearance="?android:attr/textAppearanceSmall"/> + +</LinearLayout> diff --git a/packages/SystemUI/res/layout/status_bar.xml b/packages/SystemUI/res/layout/status_bar.xml index a5d6885..2f1b36e 100644 --- a/packages/SystemUI/res/layout/status_bar.xml +++ b/packages/SystemUI/res/layout/status_bar.xml @@ -21,7 +21,8 @@ <!-- android:background="@drawable/status_bar_closed_default_background" --> <com.android.systemui.statusbar.StatusBarView xmlns:android="http://schemas.android.com/apk/res/android" - android:background="@drawable/statusbar_background" + xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui" + android:background="@drawable/status_bar_background" android:orientation="vertical" android:focusable="true" android:descendantFocusability="afterDescendants" @@ -55,6 +56,8 @@ android:layout_height="match_parent" android:singleLine="true" android:paddingRight="6dip" + android:textSize="16sp" + android:textStyle="bold" android:gravity="center_vertical|left" /> </LinearLayout> @@ -108,6 +111,6 @@ android:gravity="center_vertical|left" android:paddingLeft="6px" android:paddingRight="6px" - android:background="@drawable/statusbar_background" + android:background="@drawable/status_bar_background" /> </com.android.systemui.statusbar.StatusBarView> diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml index c744e4b..b5b1b50 100644 --- a/packages/SystemUI/res/layout/status_bar_expanded.xml +++ b/packages/SystemUI/res/layout/status_bar_expanded.xml @@ -31,7 +31,7 @@ android:paddingTop="3dp" android:paddingBottom="5dp" android:paddingRight="3dp" - android:background="@drawable/title_bar_portrait" + android:background="@drawable/shade_header_background" > <com.android.systemui.statusbar.CarrierLabel android:layout_width="0dp" @@ -43,7 +43,7 @@ android:paddingBottom="1dp" android:paddingLeft="4dp" android:textAppearance="?android:attr/textAppearanceLarge" - android:textColor="#ffdfdfdf" + android:textColor="?android:attr/textColorSecondary" /> <TextView android:id="@+id/clear_all_button" android:layout_width="wrap_content" @@ -57,7 +57,7 @@ style="?android:attr/buttonStyle" android:paddingLeft="15dp" android:paddingRight="15dp" - android:background="@android:drawable/btn_default_small" + android:background="@drawable/btn_default_small" /> </LinearLayout> @@ -71,7 +71,6 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:fadingEdge="none" - android:overScrollMode="ifContentScrolls" > <com.android.systemui.statusbar.NotificationLinearLayout android:id="@+id/notificationLinearLayout" @@ -83,7 +82,7 @@ <TextView android:id="@+id/noNotificationsTitle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/shade_bgcolor" + android:background="@drawable/title_bar_portrait" android:paddingLeft="5dp" android:textAppearance="@style/TextAppearance.StatusBar.Title" android:text="@string/status_bar_no_notifications_title" @@ -92,7 +91,7 @@ <TextView android:id="@+id/ongoingTitle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/shade_bgcolor" + android:background="@drawable/title_bar_portrait" android:paddingLeft="5dp" android:textAppearance="@style/TextAppearance.StatusBar.Title" android:text="@string/status_bar_ongoing_events_title" @@ -106,7 +105,7 @@ <TextView android:id="@+id/latestTitle" android:layout_width="match_parent" android:layout_height="wrap_content" - android:background="@drawable/shade_bgcolor" + android:background="@drawable/title_bar_portrait" android:paddingLeft="5dp" android:textAppearance="@style/TextAppearance.StatusBar.Title" android:text="@string/status_bar_latest_events_title" diff --git a/packages/SystemUI/res/layout/status_bar_latest_event.xml b/packages/SystemUI/res/layout/status_bar_latest_event.xml index b8a1cbe..88d9739 100644 --- a/packages/SystemUI/res/layout/status_bar_latest_event.xml +++ b/packages/SystemUI/res/layout/status_bar_latest_event.xml @@ -16,8 +16,8 @@ <View android:layout_width="match_parent" - android:layout_height="wrap_content" - android:background="@drawable/divider_horizontal_light_opaque" + android:layout_height="1sp" + android:background="@android:drawable/divider_horizontal_bright" /> </LinearLayout> diff --git a/packages/SystemUI/res/layout/status_bar_tracking.xml b/packages/SystemUI/res/layout/status_bar_tracking.xml index 3b9b775..a2b40e6 100644 --- a/packages/SystemUI/res/layout/status_bar_tracking.xml +++ b/packages/SystemUI/res/layout/status_bar_tracking.xml @@ -26,12 +26,11 @@ android:paddingRight="0px" > - <View - android:layout_width="match_parent" - android:layout_height="wrap_content" - android:layout_weight="1" - android:background="#ff212121" - /> + <com.android.systemui.statusbar.TrackingPatternView + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_weight="1" + /> <com.android.systemui.statusbar.CloseDragHandle android:id="@+id/close" android:layout_width="match_parent" @@ -43,7 +42,7 @@ android:layout_height="wrap_content" android:layout_gravity="bottom" android:scaleType="fitXY" - android:src="@drawable/status_bar_close_on" + android:src="@drawable/shade_handlebar" /> </com.android.systemui.statusbar.CloseDragHandle> diff --git a/packages/SystemUI/res/values-xlarge/colors.xml b/packages/SystemUI/res/values-xlarge/colors.xml new file mode 100644 index 0000000..14161c3 --- /dev/null +++ b/packages/SystemUI/res/values-xlarge/colors.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <drawable name="status_bar_background">#000000</drawable> +</resources> + diff --git a/packages/SystemUI/res/values-xlarge/config.xml b/packages/SystemUI/res/values-xlarge/config.xml new file mode 100644 index 0000000..4cf5d18d11 --- /dev/null +++ b/packages/SystemUI/res/values-xlarge/config.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/* +** 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. +*/ +--> + +<!-- These resources are around just to allow their values to be customized + for different hardware and product builds. --> +<resources> + <integer name="config_status_bar_position">1</integer> +</resources> + diff --git a/packages/SystemUI/res/values-xlarge/strings.xml b/packages/SystemUI/res/values-xlarge/strings.xml new file mode 100644 index 0000000..3c59c92 --- /dev/null +++ b/packages/SystemUI/res/values-xlarge/strings.xml @@ -0,0 +1,77 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- +/** + * Copyright (c) 2010, The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +--> +<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> + <!-- The text for the button in the notification window-shade that clears + all of the currently visible notifications. --> + <string name="status_bar_clear_all_button">Clear all</string> + + <!-- System panel ("Quick Settings") --> + + <!-- Text to display underneath the graphical battery meter. Should + include the word for "battery" and a place for the percentage charge + available. [CHAR LIMIT=20] --> + <string name="system_panel_battery_meter_format"> + Battery: <xliff:g id="number">%d</xliff:g><xliff:g id="percent">%%</xliff:g> + </string> + + <!-- Text to display underneath the graphical signal strength meter when + no connection is available. [CHAR LIMIT=20] --> + <string name="system_panel_signal_meter_disconnected"> + no internet connection + </string> + + <!-- Text to display underneath the graphical signal strength meter when + it is displaying information about a connected, named Wi-Fi network. + Should include the word for "Wi-Fi" and a placeholder for the + wireless network's SSID. [CHAR LIMIT=20] --> + <string name="system_panel_signal_meter_wifi_ssid_format"> + Wi-Fi: <xliff:g id="ssid">%s</xliff:g> + </string> + + <!-- Text to display underneath the graphical signal strength meter when + it is displaying Wi-Fi status and Wi-Fi is connected to a network + whose SSID is not available. + [CHAR LIMIT=20] --> + <string name="system_panel_signal_meter_wifi_nossid"> + Wi-Fi: connected + </string> + + <!-- Text to display underneath the graphical signal strength meter when + it is displaying Wi-Fi status and Wi-Fi is in the process of + connecting to a network. [CHAR LIMIT=20] --> + <string name="system_panel_signal_meter_wifi_connecting"> + Wi-Fi: connecting… + </string> + + <!-- Text to display underneath the graphical signal strength meter when + it is displaying mobile data (3G) status and a network connection is + available. + [CHAR LIMIT=20] --> + <string name="system_panel_signal_meter_data_connected"> + Mobile data: connected + </string> + + <!-- Text to display underneath the graphical signal strength meter when + it is displaying mobile data (3G) status and a network connection is + unavailable. + [CHAR LIMIT=20] --> + <string name="system_panel_signal_meter_data_connecting"> + Mobile data: connecting… + </string> +</resources> diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml new file mode 100644 index 0000000..23bcf20 --- /dev/null +++ b/packages/SystemUI/res/values/attrs.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- Copyright (C) 2010 The Android Open Source Project + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +--> + +<resources> + <declare-styleable name="KeyButtonView"> + <attr name="keyCode" format="integer" /> + </declare-styleable> +</resources> + diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml index 6550438..a0def6b 100644 --- a/packages/SystemUI/res/values/colors.xml +++ b/packages/SystemUI/res/values/colors.xml @@ -17,7 +17,5 @@ */ --> <resources> - <drawable name="shade_bgcolor">#ff282828</drawable> - <drawable name="notification_header_text_color">#ff969696</drawable> <drawable name="notification_number_text_color">#ffffffff</drawable> </resources> diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml index 8ea46e5..ac00c69 100644 --- a/packages/SystemUI/res/values/config.xml +++ b/packages/SystemUI/res/values/config.xml @@ -20,7 +20,16 @@ <!-- These resources are around just to allow their values to be customized for different hardware and product builds. --> <resources> - <!-- Control whether status bar should distinguish HSPA data icon form UMTS data icon on devices --> + + <!-- Control whether status bar should distinguish HSPA data icon form UMTS + data icon on devices --> <bool name="config_hspa_data_distinguishable">false</bool> + + <!-- The location of the status bar. + 0 - top + 1 - bottom + --> + <integer name="config_status_bar_position">0</integer> + </resources> diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml index ba3a3d1..1f24ba6 100644 --- a/packages/SystemUI/res/values/strings.xml +++ b/packages/SystemUI/res/values/strings.xml @@ -24,6 +24,18 @@ all of the currently visible notifications. --> <string name="status_bar_clear_all_button">Clear</string> + <!-- The text for the button in the notification window-shade that turns + on do not disturb mode, where notifications no longer show their ticker, + no sound plays, and no icons are visible. The windowshade continues to show + the notifications. --> + <string name="status_bar_do_not_disturb_button">Do not disturb</string> + + <!-- The text for the button in the notification window-shade that turns + off do not disturb mode. After clicking this, notifications will be + shown again. --> + <string name="status_bar_please_disturb_button">Show notifications</string> + + <!-- The label in the bar at the top of the status bar when there are no notifications showing. --> <string name="status_bar_no_notifications_title">No notifications</string> @@ -51,4 +63,20 @@ power usage activity to find out what drained the battery. --> <string name="battery_low_why">Battery use</string> + <!-- Name of the button that links to the Settings app. [MAXCHARS=NONE] --> + <string name="system_panel_settings_button">Settings</string> + + + <!-- Recent Tasks dialog: title + TODO: this should move to SystemUI.apk, but the code for the old + recent dialog is still in the framework + --> + <string name="recent_tasks_title">Recent</string> + <!-- Recent Tasks dialog: message when there are no recent applications + TODO: this should move to SystemUI.apk, but the code for the old + recent dialog is still in the framework + --> + <string name="recent_tasks_empty">No recent applications.</string> + + </resources> diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml index 86bcf3a..f592703 100644 --- a/packages/SystemUI/res/values/styles.xml +++ b/packages/SystemUI/res/values/styles.xml @@ -19,10 +19,24 @@ <style name="TextAppearance.StatusBar.Title" parent="@android:style/TextAppearance.StatusBar"> <item name="android:textAppearance">?android:attr/textAppearanceSmall</item> <item name="android:textStyle">bold</item> - <item name="android:textColor">@drawable/notification_header_text_color</item> + <item name="android:textColor">?android:attr/textColorPrimary</item> </style> <style name="TextAppearance.StatusBar.IntruderAlert" parent="@android:style/TextAppearance.StatusBar"> </style> + + <style name="TextAppearance.StatusBar.SystemPanel" + parent="@android:style/TextAppearance.StatusBar"> + <item name="android:textAppearance">?android:attr/textAppearance</item> + <item name="android:textStyle">normal</item> + <item name="android:textColor">#50FFFFFF</item> + </style> + + <style name="TextAppearance.StatusBar.TextButton" + parent="@android:style/TextAppearance.StatusBar"> + <item name="android:textAppearance">?android:attr/textAppearance</item> + <item name="android:textStyle">normal</item> + <item name="android:textColor">#FFFFFFFF</item> + </style> </resources> diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java new file mode 100644 index 0000000..faea3fc --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsActivity.java @@ -0,0 +1,523 @@ +/* + * 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.recent; + +import com.android.systemui.R; + +import com.android.ex.carousel.CarouselView; +import com.android.ex.carousel.CarouselViewHelper; +import com.android.ex.carousel.CarouselRS.CarouselCallback; +import com.android.ex.carousel.CarouselViewHelper.DetailTextureParameters; + +import java.util.ArrayList; +import java.util.List; + +import android.app.Activity; +import android.app.ActivityManager; +import android.app.IThumbnailReceiver; +import android.app.ActivityManager.RunningTaskInfo; +import android.content.ActivityNotFoundException; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.res.Configuration; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Matrix; +import android.graphics.Paint; +import android.graphics.PaintFlagsDrawFilter; +import android.graphics.PorterDuffXfermode; +import android.graphics.PorterDuff; +import android.graphics.Bitmap.Config; +import android.graphics.drawable.Drawable; +import android.graphics.PixelFormat; +import android.os.Bundle; +import android.os.RemoteException; +import android.util.Log; +import android.view.View; +import android.view.View.MeasureSpec; +import android.widget.TextView; + +public class RecentApplicationsActivity extends Activity { + private static final String TAG = "RecentApplicationsActivity"; + private static boolean DBG = false; + private static final int CARD_SLOTS = 56; + private static final int VISIBLE_SLOTS = 7; + private static final int MAX_TASKS = VISIBLE_SLOTS * 2; + + // TODO: these should be configurable + private static final int DETAIL_TEXTURE_MAX_WIDTH = 200; + private static final int DETAIL_TEXTURE_MAX_HEIGHT = 80; + private static final int TEXTURE_WIDTH = 256; + private static final int TEXTURE_HEIGHT = 256; + + private ActivityManager mActivityManager; + private List<RunningTaskInfo> mRunningTaskList; + private boolean mPortraitMode = true; + private ArrayList<ActivityDescription> mActivityDescriptions + = new ArrayList<ActivityDescription>(); + private CarouselView mCarouselView; + private LocalCarouselViewHelper mHelper; + private View mNoRecentsView; + private Bitmap mLoadingBitmap; + private Bitmap mRecentOverlay; + private boolean mHidden = false; + private boolean mHiding = false; + private DetailInfo mDetailInfo; + + /** + * This class is a container for all items associated with the DetailView we'll + * be drawing to a bitmap and sending to Carousel. + * + */ + static final class DetailInfo { + public DetailInfo(View _view, TextView _title, TextView _desc) { + view = _view; + title = _title; + description = _desc; + } + + /** + * Draws view into the given bitmap, if provided + * @param bitmap + */ + public Bitmap draw(Bitmap bitmap) { + resizeView(view, DETAIL_TEXTURE_MAX_WIDTH, DETAIL_TEXTURE_MAX_HEIGHT); + int desiredWidth = view.getWidth(); + int desiredHeight = view.getHeight(); + if (bitmap == null || desiredWidth != bitmap.getWidth() + || desiredHeight != bitmap.getHeight()) { + bitmap = Bitmap.createBitmap(desiredWidth, desiredHeight, Config.ARGB_8888); + } + Canvas canvas = new Canvas(bitmap); + view.draw(canvas); + return bitmap; + } + + /** + * Force a layout pass on the given view. + */ + private void resizeView(View view, int maxWidth, int maxHeight) { + int widthSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST) + | MeasureSpec.getSize(maxWidth); + int heightSpec = MeasureSpec.getMode(MeasureSpec.AT_MOST) + | MeasureSpec.getSize(maxHeight); + view.measure(widthSpec, heightSpec); + view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight()); + Log.v(TAG, "RESIZED VIEW: " + view.getWidth() + ", " + view.getHeight()); + } + + public View view; + public TextView title; + public TextView description; + } + + static class ActivityDescription { + int id; + Bitmap thumbnail; // generated by Activity.onCreateThumbnail() + Drawable icon; // application package icon + String label; // application package label + CharSequence description; // generated by Activity.onCreateDescription() + Intent intent; // launch intent for application + Matrix matrix; // arbitrary rotation matrix to correct orientation + int position; // position in list + + public ActivityDescription(Bitmap _thumbnail, + Drawable _icon, String _label, String _desc, int _id, int _pos) + { + thumbnail = _thumbnail; + icon = _icon; + label = _label; + description = _desc; + id = _id; + position = _pos; + } + + public void clear() { + icon = null; + thumbnail = null; + label = null; + description = null; + intent = null; + matrix = null; + id = -1; + position = -1; + } + }; + + private ActivityDescription findActivityDescription(int id) { + for (int i = 0; i < mActivityDescriptions.size(); i++) { + ActivityDescription item = mActivityDescriptions.get(i); + if (item != null && item.id == id) { + return item; + } + } + return null; + } + + private class LocalCarouselViewHelper extends CarouselViewHelper { + private DetailTextureParameters mDetailParams = new DetailTextureParameters(10.0f, 20.0f); + + public LocalCarouselViewHelper(Context context) { + super(context); + } + + @Override + public DetailTextureParameters getDetailTextureParameters(int id) { + return mDetailParams; + } + + public void onCardSelected(int n) { + if (n < mActivityDescriptions.size()) { + ActivityDescription item = mActivityDescriptions.get(n); + // prepare a launch intent and send it + if (item.intent != null) { + item.intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY); + try { + if (DBG) Log.v(TAG, "Starting intent " + item.intent); + startActivity(item.intent); + overridePendingTransition(R.anim.recent_app_enter, R.anim.recent_app_leave); + } catch (ActivityNotFoundException e) { + if (DBG) Log.w("Recent", "Unable to launch recent task", e); + } + finish(); + } + } + } + + @Override + public Bitmap getTexture(final int id) { + if (DBG) Log.v(TAG, "onRequestTexture(" + id + ")"); + ActivityDescription info; + synchronized(mActivityDescriptions) { + info = mActivityDescriptions.get(id); + } + Bitmap bitmap = null; + if (info != null) { + bitmap = compositeBitmap(info); + } + return bitmap; + } + + @Override + public Bitmap getDetailTexture(int n) { + Bitmap bitmap = null; + if (n < mActivityDescriptions.size()) { + ActivityDescription item = mActivityDescriptions.get(n); + mDetailInfo.title.setText(item.label); + mDetailInfo.description.setText(item.description); + bitmap = mDetailInfo.draw(null); + } + return bitmap; + } + }; + + private Bitmap compositeBitmap(ActivityDescription info) { + final int targetWidth = TEXTURE_WIDTH; + final int targetHeight = TEXTURE_HEIGHT; + final int border = 3; // inset along the edge for thumnnail content + final int overlap = 1; // how many pixels of overlap between border and thumbnail + final Resources res = getResources(); + if (mRecentOverlay == null) { + mRecentOverlay = BitmapFactory.decodeResource(res, R.drawable.recent_overlay); + } + + // Create a bitmap of the proper size/format and set the canvas to draw to it + final Bitmap result = Bitmap.createBitmap(targetWidth, targetHeight, Bitmap.Config.ARGB_8888); + final Canvas canvas = new Canvas(result); + canvas.setDrawFilter(new PaintFlagsDrawFilter(Paint.DITHER_FLAG, Paint.FILTER_BITMAP_FLAG)); + Paint paint = new Paint(); + paint.setFilterBitmap(false); + + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC)); + canvas.save(); + if (info.thumbnail != null) { + // Draw the thumbnail + int sourceWidth = targetWidth - 2 * (border - overlap); + int sourceHeight = targetHeight - 2 * (border - overlap); + final float scaleX = (float) sourceWidth / info.thumbnail.getWidth(); + final float scaleY = (float) sourceHeight / info.thumbnail.getHeight(); + canvas.translate(border * 0.5f, border * 0.5f); + canvas.scale(scaleX, scaleY); + canvas.drawBitmap(info.thumbnail, 0, 0, paint); + } else { + // Draw the Loading bitmap placeholder, TODO: Remove when RS handles blending + final float scaleX = (float) targetWidth / mLoadingBitmap.getWidth(); + final float scaleY = (float) targetHeight / mLoadingBitmap.getHeight(); + canvas.scale(scaleX, scaleY); + canvas.drawBitmap(mLoadingBitmap, 0, 0, paint); + } + canvas.restore(); + + // Draw overlay + canvas.save(); + final float scaleOverlayX = (float) targetWidth / mRecentOverlay.getWidth(); + final float scaleOverlayY = (float) targetHeight / mRecentOverlay.getHeight(); + canvas.scale(scaleOverlayX, scaleOverlayY); + paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.ADD)); + canvas.drawBitmap(mRecentOverlay, 0, 0, paint); + canvas.restore(); + + // Draw icon + if (info.icon != null) { + canvas.save(); + info.icon.draw(canvas); + canvas.restore(); + } + + return result; + } + + private final IThumbnailReceiver mThumbnailReceiver = new IThumbnailReceiver.Stub() { + + public void finished() throws RemoteException { + + } + + public void newThumbnail(final int id, final Bitmap bitmap, CharSequence description) + throws RemoteException { + int w = bitmap.getWidth(); + int h = bitmap.getHeight(); + if (DBG) Log.v(TAG, "New thumbnail for id=" + id + ", dimensions=" + w + "x" + h + + " description '" + description + "'"); + ActivityDescription info = findActivityDescription(id); + if (info != null) { + info.thumbnail = bitmap; + info.description = description; + final int thumbWidth = bitmap.getWidth(); + final int thumbHeight = bitmap.getHeight(); + if ((mPortraitMode && thumbWidth > thumbHeight) + || (!mPortraitMode && thumbWidth < thumbHeight)) { + Matrix matrix = new Matrix(); + matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2); + info.matrix = matrix; + } else { + info.matrix = null; + } + // Force Carousel to request new textures for this item. + mCarouselView.setTextureForItem(info.position, null); + mCarouselView.setDetailTextureForItem(info.position, 0, 0, 0, 0, null); + } else { + if (DBG) Log.v(TAG, "Can't find view for id " + id); + } + } + }; + + /** + * We never really finish() RecentApplicationsActivity, since we don't want to + * get destroyed and pay the start-up cost to restart it. + */ + @Override + public void finish() { + moveTaskToBack(true); + } + + @Override + protected void onNewIntent(Intent intent) { + mHidden = !mHidden; + if (mHidden) { + mHiding = true; + moveTaskToBack(true); + } else { + mHiding = false; + } + super.onNewIntent(intent); + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + final Resources res = getResources(); + final View decorView = getWindow().getDecorView(); + + getWindow().getDecorView().setBackgroundColor(0x80000000); + + if (mCarouselView == null) { + long t = System.currentTimeMillis(); + setContentView(R.layout.recent_apps_activity); + long elapsed = System.currentTimeMillis() - t; + Log.v(TAG, "Recents layout took " + elapsed + "ms to load"); + mLoadingBitmap = BitmapFactory.decodeResource(res, R.drawable.recent_rez_border); + mCarouselView = (CarouselView)findViewById(R.id.carousel); + mHelper = new LocalCarouselViewHelper(this); + mHelper.setCarouselView(mCarouselView); + + mCarouselView.setSlotCount(CARD_SLOTS); + mCarouselView.setVisibleSlots(VISIBLE_SLOTS); + mCarouselView.createCards(0); + mCarouselView.setStartAngle((float) -(2.0f*Math.PI * 5 / CARD_SLOTS)); + mCarouselView.setDefaultBitmap(mLoadingBitmap); + mCarouselView.setLoadingBitmap(mLoadingBitmap); + mCarouselView.setRezInCardCount(3.0f); + mCarouselView.getHolder().setFormat(PixelFormat.TRANSLUCENT); + + mNoRecentsView = (View) findViewById(R.id.no_applications_message); + + mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + mPortraitMode = decorView.getHeight() > decorView.getWidth(); + + // Load detail view which will be used to render text + View detail = getLayoutInflater().inflate(R.layout.recents_detail_view, null); + TextView title = (TextView) detail.findViewById(R.id.app_title); + TextView description = (TextView) detail.findViewById(R.id.app_description); + mDetailInfo = new DetailInfo(detail, title, description); + + refresh(); + } + } + + @Override + protected void onResume() { + super.onResume(); + refresh(); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + mPortraitMode = newConfig.orientation == Configuration.ORIENTATION_PORTRAIT; + if (DBG) Log.v(TAG, "CONFIG CHANGE, mPortraitMode = " + mPortraitMode); + refresh(); + } + + void updateRunningTasks() { + mRunningTaskList = mActivityManager.getRunningTasks(MAX_TASKS, 0, mThumbnailReceiver); + if (DBG) Log.v(TAG, "Portrait: " + mPortraitMode); + for (RunningTaskInfo r : mRunningTaskList) { + if (r.thumbnail != null) { + int thumbWidth = r.thumbnail.getWidth(); + int thumbHeight = r.thumbnail.getHeight(); + if (DBG) Log.v(TAG, "Got thumbnail " + thumbWidth + "x" + thumbHeight); + ActivityDescription desc = findActivityDescription(r.id); + if (desc != null) { + desc.thumbnail = r.thumbnail; + desc.description = r.description; + if ((mPortraitMode && thumbWidth > thumbHeight) + || (!mPortraitMode && thumbWidth < thumbHeight)) { + Matrix matrix = new Matrix(); + matrix.setRotate(90.0f, (float) thumbWidth / 2, (float) thumbHeight / 2); + desc.matrix = matrix; + } + } else { + if (DBG) Log.v(TAG, "Couldn't find ActivityDesc for id=" + r.id); + } + } else { + if (DBG) Log.v(TAG, "*** RUNNING THUMBNAIL WAS NULL ***"); + } + } + } + + private void updateRecentTasks() { + final PackageManager pm = getPackageManager(); + final ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE); + + final List<ActivityManager.RecentTaskInfo> recentTasks = + am.getRecentTasks(MAX_TASKS, ActivityManager.RECENT_IGNORE_UNAVAILABLE); + + ActivityInfo homeInfo = new Intent(Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_HOME) + .resolveActivityInfo(pm, 0); + + // IconUtilities iconUtilities = new IconUtilities(this); // FIXME + + int numTasks = recentTasks.size(); + mActivityDescriptions.clear(); + for (int i = 0, index = 0; i < numTasks && (index < MAX_TASKS); ++i) { + final ActivityManager.RecentTaskInfo recentInfo = recentTasks.get(i); + + Intent intent = new Intent(recentInfo.baseIntent); + if (recentInfo.origActivity != null) { + intent.setComponent(recentInfo.origActivity); + } + + // Skip the current 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 info = resolveInfo.activityInfo; + final String title = info.loadLabel(pm).toString(); + Drawable icon = info.loadIcon(pm); + + int id = recentTasks.get(i).id; + if (id != -1 && title != null && title.length() > 0 && icon != null) { + // icon = null; FIXME: iconUtilities.createIconDrawable(icon); + ActivityDescription item = new ActivityDescription( + null, icon, title, null, id, index); + item.intent = intent; + mActivityDescriptions.add(item); + if (DBG) Log.v(TAG, "Added item[" + index + + "], id=" + item.id + + ", title=" + item.label); + ++index; + } else { + if (DBG) Log.v(TAG, "SKIPPING item " + id); + } + } + } + } + + private final Runnable mRefreshRunnable = new Runnable() { + public void run() { + updateRecentTasks(); + updateRunningTasks(); + showCarousel(mActivityDescriptions.size() > 0); + } + }; + + private void showCarousel(boolean show) { + if (show) { + mCarouselView.createCards(mActivityDescriptions.size()); + for (int i = 1; i < mActivityDescriptions.size(); i++) { + // Force Carousel to update textures. Note we don't do this for the first item, + // since it will be updated when mThumbnailReceiver returns a thumbnail. + // TODO: only do this for apps that have changed. + mCarouselView.setTextureForItem(i, null); + mCarouselView.setDetailTextureForItem(i, 0, 0, 0, 0, null); + } + // Make carousel visible + mNoRecentsView.setVisibility(View.GONE); + mCarouselView.setVisibility(View.VISIBLE); + mCarouselView.createCards(mActivityDescriptions.size()); + } else { + // show "No Recent Tasks" + mNoRecentsView.setVisibility(View.VISIBLE); + mCarouselView.setVisibility(View.GONE); + } + } + + private void refresh() { + if (!mHiding && mCarouselView != null) { + // Don't update the view now. Instead, post a request so it happens next time + // we reach the looper after a delay. This way we can fold multiple refreshes + // into just the latest. + mCarouselView.removeCallbacks(mRefreshRunnable); + mCarouselView.postDelayed(mRefreshRunnable, 50); + } + } +} diff --git a/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsCarouselView.java b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsCarouselView.java new file mode 100644 index 0000000..1c8ec95 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/recent/RecentApplicationsCarouselView.java @@ -0,0 +1,39 @@ +/* + * 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.recent; + +import android.content.Context; +import android.util.AttributeSet; + +import com.android.ex.carousel.CarouselView; +import com.android.systemui.R; + +public class RecentApplicationsCarouselView extends CarouselView { + + public RecentApplicationsCarouselView(Context context) { + this(context, null); + } + + public RecentApplicationsCarouselView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public Info getRenderScriptInfo() { + return new Info(R.raw.carousel); + } + +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java b/packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java index f45caf5..0f6723e 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CloseDragHandle.java @@ -23,7 +23,7 @@ import android.widget.LinearLayout; public class CloseDragHandle extends LinearLayout { - StatusBarService mService; + PhoneStatusBarService mService; public CloseDragHandle(Context context, AttributeSet attrs) { super(context, attrs); diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java index 4f080d5..81091e3 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java @@ -32,7 +32,7 @@ import com.android.internal.statusbar.StatusBarNotification; * coalescing these calls so they don't stack up. For the calls * are coalesced, note that they are all idempotent. */ -class CommandQueue extends IStatusBar.Stub { +public class CommandQueue extends IStatusBar.Stub { private static final String TAG = "StatusBar.CommandQueue"; private static final int MSG_MASK = 0xffff0000; @@ -52,6 +52,8 @@ class CommandQueue extends IStatusBar.Stub { private static final int OP_EXPAND = 1; private static final int OP_COLLAPSE = 2; + private static final int MSG_SET_LIGHTS_ON = 0x00070000; + private StatusBarIconList mList; private Callbacks mCallbacks; private Handler mHandler = new H(); @@ -75,6 +77,7 @@ class CommandQueue extends IStatusBar.Stub { public void disable(int state); public void animateExpand(); public void animateCollapse(); + public void setLightsOn(boolean on); } public CommandQueue(Callbacks callbacks, StatusBarIconList list) { @@ -143,6 +146,13 @@ class CommandQueue extends IStatusBar.Stub { } } + public void setLightsOn(boolean on) { + synchronized (mList) { + mHandler.removeMessages(MSG_SET_LIGHTS_ON); + mHandler.obtainMessage(MSG_SET_LIGHTS_ON, on ? 1 : 0, 0, null).sendToTarget(); + } + } + private final class H extends Handler { public void handleMessage(Message msg) { final int what = msg.what & MSG_MASK; @@ -196,6 +206,10 @@ class CommandQueue extends IStatusBar.Stub { } else { mCallbacks.animateCollapse(); } + break; + case MSG_SET_LIGHTS_ON: + mCallbacks.setLightsOn(msg.arg1 != 0); + break; } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java index 3d85f27..a2d4b95 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandedView.java @@ -27,7 +27,7 @@ import android.util.Slog; public class ExpandedView extends LinearLayout { - StatusBarService mService; + PhoneStatusBarService mService; int mPrevHeight = -1; public ExpandedView(Context context, AttributeSet attrs) { @@ -53,7 +53,7 @@ public class ExpandedView extends LinearLayout { //Slog.d(StatusBarService.TAG, "height changed old=" + mPrevHeight // + " new=" + height); mPrevHeight = height; - mService.updateExpandedViewPos(StatusBarService.EXPANDED_LEAVE_ALONE); + mService.updateExpandedViewPos(PhoneStatusBarService.EXPANDED_LEAVE_ALONE); } } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java new file mode 100644 index 0000000..b01c5e7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyButtonView.java @@ -0,0 +1,143 @@ +/* + * 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; + +import android.content.Context; +import android.content.res.TypedArray; +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.KeyEvent; +import android.view.MotionEvent; +import android.view.ViewConfiguration; +import android.widget.ImageView; +import android.widget.RemoteViews.RemoteView; + +import com.android.systemui.R; + +public class KeyButtonView extends ImageView { + IWindowManager mWindowManager; + long mDownTime; + boolean mSending, mLongPressed; + int mCode; + int mRepeat; + Runnable mCheckLongPress = new Runnable() { + public void run() { + Slog.d("KeyButtonView", "longpress"); + if (isPressed()) { + mLongPressed = true; + mRepeat++; + sendEvent(KeyEvent.ACTION_DOWN, + KeyEvent.FLAG_FROM_SYSTEM + | KeyEvent.FLAG_VIRTUAL_HARD_KEY + | KeyEvent.FLAG_LONG_PRESS); + } + } + }; + + public KeyButtonView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public KeyButtonView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs); + + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.KeyButtonView, + defStyle, 0); + + mCode = a.getInteger(R.styleable.KeyButtonView_keyCode, 0); + if (mCode == 0) { + Slog.w(StatusBarService.TAG, "KeyButtonView without key code id=0x" + + Integer.toHexString(getId())); + } + + a.recycle(); + + mWindowManager = IWindowManager.Stub.asInterface( + ServiceManager.getService(Context.WINDOW_SERVICE)); + } + + public boolean onTouchEvent(MotionEvent ev) { + final int action = ev.getAction(); + int x, y; + + switch (action) { + case MotionEvent.ACTION_DOWN: + //Slog.d("KeyButtonView", "press"); + mDownTime = SystemClock.uptimeMillis(); + mRepeat = 0; + mSending = true; + mLongPressed = false; + sendEvent(KeyEvent.ACTION_DOWN, + KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY, mDownTime); + setPressed(true); + removeCallbacks(mCheckLongPress); + postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout()); + break; + case MotionEvent.ACTION_MOVE: + if (mSending) { + x = (int)ev.getX(); + y = (int)ev.getY(); + if (x < 0 || x >= getWidth() || y < 0 || y >= getHeight()) { + mSending = false; + sendEvent(KeyEvent.ACTION_UP, + KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY + | KeyEvent.FLAG_CANCELED); + setPressed(false); + removeCallbacks(mCheckLongPress); + } + } + break; + case MotionEvent.ACTION_UP: + case MotionEvent.ACTION_CANCEL: + setPressed(false); + if (mSending && !mLongPressed) { + mSending = false; + sendEvent(KeyEvent.ACTION_UP, + KeyEvent.FLAG_FROM_SYSTEM | KeyEvent.FLAG_VIRTUAL_HARD_KEY); + removeCallbacks(mCheckLongPress); + } + break; + } + + return true; + } + + void sendEvent(int action, int flags) { + sendEvent(action, flags, SystemClock.uptimeMillis()); + } + + void sendEvent(int action, int flags, long when) { + final KeyEvent ev = new KeyEvent(mDownTime, when, action, mCode, mRepeat, + 0, 0, 0, flags, InputDevice.SOURCE_KEYBOARD); + try { + //Slog.d(StatusBarService.TAG, "injecting event " + ev); + mWindowManager.injectInputEventNoWait(ev); + } catch (RemoteException ex) { + // System process is dead + } + } +} + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java index 7a82267..7e8a5c1 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java @@ -22,6 +22,7 @@ import android.view.View; import com.android.internal.statusbar.StatusBarNotification; +import java.util.Comparator; import java.util.ArrayList; /** @@ -35,26 +36,47 @@ public class NotificationData { public View row; // the outer expanded view public View content; // takes the click events and sends the PendingIntent public View expanded; // the inflated RemoteViews + public Entry() {} + public Entry(IBinder key, StatusBarNotification n, StatusBarIconView ic) { + this.key = key; + this.notification = n; + this.icon = ic; + } } private final ArrayList<Entry> mEntries = new ArrayList<Entry>(); + private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() { + public int compare(Entry a, Entry b) { + return (int)(a.notification.notification.when - b.notification.notification.when); + } + }; public int size() { return mEntries.size(); } - public Entry getEntryAt(int index) { - return mEntries.get(index); + public Entry get(int i) { + return mEntries.get(i); + } + + public Entry findByKey(IBinder key) { + for (Entry e : mEntries) { + if (e.key == key) { + return e; + } + } + return null; } - public int findEntry(IBinder key) { - final int N = mEntries.size(); - for (int i=0; i<N; i++) { - Entry entry = mEntries.get(i); - if (entry.key == key) { - return i; + public int add(Entry entry) { + int i; + int N = mEntries.size(); + for (i=0; i<N; i++) { + if (mEntryCmp.compare(mEntries.get(i), entry) > 0) { + break; } } - return -1; + mEntries.add(i, entry); + return i; } public int add(IBinder key, StatusBarNotification notification, View row, View content, @@ -66,42 +88,23 @@ public class NotificationData { entry.content = content; entry.expanded = expanded; entry.icon = icon; - final int index = chooseIndex(notification.notification.when); - mEntries.add(index, entry); - return index; + return add(entry); } public Entry remove(IBinder key) { - final int N = mEntries.size(); - for (int i=0; i<N; i++) { - Entry entry = mEntries.get(i); - if (entry.key == key) { - mEntries.remove(i); - return entry; - } - } - return null; - } - - private int chooseIndex(final long when) { - final int N = mEntries.size(); - for (int i=0; i<N; i++) { - Entry entry = mEntries.get(i); - if (entry.notification.notification.when > when) { - return i; - } + Entry e = findByKey(key); + if (e != null) { + mEntries.remove(e); } - return N; + return e; } /** * Return whether there are any visible items (i.e. items without an error). */ public boolean hasVisibleItems() { - final int N = mEntries.size(); - for (int i=0; i<N; i++) { - Entry entry = mEntries.get(i); - if (entry.expanded != null) { // the view successfully inflated + for (Entry e : mEntries) { + if (e.expanded != null) { // the view successfully inflated return true; } } @@ -112,11 +115,9 @@ public class NotificationData { * Return whether there are any clearable items (that aren't errors). */ public boolean hasClearableItems() { - final int N = mEntries.size(); - for (int i=0; i<N; i++) { - Entry entry = mEntries.get(i); - if (entry.expanded != null) { // the view successfully inflated - if ((entry.notification.notification.flags & Notification.FLAG_NO_CLEAR) == 0) { + for (Entry e : mEntries) { + if (e.expanded != null) { // the view successfully inflated + if (e.notification.isClearable()) { return true; } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java new file mode 100644 index 0000000..57ebd27 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/PhoneStatusBarService.java @@ -0,0 +1,1558 @@ +/* + * 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; + +import android.app.Service; +import android.app.ActivityManagerNative; +import android.app.Dialog; +import android.app.Notification; +import android.app.PendingIntent; +import android.app.Service; +import android.app.StatusBarManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.net.Uri; +import android.os.IBinder; +import android.os.RemoteException; +import android.os.Binder; +import android.os.Handler; +import android.os.Message; +import android.os.SystemClock; +import android.text.TextUtils; +import android.util.Slog; +import android.util.Log; +import android.view.Display; +import android.view.Gravity; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.View; +import android.view.ViewGroup; +import android.view.Window; +import android.view.WindowManager; +import android.view.WindowManagerImpl; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RemoteViews; +import android.widget.ScrollView; +import android.widget.TextView; +import android.widget.FrameLayout; + +import java.io.FileDescriptor; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Set; + +import com.android.internal.statusbar.IStatusBar; +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarIconList; +import com.android.internal.statusbar.StatusBarNotification; + +import com.android.systemui.R; +import com.android.systemui.statusbar.policy.StatusBarPolicy; + + + +public class PhoneStatusBarService extends StatusBarService { + static final String TAG = "PhoneStatusBarService"; + static final boolean SPEW = false; + + public static final String ACTION_STATUSBAR_START + = "com.android.internal.policy.statusbar.START"; + + static final int EXPANDED_LEAVE_ALONE = -10000; + static final int EXPANDED_FULL_OPEN = -10001; + + private static final int MSG_ANIMATE = 1000; + private static final int MSG_ANIMATE_REVEAL = 1001; + private static final int MSG_SHOW_INTRUDER = 1002; + private static final int MSG_HIDE_INTRUDER = 1003; + + // will likely move to a resource or other tunable param at some point + private static final int INTRUDER_ALERT_DECAY_MS = 10000; + + StatusBarPolicy mIconPolicy; + + int mIconSize; + Display mDisplay; + + StatusBarView mStatusBarView; + int mPixelFormat; + H mHandler = new H(); + Object mQueueLock = new Object(); + + // icons + LinearLayout mIcons; + IconMerger mNotificationIcons; + LinearLayout mStatusIcons; + + // expanded notifications + Dialog mExpandedDialog; + ExpandedView mExpandedView; + WindowManager.LayoutParams mExpandedParams; + ScrollView mScrollView; + View mNotificationLinearLayout; + View mExpandedContents; + // top bar + TextView mNoNotificationsTitle; + TextView mClearButton; + // drag bar + CloseDragHandle mCloseView; + // ongoing + NotificationData mOngoing = new NotificationData(); + TextView mOngoingTitle; + LinearLayout mOngoingItems; + // latest + NotificationData mLatest = new NotificationData(); + TextView mLatestTitle; + LinearLayout mLatestItems; + // position + int[] mPositionTmp = new int[2]; + boolean mExpanded; + boolean mExpandedVisible; + + // the date view + DateView mDateView; + + // for immersive activities + private View mIntruderAlertView; + + // the tracker view + TrackingView mTrackingView; + WindowManager.LayoutParams mTrackingParams; + int mTrackingPosition; // the position of the top of the tracking view. + private boolean mPanelSlightlyVisible; + + // ticker + private Ticker mTicker; + private View mTickerView; + private boolean mTicking; + + // Tracking finger for opening/closing. + int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore + boolean mTracking; + VelocityTracker mVelocityTracker; + + static final int ANIM_FRAME_DURATION = (1000/60); + + boolean mAnimating; + long mCurAnimationTime; + float mDisplayHeight; + float mAnimY; + float mAnimVel; + float mAnimAccel; + long mAnimLastTime; + boolean mAnimatingReveal = false; + int mViewDelta; + int[] mAbsPos = new int[2]; + + // for disabling the status bar + int mDisabled = 0; + + private class ExpandedDialog extends Dialog { + ExpandedDialog(Context context) { + super(context, com.android.internal.R.style.Theme_Light_NoTitleBar); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + boolean down = event.getAction() == KeyEvent.ACTION_DOWN; + switch (event.getKeyCode()) { + case KeyEvent.KEYCODE_BACK: + if (!down) { + animateCollapse(); + } + return true; + } + return super.dispatchKeyEvent(event); + } + } + + @Override + public void onCreate() { + mDisplay = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + + super.onCreate(); + + addIntruderView(); + + // Lastly, call to the icon policy to install/update all the icons. + mIconPolicy = new StatusBarPolicy(this); + } + + @Override + public void onDestroy() { + // we're never destroyed + } + + // ================================================================================ + // Constructing the view + // ================================================================================ + protected View makeStatusBarView() { + final Context context = this; + + Resources res = context.getResources(); + + mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size); + + ExpandedView expanded = (ExpandedView)View.inflate(context, + R.layout.status_bar_expanded, null); + expanded.mService = this; + + mIntruderAlertView = View.inflate(context, R.layout.intruder_alert, null); + mIntruderAlertView.setVisibility(View.GONE); + mIntruderAlertView.setClickable(true); + + StatusBarView sb = (StatusBarView)View.inflate(context, R.layout.status_bar, null); + sb.mService = this; + + // figure out which pixel-format to use for the status bar. + mPixelFormat = PixelFormat.TRANSLUCENT; + Drawable bg = sb.getBackground(); + if (bg != null) { + mPixelFormat = bg.getOpacity(); + } + + mStatusBarView = sb; + mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons); + mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons); + mIcons = (LinearLayout)sb.findViewById(R.id.icons); + mTickerView = sb.findViewById(R.id.ticker); + mDateView = (DateView)sb.findViewById(R.id.date); + + mExpandedDialog = new ExpandedDialog(context); + mExpandedView = expanded; + mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout); + mOngoingTitle = (TextView)expanded.findViewById(R.id.ongoingTitle); + mOngoingItems = (LinearLayout)expanded.findViewById(R.id.ongoingItems); + mLatestTitle = (TextView)expanded.findViewById(R.id.latestTitle); + mLatestItems = (LinearLayout)expanded.findViewById(R.id.latestItems); + mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle); + mClearButton = (TextView)expanded.findViewById(R.id.clear_all_button); + mClearButton.setOnClickListener(mClearButtonListener); + mScrollView = (ScrollView)expanded.findViewById(R.id.scroll); + mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout); + + mOngoingTitle.setVisibility(View.GONE); + mLatestTitle.setVisibility(View.GONE); + + mTicker = new MyTicker(context, sb); + + TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText); + tickerView.mTicker = mTicker; + + mTrackingView = (TrackingView)View.inflate(context, R.layout.status_bar_tracking, null); + mTrackingView.mService = this; + mCloseView = (CloseDragHandle)mTrackingView.findViewById(R.id.close); + mCloseView.mService = this; + + mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore); + + // set the inital view visibility + setAreThereNotifications(); + mDateView.setVisibility(View.INVISIBLE); + + // receive broadcasts + IntentFilter filter = new IntentFilter(); + filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); + filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); + filter.addAction(Intent.ACTION_SCREEN_OFF); + context.registerReceiver(mBroadcastReceiver, filter); + + return sb; + } + + protected int getStatusBarGravity() { + return Gravity.TOP | Gravity.FILL_HORIZONTAL; + } + + private void addIntruderView() { + final Resources res = getResources(); + final int height= res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); + + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.WRAP_CONTENT, + WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, + PixelFormat.TRANSLUCENT); + lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; + lp.y += height * 1.5; // FIXME + lp.setTitle("IntruderAlert"); + lp.windowAnimations = com.android.internal.R.style.Animation_StatusBar_IntruderAlert; + + WindowManagerImpl.getDefault().addView(mIntruderAlertView, lp); + } + + public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) { + if (SPEW) Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex + + " icon=" + icon); + StatusBarIconView view = new StatusBarIconView(this, slot); + view.set(icon); + mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize)); + } + + public void updateIcon(String slot, int index, int viewIndex, + StatusBarIcon old, StatusBarIcon icon) { + if (SPEW) Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex + + " old=" + old + " icon=" + icon); + StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex); + view.set(icon); + } + + public void removeIcon(String slot, int index, int viewIndex) { + if (SPEW) Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex); + mStatusIcons.removeViewAt(viewIndex); + } + + public void addNotification(IBinder key, StatusBarNotification notification) { + StatusBarIconView iconView = addNotificationViews(key, notification); + if (iconView == null) return; + + boolean immersive = false; + try { + immersive = ActivityManagerNative.getDefault().isTopActivityImmersive(); + Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive")); + } catch (RemoteException ex) { + } + if (immersive) { + if ((notification.notification.flags & Notification.FLAG_HIGH_PRIORITY) != 0) { + Slog.d(TAG, "Presenting high-priority notification in immersive activity"); + // special new transient ticker mode + // 1. Populate mIntruderAlertView + + ImageView alertIcon = (ImageView) mIntruderAlertView.findViewById(R.id.alertIcon); + TextView alertText = (TextView) mIntruderAlertView.findViewById(R.id.alertText); + alertIcon.setImageDrawable(StatusBarIconView.getIcon( + alertIcon.getContext(), + iconView.getStatusBarIcon())); + alertText.setText(notification.notification.tickerText); + + View button = mIntruderAlertView.findViewById(R.id.intruder_alert_content); + button.setOnClickListener( + new Launcher(notification.notification.contentIntent, + notification.pkg, notification.tag, notification.id)); + + // 2. Animate mIntruderAlertView in + mHandler.sendEmptyMessage(MSG_SHOW_INTRUDER); + + // 3. Set alarm to age the notification off (TODO) + mHandler.removeMessages(MSG_HIDE_INTRUDER); + mHandler.sendEmptyMessageDelayed(MSG_HIDE_INTRUDER, INTRUDER_ALERT_DECAY_MS); + } + } else if (notification.notification.fullScreenIntent != null) { + // not immersive & a full-screen alert should be shown + Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;" + + " sending fullScreenIntent"); + try { + notification.notification.fullScreenIntent.send(); + } catch (PendingIntent.CanceledException e) { + } + } else { + // usual case: status bar visible & not immersive + + // show the ticker + tick(notification); + } + + // Recalculate the position of the sliding windows and the titles. + setAreThereNotifications(); + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); + } + + public void updateNotification(IBinder key, StatusBarNotification notification) { + Slog.d(TAG, "updateNotification key=" + key + " notification=" + notification); + + NotificationData oldList; + NotificationData.Entry oldEntry = mOngoing.findByKey(key); + if (oldEntry != null) { + oldList = mOngoing; + } else { + oldEntry = mLatest.findByKey(key); + if (oldEntry == null) { + Slog.w(TAG, "updateNotification for unknown key: " + key); + return; + } + oldList = mLatest; + } + final StatusBarNotification oldNotification = oldEntry.notification; + final RemoteViews oldContentView = oldNotification.notification.contentView; + + final RemoteViews contentView = notification.notification.contentView; + + if (false) { + Slog.d(TAG, "old notification: when=" + oldNotification.notification.when + + " ongoing=" + oldNotification.isOngoing() + + " expanded=" + oldEntry.expanded + + " contentView=" + oldContentView); + Slog.d(TAG, "new notification: when=" + notification.notification.when + + " ongoing=" + oldNotification.isOngoing() + + " contentView=" + contentView); + } + + // Can we just reapply the RemoteViews in place? If when didn't change, the order + // didn't change. + if (notification.notification.when == oldNotification.notification.when + && notification.isOngoing() == oldNotification.isOngoing() + && oldEntry.expanded != null + && contentView != null && oldContentView != null + && contentView.getPackage() != null + && oldContentView.getPackage() != null + && oldContentView.getPackage().equals(contentView.getPackage()) + && oldContentView.getLayoutId() == contentView.getLayoutId()) { + if (SPEW) Slog.d(TAG, "reusing notification"); + oldEntry.notification = notification; + try { + // Reapply the RemoteViews + contentView.reapply(this, oldEntry.content); + // update the contentIntent + final PendingIntent contentIntent = notification.notification.contentIntent; + if (contentIntent != null) { + oldEntry.content.setOnClickListener(new Launcher(contentIntent, + notification.pkg, notification.tag, notification.id)); + } + // Update the icon. + final StatusBarIcon ic = new StatusBarIcon(notification.pkg, + notification.notification.icon, notification.notification.iconLevel, + notification.notification.number); + if (!oldEntry.icon.set(ic)) { + handleNotificationError(key, notification, "Couldn't update icon: " + ic); + return; + } + } + catch (RuntimeException e) { + // It failed to add cleanly. Log, and remove the view from the panel. + Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); + removeNotificationViews(key); + addNotificationViews(key, notification); + } + } else { + if (SPEW) Slog.d(TAG, "not reusing notification"); + removeNotificationViews(key); + addNotificationViews(key, notification); + } + + // Restart the ticker if it's still running + if (notification.notification.tickerText != null + && !TextUtils.equals(notification.notification.tickerText, + oldEntry.notification.notification.tickerText)) { + tick(notification); + } + + // Recalculate the position of the sliding windows and the titles. + setAreThereNotifications(); + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); + } + + public void removeNotification(IBinder key) { + if (SPEW) Slog.d(TAG, "removeNotification key=" + key); + StatusBarNotification old = removeNotificationViews(key); + + if (old != null) { + // Cancel the ticker if it's still running + mTicker.removeEntry(old); + + // Recalculate the position of the sliding windows and the titles. + setAreThereNotifications(); + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); + } + } + + private int chooseIconIndex(boolean isOngoing, int viewIndex) { + final int latestSize = mLatest.size(); + if (isOngoing) { + return latestSize + (mOngoing.size() - viewIndex); + } else { + return latestSize - viewIndex; + } + } + + View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) { + Notification n = notification.notification; + RemoteViews remoteViews = n.contentView; + if (remoteViews == null) { + return null; + } + + // create the row view + LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View row = inflater.inflate(R.layout.status_bar_latest_event, parent, false); + + // bind the click event to the content area + ViewGroup content = (ViewGroup)row.findViewById(R.id.content); + content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); + content.setOnFocusChangeListener(mFocusChangeListener); + PendingIntent contentIntent = n.contentIntent; + if (contentIntent != null) { + content.setOnClickListener(new Launcher(contentIntent, notification.pkg, + notification.tag, notification.id)); + } + + View expanded = null; + Exception exception = null; + try { + expanded = remoteViews.apply(this, content); + } + catch (RuntimeException e) { + exception = e; + } + if (expanded == null) { + String ident = notification.pkg + "/0x" + Integer.toHexString(notification.id); + Slog.e(TAG, "couldn't inflate view for notification " + ident, exception); + return null; + } else { + content.addView(expanded); + row.setDrawingCacheEnabled(true); + } + + return new View[] { row, content, expanded }; + } + + StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) { + NotificationData list; + ViewGroup parent; + final boolean isOngoing = notification.isOngoing(); + if (isOngoing) { + list = mOngoing; + parent = mOngoingItems; + } else { + list = mLatest; + parent = mLatestItems; + } + // Construct the expanded view. + final View[] views = makeNotificationView(notification, parent); + if (views == null) { + handleNotificationError(key, notification, "Couldn't expand RemoteViews for: " + + notification); + return null; + } + final View row = views[0]; + final View content = views[1]; + final View expanded = views[2]; + // Construct the icon. + final StatusBarIconView iconView = new StatusBarIconView(this, + notification.pkg + "/0x" + Integer.toHexString(notification.id)); + final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon, + notification.notification.iconLevel, notification.notification.number); + if (!iconView.set(ic)) { + handleNotificationError(key, notification, "Coulding create icon: " + ic); + return null; + } + // Add the expanded view. + final int viewIndex = list.add(key, notification, row, content, expanded, iconView); + parent.addView(row, viewIndex); + // Add the icon. + final int iconIndex = chooseIconIndex(isOngoing, viewIndex); + mNotificationIcons.addView(iconView, iconIndex); + return iconView; + } + + StatusBarNotification removeNotificationViews(IBinder key) { + NotificationData.Entry entry = mOngoing.remove(key); + if (entry == null) { + entry = mLatest.remove(key); + if (entry == null) { + Slog.w(TAG, "removeNotification for unknown key: " + key); + return null; + } + } + // Remove the expanded view. + ((ViewGroup)entry.row.getParent()).removeView(entry.row); + // Remove the icon. + ((ViewGroup)entry.icon.getParent()).removeView(entry.icon); + + return entry.notification; + } + + private void setAreThereNotifications() { + boolean ongoing = mOngoing.hasVisibleItems(); + boolean latest = mLatest.hasVisibleItems(); + + // (no ongoing notifications are clearable) + if (mLatest.hasClearableItems()) { + mClearButton.setVisibility(View.VISIBLE); + } else { + mClearButton.setVisibility(View.INVISIBLE); + } + + mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE); + mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE); + + if (ongoing || latest) { + mNoNotificationsTitle.setVisibility(View.GONE); + } else { + mNoNotificationsTitle.setVisibility(View.VISIBLE); + } + } + + + /** + * State is one or more of the DISABLE constants from StatusBarManager. + */ + public void disable(int state) { + final int old = mDisabled; + final int diff = state ^ old; + mDisabled = state; + + if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { + if ((state & StatusBarManager.DISABLE_EXPAND) != 0) { + Slog.d(TAG, "DISABLE_EXPAND: yes"); + animateCollapse(); + } + } + if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); + if (mTicking) { + mTicker.halt(); + } else { + setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); + } + } else { + Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); + if (!mExpandedVisible) { + setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); + } + } + } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { + if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { + Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes"); + mTicker.halt(); + } + } + } + + /** + * All changes to the status bar and notifications funnel through here and are batched. + */ + private class H extends Handler { + public void handleMessage(Message m) { + switch (m.what) { + case MSG_ANIMATE: + doAnimation(); + break; + case MSG_ANIMATE_REVEAL: + doRevealAnimation(); + break; + case MSG_SHOW_INTRUDER: + setIntruderAlertVisibility(true); + break; + case MSG_HIDE_INTRUDER: + setIntruderAlertVisibility(false); + break; + } + } + } + + View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() { + public void onFocusChange(View v, boolean hasFocus) { + // Because 'v' is a ViewGroup, all its children will be (un)selected + // too, which allows marqueeing to work. + v.setSelected(hasFocus); + } + }; + + private void makeExpandedVisible() { + if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible); + if (mExpandedVisible) { + return; + } + mExpandedVisible = true; + visibilityChanged(true); + + updateExpandedViewPos(EXPANDED_LEAVE_ALONE); + mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + mExpandedDialog.getWindow().setAttributes(mExpandedParams); + mExpandedView.requestFocus(View.FOCUS_FORWARD); + mTrackingView.setVisibility(View.VISIBLE); + + if (!mTicking) { + setDateViewVisibility(true, com.android.internal.R.anim.fade_in); + } + } + + public void animateExpand() { + if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded); + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { + return ; + } + if (mExpanded) { + return; + } + + prepareTracking(0, true); + performFling(0, 2000.0f, true); + } + + public void animateCollapse() { + if (SPEW) { + Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded + + " mExpandedVisible=" + mExpandedVisible + + " mExpanded=" + mExpanded + + " mAnimating=" + mAnimating + + " mAnimY=" + mAnimY + + " mAnimVel=" + mAnimVel); + } + + if (!mExpandedVisible) { + return; + } + + int y; + if (mAnimating) { + y = (int)mAnimY; + } else { + y = mDisplay.getHeight()-1; + } + // Let the fling think that we're open so it goes in the right direction + // and doesn't try to re-open the windowshade. + mExpanded = true; + prepareTracking(y, false); + performFling(y, -2000.0f, true); + } + + void performExpand() { + if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded); + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { + return ; + } + if (mExpanded) { + return; + } + + mExpanded = true; + makeExpandedVisible(); + updateExpandedViewPos(EXPANDED_FULL_OPEN); + + if (false) postStartTracing(); + } + + void performCollapse() { + if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded + + " mExpandedVisible=" + mExpandedVisible); + + if (!mExpandedVisible) { + return; + } + mExpandedVisible = false; + visibilityChanged(false); + mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; + mExpandedDialog.getWindow().setAttributes(mExpandedParams); + mTrackingView.setVisibility(View.GONE); + + if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) { + setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); + } + setDateViewVisibility(false, com.android.internal.R.anim.fade_out); + + if (!mExpanded) { + return; + } + mExpanded = false; + } + + void doAnimation() { + if (mAnimating) { + if (SPEW) Slog.d(TAG, "doAnimation"); + if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY); + incrementAnim(); + if (SPEW) Slog.d(TAG, "doAnimation after mAnimY=" + mAnimY); + if (mAnimY >= mDisplay.getHeight()-1) { + if (SPEW) Slog.d(TAG, "Animation completed to expanded state."); + mAnimating = false; + updateExpandedViewPos(EXPANDED_FULL_OPEN); + performExpand(); + } + else if (mAnimY < mStatusBarView.getHeight()) { + if (SPEW) Slog.d(TAG, "Animation completed to collapsed state."); + mAnimating = false; + updateExpandedViewPos(0); + performCollapse(); + } + else { + updateExpandedViewPos((int)mAnimY); + mCurAnimationTime += ANIM_FRAME_DURATION; + mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime); + } + } + } + + void stopTracking() { + mTracking = false; + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + + void incrementAnim() { + long now = SystemClock.uptimeMillis(); + float t = ((float)(now - mAnimLastTime)) / 1000; // ms -> s + final float y = mAnimY; + final float v = mAnimVel; // px/s + final float a = mAnimAccel; // px/s/s + mAnimY = y + (v*t) + (0.5f*a*t*t); // px + mAnimVel = v + (a*t); // px/s + mAnimLastTime = now; // ms + //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY + // + " mAnimAccel=" + mAnimAccel); + } + + void doRevealAnimation() { + final int h = mCloseView.getHeight() + mStatusBarView.getHeight(); + if (mAnimatingReveal && mAnimating && mAnimY < h) { + incrementAnim(); + if (mAnimY >= h) { + mAnimY = h; + updateExpandedViewPos((int)mAnimY); + } else { + updateExpandedViewPos((int)mAnimY); + mCurAnimationTime += ANIM_FRAME_DURATION; + mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL), + mCurAnimationTime); + } + } + } + + void prepareTracking(int y, boolean opening) { + mTracking = true; + mVelocityTracker = VelocityTracker.obtain(); + if (opening) { + mAnimAccel = 2000.0f; + mAnimVel = 200; + mAnimY = mStatusBarView.getHeight(); + updateExpandedViewPos((int)mAnimY); + mAnimating = true; + mAnimatingReveal = true; + mHandler.removeMessages(MSG_ANIMATE); + mHandler.removeMessages(MSG_ANIMATE_REVEAL); + long now = SystemClock.uptimeMillis(); + mAnimLastTime = now; + mCurAnimationTime = now + ANIM_FRAME_DURATION; + mAnimating = true; + mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL), + mCurAnimationTime); + makeExpandedVisible(); + } else { + // it's open, close it? + if (mAnimating) { + mAnimating = false; + mHandler.removeMessages(MSG_ANIMATE); + } + updateExpandedViewPos(y + mViewDelta); + } + } + + void performFling(int y, float vel, boolean always) { + mAnimatingReveal = false; + mDisplayHeight = mDisplay.getHeight(); + + mAnimY = y; + mAnimVel = vel; + + //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel); + + if (mExpanded) { + if (!always && ( + vel > 200.0f + || (y > (mDisplayHeight-25) && vel > -200.0f))) { + // We are expanded, but they didn't move sufficiently to cause + // us to retract. Animate back to the expanded position. + mAnimAccel = 2000.0f; + if (vel < 0) { + mAnimVel = 0; + } + } + else { + // We are expanded and are now going to animate away. + mAnimAccel = -2000.0f; + if (vel > 0) { + mAnimVel = 0; + } + } + } else { + if (always || ( + vel > 200.0f + || (y > (mDisplayHeight/2) && vel > -200.0f))) { + // We are collapsed, and they moved enough to allow us to + // expand. Animate in the notifications. + mAnimAccel = 2000.0f; + if (vel < 0) { + mAnimVel = 0; + } + } + else { + // We are collapsed, but they didn't move sufficiently to cause + // us to retract. Animate back to the collapsed position. + mAnimAccel = -2000.0f; + if (vel > 0) { + mAnimVel = 0; + } + } + } + //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel + // + " mAnimAccel=" + mAnimAccel); + + long now = SystemClock.uptimeMillis(); + mAnimLastTime = now; + mCurAnimationTime = now + ANIM_FRAME_DURATION; + mAnimating = true; + mHandler.removeMessages(MSG_ANIMATE); + mHandler.removeMessages(MSG_ANIMATE_REVEAL); + mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime); + stopTracking(); + } + + boolean interceptTouchEvent(MotionEvent event) { + if (SPEW) { + Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled=" + + mDisabled); + } + + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { + return false; + } + + final int statusBarSize = mStatusBarView.getHeight(); + final int hitSize = statusBarSize*2; + if (event.getAction() == MotionEvent.ACTION_DOWN) { + final int y = (int)event.getRawY(); + + if (!mExpanded) { + mViewDelta = statusBarSize - y; + } else { + mTrackingView.getLocationOnScreen(mAbsPos); + mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y; + } + if ((!mExpanded && y < hitSize) || + (mExpanded && y > (mDisplay.getHeight()-hitSize))) { + + // We drop events at the edge of the screen to make the windowshade come + // down by accident less, especially when pushing open a device with a keyboard + // that rotates (like g1 and droid) + int x = (int)event.getRawX(); + final int edgeBorder = mEdgeBorder; + if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder) { + prepareTracking(y, !mExpanded);// opening if we're not already fully visible + mVelocityTracker.addMovement(event); + } + } + } else if (mTracking) { + mVelocityTracker.addMovement(event); + final int minY = statusBarSize + mCloseView.getHeight(); + if (event.getAction() == MotionEvent.ACTION_MOVE) { + int y = (int)event.getRawY(); + if (mAnimatingReveal && y < minY) { + // nothing + } else { + mAnimatingReveal = false; + updateExpandedViewPos(y + mViewDelta); + } + } else if (event.getAction() == MotionEvent.ACTION_UP) { + mVelocityTracker.computeCurrentVelocity(1000); + + float yVel = mVelocityTracker.getYVelocity(); + boolean negative = yVel < 0; + + float xVel = mVelocityTracker.getXVelocity(); + if (xVel < 0) { + xVel = -xVel; + } + if (xVel > 150.0f) { + xVel = 150.0f; // limit how much we care about the x axis + } + + float vel = (float)Math.hypot(yVel, xVel); + if (negative) { + vel = -vel; + } + + performFling((int)event.getRawY(), vel, false); + } + + } + return false; + } + + public void setLightsOn(boolean on) { + if (!on) { + // All we do for "lights out" mode on a phone is hide the status bar, + // which the window manager does. But we do need to hide the windowshade + // on our own. + animateCollapse(); + } + } + + private class Launcher implements View.OnClickListener { + private PendingIntent mIntent; + private String mPkg; + private String mTag; + private int mId; + + Launcher(PendingIntent intent, String pkg, String tag, int id) { + mIntent = intent; + mPkg = pkg; + mTag = tag; + mId = id; + } + + public void onClick(View v) { + try { + // The intent we are sending is for the application, which + // won't have permission to immediately start an activity after + // the user switches to home. We know it is safe to do at this + // point, so make sure new activity switches are now allowed. + ActivityManagerNative.getDefault().resumeAppSwitches(); + } catch (RemoteException e) { + } + + if (mIntent != null) { + int[] pos = new int[2]; + v.getLocationOnScreen(pos); + Intent overlay = new Intent(); + overlay.setSourceBounds( + new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight())); + try { + mIntent.send(PhoneStatusBarService.this, 0, overlay); + } catch (PendingIntent.CanceledException e) { + // the stack trace isn't very helpful here. Just log the exception message. + Slog.w(TAG, "Sending contentIntent failed: " + e); + } + } + + try { + mBarService.onNotificationClick(mPkg, mTag, mId); + } catch (RemoteException ex) { + // system process is dead if we're here. + } + + // close the shade if it was open + animateCollapse(); + + // If this click was on the intruder alert, hide that instead + mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER); + } + } + + private void tick(StatusBarNotification n) { + // Show the ticker if one is requested. Also don't do this + // until status bar window is attached to the window manager, + // because... well, what's the point otherwise? And trying to + // run a ticker without being attached will crash! + if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) { + if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS + | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) { + mTicker.addEntry(n); + } + } + } + + /** + * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService + * about the failure. + * + * WARNING: this will call back into us. Don't hold any locks. + */ + void handleNotificationError(IBinder key, StatusBarNotification n, String message) { + removeNotification(key); + try { + mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message); + } catch (RemoteException ex) { + // The end is nigh. + } + } + + private class MyTicker extends Ticker { + MyTicker(Context context, View sb) { + super(context, sb); + } + + @Override + public void tickerStarting() { + mTicking = true; + mIcons.setVisibility(View.GONE); + mTickerView.setVisibility(View.VISIBLE); + mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null)); + mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null)); + if (mExpandedVisible) { + setDateViewVisibility(false, com.android.internal.R.anim.push_up_out); + } + } + + @Override + public void tickerDone() { + mIcons.setVisibility(View.VISIBLE); + mTickerView.setVisibility(View.GONE); + mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null)); + mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out, + mTickingDoneListener)); + if (mExpandedVisible) { + setDateViewVisibility(true, com.android.internal.R.anim.push_down_in); + } + } + + public void tickerHalting() { + mIcons.setVisibility(View.VISIBLE); + mTickerView.setVisibility(View.GONE); + mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null)); + mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out, + mTickingDoneListener)); + if (mExpandedVisible) { + setDateViewVisibility(true, com.android.internal.R.anim.fade_in); + } + } + } + + Animation.AnimationListener mTickingDoneListener = new Animation.AnimationListener() {; + public void onAnimationEnd(Animation animation) { + mTicking = false; + } + public void onAnimationRepeat(Animation animation) { + } + public void onAnimationStart(Animation animation) { + } + }; + + private Animation loadAnim(int id, Animation.AnimationListener listener) { + Animation anim = AnimationUtils.loadAnimation(PhoneStatusBarService.this, id); + if (listener != null) { + anim.setAnimationListener(listener); + } + return anim; + } + + public String viewInfo(View v) { + return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom() + + " " + v.getWidth() + "x" + v.getHeight() + ")"; + } + + protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { + if (checkCallingOrSelfPermission(android.Manifest.permission.DUMP) + != PackageManager.PERMISSION_GRANTED) { + pw.println("Permission Denial: can't dump StatusBar from from pid=" + + Binder.getCallingPid() + + ", uid=" + Binder.getCallingUid()); + return; + } + + synchronized (mQueueLock) { + pw.println("Current Status Bar state:"); + pw.println(" mExpanded=" + mExpanded + + ", mExpandedVisible=" + mExpandedVisible); + pw.println(" mTicking=" + mTicking); + pw.println(" mTracking=" + mTracking); + pw.println(" mAnimating=" + mAnimating + + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel + + ", mAnimAccel=" + mAnimAccel); + pw.println(" mCurAnimationTime=" + mCurAnimationTime + + " mAnimLastTime=" + mAnimLastTime); + pw.println(" mDisplayHeight=" + mDisplayHeight + + " mAnimatingReveal=" + mAnimatingReveal + + " mViewDelta=" + mViewDelta); + pw.println(" mDisplayHeight=" + mDisplayHeight); + pw.println(" mExpandedParams: " + mExpandedParams); + pw.println(" mExpandedView: " + viewInfo(mExpandedView)); + pw.println(" mExpandedDialog: " + mExpandedDialog); + pw.println(" mTrackingParams: " + mTrackingParams); + pw.println(" mTrackingView: " + viewInfo(mTrackingView)); + pw.println(" mOngoingTitle: " + viewInfo(mOngoingTitle)); + pw.println(" mOngoingItems: " + viewInfo(mOngoingItems)); + pw.println(" mLatestTitle: " + viewInfo(mLatestTitle)); + pw.println(" mLatestItems: " + viewInfo(mLatestItems)); + pw.println(" mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle)); + pw.println(" mCloseView: " + viewInfo(mCloseView)); + pw.println(" mTickerView: " + viewInfo(mTickerView)); + pw.println(" mScrollView: " + viewInfo(mScrollView) + + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY()); + pw.println("mNotificationLinearLayout: " + viewInfo(mNotificationLinearLayout)); + } + /* + synchronized (mNotificationData) { + int N = mNotificationData.ongoingCount(); + pw.println(" ongoingCount.size=" + N); + for (int i=0; i<N; i++) { + StatusBarNotification n = mNotificationData.getOngoing(i); + pw.println(" [" + i + "] key=" + n.key + " view=" + n.view); + pw.println(" data=" + n.data); + } + N = mNotificationData.latestCount(); + pw.println(" ongoingCount.size=" + N); + for (int i=0; i<N; i++) { + StatusBarNotification n = mNotificationData.getLatest(i); + pw.println(" [" + i + "] key=" + n.key + " view=" + n.view); + pw.println(" data=" + n.data); + } + } + */ + + if (false) { + pw.println("see the logcat for a dump of the views we have created."); + // must happen on ui thread + mHandler.post(new Runnable() { + public void run() { + mStatusBarView.getLocationOnScreen(mAbsPos); + Slog.d(TAG, "mStatusBarView: ----- (" + mAbsPos[0] + "," + mAbsPos[1] + + ") " + mStatusBarView.getWidth() + "x" + + mStatusBarView.getHeight()); + mStatusBarView.debug(); + + mExpandedView.getLocationOnScreen(mAbsPos); + Slog.d(TAG, "mExpandedView: ----- (" + mAbsPos[0] + "," + mAbsPos[1] + + ") " + mExpandedView.getWidth() + "x" + + mExpandedView.getHeight()); + mExpandedView.debug(); + + mTrackingView.getLocationOnScreen(mAbsPos); + Slog.d(TAG, "mTrackingView: ----- (" + mAbsPos[0] + "," + mAbsPos[1] + + ") " + mTrackingView.getWidth() + "x" + + mTrackingView.getHeight()); + mTrackingView.debug(); + } + }); + } + } + + void onBarViewAttached() { + WindowManager.LayoutParams lp; + int pixelFormat; + Drawable bg; + + /// ---------- Tracking View -------------- + pixelFormat = PixelFormat.RGBX_8888; + bg = mTrackingView.getBackground(); + if (bg != null) { + pixelFormat = bg.getOpacity(); + } + + lp = new WindowManager.LayoutParams( + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT, + WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, + WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, + pixelFormat); +// lp.token = mStatusBarView.getWindowToken(); + lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; + lp.setTitle("TrackingView"); + lp.y = mTrackingPosition; + mTrackingParams = lp; + + WindowManagerImpl.getDefault().addView(mTrackingView, lp); + } + + void onTrackingViewAttached() { + WindowManager.LayoutParams lp; + int pixelFormat; + Drawable bg; + + /// ---------- Expanded View -------------- + pixelFormat = PixelFormat.TRANSLUCENT; + + final int disph = mDisplay.getHeight(); + lp = mExpandedDialog.getWindow().getAttributes(); + lp.width = ViewGroup.LayoutParams.MATCH_PARENT; + lp.height = getExpandedHeight(); + lp.x = 0; + mTrackingPosition = lp.y = -disph; // sufficiently large negative + lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL; + lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN + | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS + | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL + | WindowManager.LayoutParams.FLAG_DITHER + | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; + lp.format = pixelFormat; + lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; + lp.setTitle("StatusBarExpanded"); + mExpandedDialog.getWindow().setAttributes(lp); + mExpandedDialog.getWindow().setFormat(pixelFormat); + mExpandedParams = lp; + + mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE); + mExpandedDialog.setContentView(mExpandedView, + new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT)); + mExpandedDialog.getWindow().setBackgroundDrawable(null); + mExpandedDialog.show(); + FrameLayout hack = (FrameLayout)mExpandedView.getParent(); + } + + void setDateViewVisibility(boolean visible, int anim) { + mDateView.setUpdates(visible); + mDateView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); + mDateView.startAnimation(loadAnim(anim, null)); + } + + void setNotificationIconVisibility(boolean visible, int anim) { + int old = mNotificationIcons.getVisibility(); + int v = visible ? View.VISIBLE : View.INVISIBLE; + if (old != v) { + mNotificationIcons.setVisibility(v); + mNotificationIcons.startAnimation(loadAnim(anim, null)); + } + } + + void updateExpandedViewPos(int expandedPosition) { + if (SPEW) { + Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition + + " mTrackingParams.y=" + mTrackingParams.y + + " mTrackingPosition=" + mTrackingPosition); + } + + int h = mStatusBarView.getHeight(); + int disph = mDisplay.getHeight(); + + // If the expanded view is not visible, make sure they're still off screen. + // Maybe the view was resized. + if (!mExpandedVisible) { + if (mTrackingView != null) { + mTrackingPosition = -disph; + if (mTrackingParams != null) { + mTrackingParams.y = mTrackingPosition; + WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams); + } + } + if (mExpandedParams != null) { + mExpandedParams.y = -disph; + mExpandedDialog.getWindow().setAttributes(mExpandedParams); + } + return; + } + + // tracking view... + int pos; + if (expandedPosition == EXPANDED_FULL_OPEN) { + pos = h; + } + else if (expandedPosition == EXPANDED_LEAVE_ALONE) { + pos = mTrackingPosition; + } + else { + if (expandedPosition <= disph) { + pos = expandedPosition; + } else { + pos = disph; + } + pos -= disph-h; + } + mTrackingPosition = mTrackingParams.y = pos; + mTrackingParams.height = disph-h; + WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams); + + if (mExpandedParams != null) { + mCloseView.getLocationInWindow(mPositionTmp); + final int closePos = mPositionTmp[1]; + + mExpandedContents.getLocationInWindow(mPositionTmp); + final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight(); + + mExpandedParams.y = pos + mTrackingView.getHeight() + - (mTrackingParams.height-closePos) - contentsBottom; + int max = h; + if (mExpandedParams.y > max) { + mExpandedParams.y = max; + } + int min = mTrackingPosition; + if (mExpandedParams.y < min) { + mExpandedParams.y = min; + } + + boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h; + if (!visible) { + // if the contents aren't visible, move the expanded view way off screen + // because the window itself extends below the content view. + mExpandedParams.y = -disph; + } + mExpandedDialog.getWindow().setAttributes(mExpandedParams); + + // As long as this isn't just a repositioning that's not supposed to affect + // the user's perception of what's showing, call to say that the visibility + // has changed. (Otherwise, someone else will call to do that). + if (expandedPosition != EXPANDED_LEAVE_ALONE) { + if (SPEW) Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")"); + visibilityChanged(visible); + } + } + + if (SPEW) { + Slog.d(TAG, "updateExpandedViewPos after expandedPosition=" + expandedPosition + + " mTrackingParams.y=" + mTrackingParams.y + + " mTrackingPosition=" + mTrackingPosition + + " mExpandedParams.y=" + mExpandedParams.y + + " mExpandedParams.height=" + mExpandedParams.height); + } + } + + int getExpandedHeight() { + return mDisplay.getHeight() - mStatusBarView.getHeight() - mCloseView.getHeight(); + } + + void updateExpandedHeight() { + if (mExpandedView != null) { + mExpandedParams.height = getExpandedHeight(); + mExpandedDialog.getWindow().setAttributes(mExpandedParams); + } + } + + /** + * The LEDs are turned o)ff when the notification panel is shown, even just a little bit. + * This was added last-minute and is inconsistent with the way the rest of the notifications + * are handled, because the notification isn't really cancelled. The lights are just + * turned off. If any other notifications happen, the lights will turn back on. Steve says + * this is what he wants. (see bug 1131461) + */ + void visibilityChanged(boolean visible) { + if (mPanelSlightlyVisible != visible) { + mPanelSlightlyVisible = visible; + try { + mBarService.onPanelRevealed(); + } catch (RemoteException ex) { + // Won't fail unless the world has ended. + } + } + } + + void performDisableActions(int net) { + int old = mDisabled; + int diff = net ^ old; + mDisabled = net; + + // act accordingly + if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { + if ((net & StatusBarManager.DISABLE_EXPAND) != 0) { + Slog.d(TAG, "DISABLE_EXPAND: yes"); + animateCollapse(); + } + } + if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); + if (mTicking) { + mNotificationIcons.setVisibility(View.INVISIBLE); + mTicker.halt(); + } else { + setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); + } + } else { + Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); + if (!mExpandedVisible) { + setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); + } + } + } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { + if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { + mTicker.halt(); + } + } + } + + private View.OnClickListener mClearButtonListener = new View.OnClickListener() { + public void onClick(View v) { + try { + mBarService.onClearAllNotifications(); + } catch (RemoteException ex) { + // system process is dead if we're here. + } + animateCollapse(); + } + }; + + private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { + public void onReceive(Context context, Intent intent) { + String action = intent.getAction(); + if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) + || Intent.ACTION_SCREEN_OFF.equals(action)) { + animateCollapse(); + } + else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { + updateResources(); + } + } + }; + + private void setIntruderAlertVisibility(boolean vis) { + mIntruderAlertView.setVisibility(vis ? View.VISIBLE : View.GONE); + } + + /** + * Reload some of our resources when the configuration changes. + * + * We don't reload everything when the configuration changes -- we probably + * should, but getting that smooth is tough. Someday we'll fix that. In the + * meantime, just update the things that we know change. + */ + void updateResources() { + Resources res = getResources(); + + mClearButton.setText(getText(R.string.status_bar_clear_all_button)); + mOngoingTitle.setText(getText(R.string.status_bar_ongoing_events_title)); + mLatestTitle.setText(getText(R.string.status_bar_latest_events_title)); + mNoNotificationsTitle.setText(getText(R.string.status_bar_no_notifications_title)); + + mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore); + + if (false) Slog.v(TAG, "updateResources"); + } + + // + // tracing + // + + void postStartTracing() { + mHandler.postDelayed(mStartTracing, 3000); + } + + void vibrate() { + android.os.Vibrator vib = (android.os.Vibrator)getSystemService(Context.VIBRATOR_SERVICE); + vib.vibrate(250); + } + + Runnable mStartTracing = new Runnable() { + public void run() { + vibrate(); + SystemClock.sleep(250); + Slog.d(TAG, "startTracing"); + android.os.Debug.startMethodTracing("/data/statusbar-traces/trace"); + mHandler.postDelayed(mStopTracing, 10000); + } + }; + + Runnable mStopTracing = new Runnable() { + public void run() { + android.os.Debug.stopMethodTracing(); + Slog.d(TAG, "stopTracing"); + vibrate(); + } + }; +} + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java index 0309430..e0019b5 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarPolicy.java @@ -18,9 +18,8 @@ package com.android.systemui.statusbar.policy; import android.app.StatusBarManager; import android.app.AlertDialog; -import android.bluetooth.BluetoothA2dp; import android.bluetooth.BluetoothAdapter; -import android.bluetooth.BluetoothHeadset; +import android.bluetooth.BluetoothProfile; import android.bluetooth.BluetoothPbap; import android.content.BroadcastReceiver; import android.content.ContentResolver; @@ -319,9 +318,6 @@ public class StatusBarPolicy { private boolean mVolumeVisible; // bluetooth device status - private int mBluetoothHeadsetState; - private boolean mBluetoothA2dpConnected; - private int mBluetoothPbapState; private boolean mBluetoothEnabled; // wifi @@ -369,9 +365,7 @@ public class StatusBarPolicy { onBatteryOkay(intent); } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED) || - action.equals(BluetoothHeadset.ACTION_STATE_CHANGED) || - action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED) || - action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) { + action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { updateBluetooth(intent); } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION) || @@ -454,9 +448,6 @@ public class StatusBarPolicy { } else { mBluetoothEnabled = false; } - mBluetoothA2dpConnected = false; - mBluetoothHeadsetState = BluetoothHeadset.STATE_DISCONNECTED; - mBluetoothPbapState = BluetoothPbap.STATE_DISCONNECTED; mService.setIconVisibility("bluetooth", mBluetoothEnabled); // Gps status @@ -490,9 +481,7 @@ public class StatusBarPolicy { filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); filter.addAction(AudioManager.VIBRATE_SETTING_CHANGED_ACTION); filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); - filter.addAction(BluetoothHeadset.ACTION_STATE_CHANGED); - filter.addAction(BluetoothA2dp.ACTION_SINK_STATE_CHANGED); - filter.addAction(BluetoothPbap.PBAP_STATE_CHANGED_ACTION); + filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION); filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); @@ -1064,28 +1053,16 @@ public class StatusBarPolicy { if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); mBluetoothEnabled = state == BluetoothAdapter.STATE_ON; - } else if (action.equals(BluetoothHeadset.ACTION_STATE_CHANGED)) { - mBluetoothHeadsetState = intent.getIntExtra(BluetoothHeadset.EXTRA_STATE, - BluetoothHeadset.STATE_ERROR); - } else if (action.equals(BluetoothA2dp.ACTION_SINK_STATE_CHANGED)) { - BluetoothA2dp a2dp = new BluetoothA2dp(mContext); - if (a2dp.getConnectedSinks().size() != 0) { - mBluetoothA2dpConnected = true; - } else { - mBluetoothA2dpConnected = false; + } else if (action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED)) { + int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, + BluetoothAdapter.STATE_DISCONNECTED); + if (state == BluetoothAdapter.STATE_CONNECTED) { + iconId = R.drawable.stat_sys_data_bluetooth_connected; } - } else if (action.equals(BluetoothPbap.PBAP_STATE_CHANGED_ACTION)) { - mBluetoothPbapState = intent.getIntExtra(BluetoothPbap.PBAP_STATE, - BluetoothPbap.STATE_DISCONNECTED); } else { return; } - if (mBluetoothHeadsetState == BluetoothHeadset.STATE_CONNECTED || mBluetoothA2dpConnected || - mBluetoothPbapState == BluetoothPbap.STATE_CONNECTED) { - iconId = R.drawable.stat_sys_data_bluetooth_connected; - } - mService.setIcon("bluetooth", iconId, 0); mService.setIconVisibility("bluetooth", mBluetoothEnabled); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java index f3da2a3..695fdba 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarService.java @@ -17,185 +17,53 @@ package com.android.systemui.statusbar; import android.app.Service; -import com.android.internal.statusbar.IStatusBar; -import com.android.internal.statusbar.IStatusBarService; -import com.android.internal.statusbar.StatusBarIcon; -import com.android.internal.statusbar.StatusBarIconList; -import com.android.internal.statusbar.StatusBarNotification; - -import android.app.ActivityManagerNative; -import android.app.Dialog; -import android.app.Notification; -import android.app.PendingIntent; -import android.app.Service; -import android.app.StatusBarManager; -import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; -import android.content.IntentFilter; -import android.content.pm.PackageManager; import android.content.res.Resources; import android.graphics.PixelFormat; -import android.graphics.Rect; -import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.IBinder; import android.os.RemoteException; -import android.os.Binder; -import android.os.Handler; -import android.os.Message; import android.os.ServiceManager; -import android.os.SystemClock; -import android.text.TextUtils; import android.util.Slog; import android.util.Log; -import android.view.Display; import android.view.Gravity; -import android.view.KeyEvent; -import android.view.LayoutInflater; -import android.view.MotionEvent; -import android.view.VelocityTracker; import android.view.View; import android.view.ViewGroup; -import android.view.Window; import android.view.WindowManager; import android.view.WindowManagerImpl; -import android.view.animation.Animation; -import android.view.animation.AnimationUtils; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.RemoteViews; -import android.widget.ScrollView; -import android.widget.TextView; -import android.widget.FrameLayout; -import java.io.FileDescriptor; -import java.io.PrintWriter; import java.util.ArrayList; -import java.util.HashMap; -import java.util.Set; - -import com.android.systemui.R; -import com.android.systemui.statusbar.policy.StatusBarPolicy; +import com.android.internal.statusbar.IStatusBar; +import com.android.internal.statusbar.IStatusBarService; +import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarIconList; +import com.android.internal.statusbar.StatusBarNotification; +import com.android.systemui.R; -public class StatusBarService extends Service implements CommandQueue.Callbacks { +public abstract class StatusBarService extends Service implements CommandQueue.Callbacks { static final String TAG = "StatusBarService"; - static final boolean SPEW_ICONS = false; - static final boolean SPEW = false; - - public static final String ACTION_STATUSBAR_START - = "com.android.internal.policy.statusbar.START"; - - static final int EXPANDED_LEAVE_ALONE = -10000; - static final int EXPANDED_FULL_OPEN = -10001; - - private static final int MSG_ANIMATE = 1000; - private static final int MSG_ANIMATE_REVEAL = 1001; - - StatusBarPolicy mIconPolicy; - - CommandQueue mCommandQueue; - IStatusBarService mBarService; - - int mIconSize; - Display mDisplay; - StatusBarView mStatusBarView; - int mPixelFormat; - H mHandler = new H(); - Object mQueueLock = new Object(); - - // icons - LinearLayout mIcons; - IconMerger mNotificationIcons; - LinearLayout mStatusIcons; - - // expanded notifications - Dialog mExpandedDialog; - ExpandedView mExpandedView; - WindowManager.LayoutParams mExpandedParams; - ScrollView mScrollView; - View mNotificationLinearLayout; - View mExpandedContents; - // top bar - TextView mNoNotificationsTitle; - TextView mClearButton; - // drag bar - CloseDragHandle mCloseView; - // ongoing - NotificationData mOngoing = new NotificationData(); - TextView mOngoingTitle; - LinearLayout mOngoingItems; - // latest - NotificationData mLatest = new NotificationData(); - TextView mLatestTitle; - LinearLayout mLatestItems; - // position - int[] mPositionTmp = new int[2]; - boolean mExpanded; - boolean mExpandedVisible; - - // the date view - DateView mDateView; - // the tracker view - TrackingView mTrackingView; - WindowManager.LayoutParams mTrackingParams; - int mTrackingPosition; // the position of the top of the tracking view. - private boolean mPanelSlightlyVisible; + protected CommandQueue mCommandQueue; + protected IStatusBarService mBarService; - // ticker - private Ticker mTicker; - private View mTickerView; - private boolean mTicking; + // Up-call methods + protected abstract View makeStatusBarView(); + protected abstract int getStatusBarGravity(); - // Tracking finger for opening/closing. - int mEdgeBorder; // corresponds to R.dimen.status_bar_edge_ignore - boolean mTracking; - VelocityTracker mVelocityTracker; - - static final int ANIM_FRAME_DURATION = (1000/60); - - boolean mAnimating; - long mCurAnimationTime; - float mDisplayHeight; - float mAnimY; - float mAnimVel; - float mAnimAccel; - long mAnimLastTime; - boolean mAnimatingReveal = false; - int mViewDelta; - int[] mAbsPos = new int[2]; - - // for disabling the status bar - int mDisabled = 0; - - private class ExpandedDialog extends Dialog { - ExpandedDialog(Context context) { - super(context, com.android.internal.R.style.Theme_Light_NoTitleBar); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - boolean down = event.getAction() == KeyEvent.ACTION_DOWN; - switch (event.getKeyCode()) { - case KeyEvent.KEYCODE_BACK: - if (!down) { - animateCollapse(); - } - return true; - } - return super.dispatchKeyEvent(event); - } + /** + * Nobody binds to us. + */ + @Override + public IBinder onBind(Intent intent) { + return null; } - @Override public void onCreate() { // First set up our views and stuff. - mDisplay = ((WindowManager)getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); - makeStatusBarView(this); + View sb = makeStatusBarView(); // Connect in to the status bar manager service StatusBarIconList iconList = new StatusBarIconList(); @@ -204,12 +72,16 @@ public class StatusBarService extends Service implements CommandQueue.Callbacks mCommandQueue = new CommandQueue(this, iconList); mBarService = IStatusBarService.Stub.asInterface( ServiceManager.getService(Context.STATUS_BAR_SERVICE)); + boolean[] lightsOn = new boolean[1]; try { - mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications); + mBarService.registerStatusBar(mCommandQueue, iconList, notificationKeys, notifications, + lightsOn); } catch (RemoteException ex) { // If the system process isn't there we're doomed anyway. } + setLightsOn(lightsOn[0]); + // Set up the initial icon state int N = iconList.size(); int viewIndex = 0; @@ -233,1271 +105,22 @@ public class StatusBarService extends Service implements CommandQueue.Callbacks } // Put up the view - addStatusBarView(); - - // Lastly, call to the icon policy to install/update all the icons. - mIconPolicy = new StatusBarPolicy(this); - } - - @Override - public void onDestroy() { - // we're never destroyed - } - - /** - * Nobody binds to us. - */ - @Override - public IBinder onBind(Intent intent) { - return null; - } - - // ================================================================================ - // Constructing the view - // ================================================================================ - private void makeStatusBarView(Context context) { - Resources res = context.getResources(); - - mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size); - - ExpandedView expanded = (ExpandedView)View.inflate(context, - R.layout.status_bar_expanded, null); - expanded.mService = this; - - StatusBarView sb = (StatusBarView)View.inflate(context, R.layout.status_bar, null); - sb.mService = this; - - // figure out which pixel-format to use for the status bar. - mPixelFormat = PixelFormat.TRANSLUCENT; - Drawable bg = sb.getBackground(); - if (bg != null) { - mPixelFormat = bg.getOpacity(); - } - - mStatusBarView = sb; - mStatusIcons = (LinearLayout)sb.findViewById(R.id.statusIcons); - mNotificationIcons = (IconMerger)sb.findViewById(R.id.notificationIcons); - mIcons = (LinearLayout)sb.findViewById(R.id.icons); - mTickerView = sb.findViewById(R.id.ticker); - mDateView = (DateView)sb.findViewById(R.id.date); - - mExpandedDialog = new ExpandedDialog(context); - mExpandedView = expanded; - mExpandedContents = expanded.findViewById(R.id.notificationLinearLayout); - mOngoingTitle = (TextView)expanded.findViewById(R.id.ongoingTitle); - mOngoingItems = (LinearLayout)expanded.findViewById(R.id.ongoingItems); - mLatestTitle = (TextView)expanded.findViewById(R.id.latestTitle); - mLatestItems = (LinearLayout)expanded.findViewById(R.id.latestItems); - mNoNotificationsTitle = (TextView)expanded.findViewById(R.id.noNotificationsTitle); - mClearButton = (TextView)expanded.findViewById(R.id.clear_all_button); - mClearButton.setOnClickListener(mClearButtonListener); - mScrollView = (ScrollView)expanded.findViewById(R.id.scroll); - mNotificationLinearLayout = expanded.findViewById(R.id.notificationLinearLayout); - - mOngoingTitle.setVisibility(View.GONE); - mLatestTitle.setVisibility(View.GONE); - - mTicker = new MyTicker(context, sb); - - TickerView tickerView = (TickerView)sb.findViewById(R.id.tickerText); - tickerView.mTicker = mTicker; - - mTrackingView = (TrackingView)View.inflate(context, R.layout.status_bar_tracking, null); - mTrackingView.mService = this; - mCloseView = (CloseDragHandle)mTrackingView.findViewById(R.id.close); - mCloseView.mService = this; - - mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore); - - // set the inital view visibility - setAreThereNotifications(); - mDateView.setVisibility(View.INVISIBLE); - - // receive broadcasts - IntentFilter filter = new IntentFilter(); - filter.addAction(Intent.ACTION_CONFIGURATION_CHANGED); - filter.addAction(Intent.ACTION_CLOSE_SYSTEM_DIALOGS); - filter.addAction(Intent.ACTION_SCREEN_OFF); - context.registerReceiver(mBroadcastReceiver, filter); - } - - protected void addStatusBarView() { - Resources res = getResources(); + final Resources res = getResources(); final int height= res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_height); - final StatusBarView view = mStatusBarView; - WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + final WindowManager.LayoutParams lp = new WindowManager.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, height, WindowManager.LayoutParams.TYPE_STATUS_BAR, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_TOUCHABLE_WHEN_WAKING, PixelFormat.RGBX_8888); - lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; + lp.gravity = getStatusBarGravity(); lp.setTitle("StatusBar"); // TODO lp.windowAnimations = R.style.Animation_StatusBar; + WindowManagerImpl.getDefault().addView(sb, lp); - WindowManagerImpl.getDefault().addView(view, lp); - } - - public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) { - if (SPEW_ICONS) { - Slog.d(TAG, "addIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex - + " icon=" + icon); - } - StatusBarIconView view = new StatusBarIconView(this, slot); - view.set(icon); - mStatusIcons.addView(view, viewIndex, new LinearLayout.LayoutParams(mIconSize, mIconSize)); - } - - public void updateIcon(String slot, int index, int viewIndex, - StatusBarIcon old, StatusBarIcon icon) { - if (SPEW_ICONS) { - Slog.d(TAG, "updateIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex - + " old=" + old + " icon=" + icon); - } - StatusBarIconView view = (StatusBarIconView)mStatusIcons.getChildAt(viewIndex); - view.set(icon); - } - - public void removeIcon(String slot, int index, int viewIndex) { - if (SPEW_ICONS) { - Slog.d(TAG, "removeIcon slot=" + slot + " index=" + index + " viewIndex=" + viewIndex); - } - mStatusIcons.removeViewAt(viewIndex); - } - - public void addNotification(IBinder key, StatusBarNotification notification) { - boolean shouldTick = true; - if (notification.notification.fullScreenIntent != null) { - shouldTick = false; - Slog.d(TAG, "Notification has fullScreenIntent; sending fullScreenIntent"); - try { - notification.notification.fullScreenIntent.send(); - } catch (PendingIntent.CanceledException e) { - } - } - - StatusBarIconView iconView = addNotificationViews(key, notification); - if (iconView == null) return; - - if (shouldTick) { - tick(notification); - } - - // Recalculate the position of the sliding windows and the titles. - setAreThereNotifications(); - updateExpandedViewPos(EXPANDED_LEAVE_ALONE); - } - - public void updateNotification(IBinder key, StatusBarNotification notification) { - Slog.d(TAG, "updateNotification key=" + key + " notification=" + notification); - - NotificationData oldList; - int oldIndex = mOngoing.findEntry(key); - if (oldIndex >= 0) { - oldList = mOngoing; - } else { - oldIndex = mLatest.findEntry(key); - if (oldIndex < 0) { - Slog.w(TAG, "updateNotification for unknown key: " + key); - return; - } - oldList = mLatest; - } - final NotificationData.Entry oldEntry = oldList.getEntryAt(oldIndex); - final StatusBarNotification oldNotification = oldEntry.notification; - final RemoteViews oldContentView = oldNotification.notification.contentView; - - final RemoteViews contentView = notification.notification.contentView; - - if (false) { - Slog.d(TAG, "old notification: when=" + oldNotification.notification.when - + " ongoing=" + oldNotification.isOngoing() - + " expanded=" + oldEntry.expanded - + " contentView=" + oldContentView); - Slog.d(TAG, "new notification: when=" + notification.notification.when - + " ongoing=" + oldNotification.isOngoing() - + " contentView=" + contentView); - } - - // Can we just reapply the RemoteViews in place? If when didn't change, the order - // didn't change. - if (notification.notification.when == oldNotification.notification.when - && notification.isOngoing() == oldNotification.isOngoing() - && oldEntry.expanded != null - && contentView != null && oldContentView != null - && contentView.getPackage() != null - && oldContentView.getPackage() != null - && oldContentView.getPackage().equals(contentView.getPackage()) - && oldContentView.getLayoutId() == contentView.getLayoutId()) { - if (SPEW) Slog.d(TAG, "reusing notification"); - oldEntry.notification = notification; - try { - // Reapply the RemoteViews - contentView.reapply(this, oldEntry.content); - // update the contentIntent - final PendingIntent contentIntent = notification.notification.contentIntent; - if (contentIntent != null) { - oldEntry.content.setOnClickListener(new Launcher(contentIntent, - notification.pkg, notification.tag, notification.id)); - } - // Update the icon. - final StatusBarIcon ic = new StatusBarIcon(notification.pkg, - notification.notification.icon, notification.notification.iconLevel, - notification.notification.number); - if (!oldEntry.icon.set(ic)) { - handleNotificationError(key, notification, "Couldn't update icon: " + ic); - return; - } - } - catch (RuntimeException e) { - // It failed to add cleanly. Log, and remove the view from the panel. - Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); - removeNotificationViews(key); - addNotificationViews(key, notification); - } - } else { - if (SPEW) Slog.d(TAG, "not reusing notification"); - removeNotificationViews(key); - addNotificationViews(key, notification); - } - - // Restart the ticker if it's still running - if (notification.notification.tickerText != null - && !TextUtils.equals(notification.notification.tickerText, - oldEntry.notification.notification.tickerText)) { - tick(notification); - } - - // Recalculate the position of the sliding windows and the titles. - setAreThereNotifications(); - updateExpandedViewPos(EXPANDED_LEAVE_ALONE); - } - - public void removeNotification(IBinder key) { - if (SPEW) Slog.d(TAG, "removeNotification key=" + key); - StatusBarNotification old = removeNotificationViews(key); - - if (old != null) { - // Cancel the ticker if it's still running - mTicker.removeEntry(old); - - // Recalculate the position of the sliding windows and the titles. - setAreThereNotifications(); - updateExpandedViewPos(EXPANDED_LEAVE_ALONE); - } - } - - private int chooseIconIndex(boolean isOngoing, int viewIndex) { - final int latestSize = mLatest.size(); - if (isOngoing) { - return latestSize + (mOngoing.size() - viewIndex); - } else { - return latestSize - viewIndex; - } - } - - View[] makeNotificationView(StatusBarNotification notification, ViewGroup parent) { - Notification n = notification.notification; - RemoteViews remoteViews = n.contentView; - if (remoteViews == null) { - return null; - } - - // create the row view - LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); - View row = inflater.inflate(R.layout.status_bar_latest_event, parent, false); - - // bind the click event to the content area - ViewGroup content = (ViewGroup)row.findViewById(R.id.content); - content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); - content.setOnFocusChangeListener(mFocusChangeListener); - PendingIntent contentIntent = n.contentIntent; - if (contentIntent != null) { - content.setOnClickListener(new Launcher(contentIntent, notification.pkg, - notification.tag, notification.id)); - } - - View expanded = null; - Exception exception = null; - try { - expanded = remoteViews.apply(this, content); - } - catch (RuntimeException e) { - exception = e; - } - if (expanded == null) { - String ident = notification.pkg + "/0x" + Integer.toHexString(notification.id); - Slog.e(TAG, "couldn't inflate view for notification " + ident, exception); - return null; - } else { - content.addView(expanded); - row.setDrawingCacheEnabled(true); - } - - return new View[] { row, content, expanded }; - } - - StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) { - NotificationData list; - ViewGroup parent; - final boolean isOngoing = notification.isOngoing(); - if (isOngoing) { - list = mOngoing; - parent = mOngoingItems; - } else { - list = mLatest; - parent = mLatestItems; - } - // Construct the expanded view. - final View[] views = makeNotificationView(notification, parent); - if (views == null) { - handleNotificationError(key, notification, "Couldn't expand RemoteViews for: " - + notification); - return null; - } - final View row = views[0]; - final View content = views[1]; - final View expanded = views[2]; - // Construct the icon. - final StatusBarIconView iconView = new StatusBarIconView(this, - notification.pkg + "/0x" + Integer.toHexString(notification.id)); - final StatusBarIcon ic = new StatusBarIcon(notification.pkg, notification.notification.icon, - notification.notification.iconLevel, notification.notification.number); - if (!iconView.set(ic)) { - handleNotificationError(key, notification, "Coulding create icon: " + ic); - return null; - } - // Add the expanded view. - final int viewIndex = list.add(key, notification, row, content, expanded, iconView); - parent.addView(row, viewIndex); - // Add the icon. - final int iconIndex = chooseIconIndex(isOngoing, viewIndex); - mNotificationIcons.addView(iconView, iconIndex); - return iconView; - } - - StatusBarNotification removeNotificationViews(IBinder key) { - NotificationData.Entry entry = mOngoing.remove(key); - if (entry == null) { - entry = mLatest.remove(key); - if (entry == null) { - Slog.w(TAG, "removeNotification for unknown key: " + key); - return null; - } - } - // Remove the expanded view. - ((ViewGroup)entry.row.getParent()).removeView(entry.row); - // Remove the icon. - ((ViewGroup)entry.icon.getParent()).removeView(entry.icon); - - return entry.notification; + Slog.d(TAG, "Added status bar view w/ gravity 0x" + Integer.toHexString(lp.gravity)); } - - private void setAreThereNotifications() { - boolean ongoing = mOngoing.hasVisibleItems(); - boolean latest = mLatest.hasVisibleItems(); - - // (no ongoing notifications are clearable) - if (mLatest.hasClearableItems()) { - mClearButton.setVisibility(View.VISIBLE); - } else { - mClearButton.setVisibility(View.INVISIBLE); - } - - mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE); - mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE); - - if (ongoing || latest) { - mNoNotificationsTitle.setVisibility(View.GONE); - } else { - mNoNotificationsTitle.setVisibility(View.VISIBLE); - } - } - - - /** - * State is one or more of the DISABLE constants from StatusBarManager. - */ - public void disable(int state) { - final int old = mDisabled; - final int diff = state ^ old; - mDisabled = state; - - if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { - if ((state & StatusBarManager.DISABLE_EXPAND) != 0) { - Slog.d(TAG, "DISABLE_EXPAND: yes"); - animateCollapse(); - } - } - if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); - if (mTicking) { - mTicker.halt(); - } else { - setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); - } - } else { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); - if (!mExpandedVisible) { - setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); - } - } - } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: yes"); - mTicker.halt(); - } - } - } - - /** - * All changes to the status bar and notifications funnel through here and are batched. - */ - private class H extends Handler { - public void handleMessage(Message m) { - switch (m.what) { - case MSG_ANIMATE: - doAnimation(); - break; - case MSG_ANIMATE_REVEAL: - doRevealAnimation(); - break; - } - } - } - - View.OnFocusChangeListener mFocusChangeListener = new View.OnFocusChangeListener() { - public void onFocusChange(View v, boolean hasFocus) { - // Because 'v' is a ViewGroup, all its children will be (un)selected - // too, which allows marqueeing to work. - v.setSelected(hasFocus); - } - }; - - private void makeExpandedVisible() { - if (SPEW) Slog.d(TAG, "Make expanded visible: expanded visible=" + mExpandedVisible); - if (mExpandedVisible) { - return; - } - mExpandedVisible = true; - visibilityChanged(true); - - updateExpandedViewPos(EXPANDED_LEAVE_ALONE); - mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; - mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - mExpandedDialog.getWindow().setAttributes(mExpandedParams); - mExpandedView.requestFocus(View.FOCUS_FORWARD); - mTrackingView.setVisibility(View.VISIBLE); - - if (!mTicking) { - setDateViewVisibility(true, com.android.internal.R.anim.fade_in); - } - } - - public void animateExpand() { - if (SPEW) Slog.d(TAG, "Animate expand: expanded=" + mExpanded); - if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { - return ; - } - if (mExpanded) { - return; - } - - prepareTracking(0, true); - performFling(0, 2000.0f, true); - } - - public void animateCollapse() { - if (SPEW) { - Slog.d(TAG, "animateCollapse(): mExpanded=" + mExpanded - + " mExpandedVisible=" + mExpandedVisible - + " mExpanded=" + mExpanded - + " mAnimating=" + mAnimating - + " mAnimY=" + mAnimY - + " mAnimVel=" + mAnimVel); - } - - if (!mExpandedVisible) { - return; - } - - int y; - if (mAnimating) { - y = (int)mAnimY; - } else { - y = mDisplay.getHeight()-1; - } - // Let the fling think that we're open so it goes in the right direction - // and doesn't try to re-open the windowshade. - mExpanded = true; - prepareTracking(y, false); - performFling(y, -2000.0f, true); - } - - void performExpand() { - if (SPEW) Slog.d(TAG, "performExpand: mExpanded=" + mExpanded); - if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { - return ; - } - if (mExpanded) { - return; - } - - mExpanded = true; - makeExpandedVisible(); - updateExpandedViewPos(EXPANDED_FULL_OPEN); - - if (false) postStartTracing(); - } - - void performCollapse() { - if (SPEW) Slog.d(TAG, "performCollapse: mExpanded=" + mExpanded - + " mExpandedVisible=" + mExpandedVisible - + " mTicking=" + mTicking); - - if (!mExpandedVisible) { - return; - } - mExpandedVisible = false; - visibilityChanged(false); - mExpandedParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; - mExpandedParams.flags &= ~WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM; - mExpandedDialog.getWindow().setAttributes(mExpandedParams); - mTrackingView.setVisibility(View.GONE); - - if ((mDisabled & StatusBarManager.DISABLE_NOTIFICATION_ICONS) == 0) { - setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); - } - if (mDateView.getVisibility() == View.VISIBLE) { - setDateViewVisibility(false, com.android.internal.R.anim.fade_out); - } - - if (!mExpanded) { - return; - } - mExpanded = false; - } - - void doAnimation() { - if (mAnimating) { - if (SPEW) Slog.d(TAG, "doAnimation"); - if (SPEW) Slog.d(TAG, "doAnimation before mAnimY=" + mAnimY); - incrementAnim(); - if (SPEW) Slog.d(TAG, "doAnimation after mAnimY=" + mAnimY); - if (mAnimY >= mDisplay.getHeight()-1) { - if (SPEW) Slog.d(TAG, "Animation completed to expanded state."); - mAnimating = false; - updateExpandedViewPos(EXPANDED_FULL_OPEN); - performExpand(); - } - else if (mAnimY < mStatusBarView.getHeight()) { - if (SPEW) Slog.d(TAG, "Animation completed to collapsed state."); - mAnimating = false; - updateExpandedViewPos(0); - performCollapse(); - } - else { - updateExpandedViewPos((int)mAnimY); - mCurAnimationTime += ANIM_FRAME_DURATION; - mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime); - } - } - } - - void stopTracking() { - mTracking = false; - mVelocityTracker.recycle(); - mVelocityTracker = null; - } - - void incrementAnim() { - long now = SystemClock.uptimeMillis(); - float t = ((float)(now - mAnimLastTime)) / 1000; // ms -> s - final float y = mAnimY; - final float v = mAnimVel; // px/s - final float a = mAnimAccel; // px/s/s - mAnimY = y + (v*t) + (0.5f*a*t*t); // px - mAnimVel = v + (a*t); // px/s - mAnimLastTime = now; // ms - //Slog.d(TAG, "y=" + y + " v=" + v + " a=" + a + " t=" + t + " mAnimY=" + mAnimY - // + " mAnimAccel=" + mAnimAccel); - } - - void doRevealAnimation() { - final int h = mCloseView.getHeight() + mStatusBarView.getHeight(); - if (mAnimatingReveal && mAnimating && mAnimY < h) { - incrementAnim(); - if (mAnimY >= h) { - mAnimY = h; - updateExpandedViewPos((int)mAnimY); - } else { - updateExpandedViewPos((int)mAnimY); - mCurAnimationTime += ANIM_FRAME_DURATION; - mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL), - mCurAnimationTime); - } - } - } - - void prepareTracking(int y, boolean opening) { - mTracking = true; - mVelocityTracker = VelocityTracker.obtain(); - if (opening) { - mAnimAccel = 2000.0f; - mAnimVel = 200; - mAnimY = mStatusBarView.getHeight(); - updateExpandedViewPos((int)mAnimY); - mAnimating = true; - mAnimatingReveal = true; - mHandler.removeMessages(MSG_ANIMATE); - mHandler.removeMessages(MSG_ANIMATE_REVEAL); - long now = SystemClock.uptimeMillis(); - mAnimLastTime = now; - mCurAnimationTime = now + ANIM_FRAME_DURATION; - mAnimating = true; - mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE_REVEAL), - mCurAnimationTime); - makeExpandedVisible(); - } else { - // it's open, close it? - if (mAnimating) { - mAnimating = false; - mHandler.removeMessages(MSG_ANIMATE); - } - updateExpandedViewPos(y + mViewDelta); - } - } - - void performFling(int y, float vel, boolean always) { - mAnimatingReveal = false; - mDisplayHeight = mDisplay.getHeight(); - - mAnimY = y; - mAnimVel = vel; - - //Slog.d(TAG, "starting with mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel); - - if (mExpanded) { - if (!always && ( - vel > 200.0f - || (y > (mDisplayHeight-25) && vel > -200.0f))) { - // We are expanded, but they didn't move sufficiently to cause - // us to retract. Animate back to the expanded position. - mAnimAccel = 2000.0f; - if (vel < 0) { - mAnimVel = 0; - } - } - else { - // We are expanded and are now going to animate away. - mAnimAccel = -2000.0f; - if (vel > 0) { - mAnimVel = 0; - } - } - } else { - if (always || ( - vel > 200.0f - || (y > (mDisplayHeight/2) && vel > -200.0f))) { - // We are collapsed, and they moved enough to allow us to - // expand. Animate in the notifications. - mAnimAccel = 2000.0f; - if (vel < 0) { - mAnimVel = 0; - } - } - else { - // We are collapsed, but they didn't move sufficiently to cause - // us to retract. Animate back to the collapsed position. - mAnimAccel = -2000.0f; - if (vel > 0) { - mAnimVel = 0; - } - } - } - //Slog.d(TAG, "mAnimY=" + mAnimY + " mAnimVel=" + mAnimVel - // + " mAnimAccel=" + mAnimAccel); - - long now = SystemClock.uptimeMillis(); - mAnimLastTime = now; - mCurAnimationTime = now + ANIM_FRAME_DURATION; - mAnimating = true; - mHandler.removeMessages(MSG_ANIMATE); - mHandler.removeMessages(MSG_ANIMATE_REVEAL); - mHandler.sendMessageAtTime(mHandler.obtainMessage(MSG_ANIMATE), mCurAnimationTime); - stopTracking(); - } - - boolean interceptTouchEvent(MotionEvent event) { - if (SPEW) { - Slog.d(TAG, "Touch: rawY=" + event.getRawY() + " event=" + event + " mDisabled=" - + mDisabled); - } - - if ((mDisabled & StatusBarManager.DISABLE_EXPAND) != 0) { - return false; - } - - final int statusBarSize = mStatusBarView.getHeight(); - final int hitSize = statusBarSize*2; - if (event.getAction() == MotionEvent.ACTION_DOWN) { - final int y = (int)event.getRawY(); - - if (!mExpanded) { - mViewDelta = statusBarSize - y; - } else { - mTrackingView.getLocationOnScreen(mAbsPos); - mViewDelta = mAbsPos[1] + mTrackingView.getHeight() - y; - } - if ((!mExpanded && y < hitSize) || - (mExpanded && y > (mDisplay.getHeight()-hitSize))) { - - // We drop events at the edge of the screen to make the windowshade come - // down by accident less, especially when pushing open a device with a keyboard - // that rotates (like g1 and droid) - int x = (int)event.getRawX(); - final int edgeBorder = mEdgeBorder; - if (x >= edgeBorder && x < mDisplay.getWidth() - edgeBorder) { - prepareTracking(y, !mExpanded);// opening if we're not already fully visible - mVelocityTracker.addMovement(event); - } - } - } else if (mTracking) { - mVelocityTracker.addMovement(event); - final int minY = statusBarSize + mCloseView.getHeight(); - if (event.getAction() == MotionEvent.ACTION_MOVE) { - int y = (int)event.getRawY(); - if (mAnimatingReveal && y < minY) { - // nothing - } else { - mAnimatingReveal = false; - updateExpandedViewPos(y + mViewDelta); - } - } else if (event.getAction() == MotionEvent.ACTION_UP) { - mVelocityTracker.computeCurrentVelocity(1000); - - float yVel = mVelocityTracker.getYVelocity(); - boolean negative = yVel < 0; - - float xVel = mVelocityTracker.getXVelocity(); - if (xVel < 0) { - xVel = -xVel; - } - if (xVel > 150.0f) { - xVel = 150.0f; // limit how much we care about the x axis - } - - float vel = (float)Math.hypot(yVel, xVel); - if (negative) { - vel = -vel; - } - - performFling((int)event.getRawY(), vel, false); - } - - } - return false; - } - - private class Launcher implements View.OnClickListener { - private PendingIntent mIntent; - private String mPkg; - private String mTag; - private int mId; - - Launcher(PendingIntent intent, String pkg, String tag, int id) { - mIntent = intent; - mPkg = pkg; - mTag = tag; - mId = id; - } - - public void onClick(View v) { - try { - // The intent we are sending is for the application, which - // won't have permission to immediately start an activity after - // the user switches to home. We know it is safe to do at this - // point, so make sure new activity switches are now allowed. - ActivityManagerNative.getDefault().resumeAppSwitches(); - } catch (RemoteException e) { - } - - if (mIntent != null) { - int[] pos = new int[2]; - v.getLocationOnScreen(pos); - Intent overlay = new Intent(); - overlay.setSourceBounds( - new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight())); - try { - mIntent.send(StatusBarService.this, 0, overlay); - } catch (PendingIntent.CanceledException e) { - // the stack trace isn't very helpful here. Just log the exception message. - Slog.w(TAG, "Sending contentIntent failed: " + e); - } - } - - try { - mBarService.onNotificationClick(mPkg, mTag, mId); - } catch (RemoteException ex) { - // system process is dead if we're here. - } - - // close the shade if it was open - animateCollapse(); - } - } - - private void tick(StatusBarNotification n) { - // Show the ticker if one is requested. Also don't do this - // until status bar window is attached to the window manager, - // because... well, what's the point otherwise? And trying to - // run a ticker without being attached will crash! - if (n.notification.tickerText != null && mStatusBarView.getWindowToken() != null) { - if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS - | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) { - mTicker.addEntry(n); - } - } - } - - /** - * Cancel this notification and tell the StatusBarManagerService / NotificationManagerService - * about the failure. - * - * WARNING: this will call back into us. Don't hold any locks. - */ - void handleNotificationError(IBinder key, StatusBarNotification n, String message) { - removeNotification(key); - try { - mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message); - } catch (RemoteException ex) { - // The end is nigh. - } - } - - private class MyTicker extends Ticker { - MyTicker(Context context, StatusBarView sb) { - super(context, sb); - } - - @Override - void tickerStarting() { - if (SPEW) Slog.d(TAG, "tickerStarting"); - mTicking = true; - mIcons.setVisibility(View.GONE); - mTickerView.setVisibility(View.VISIBLE); - mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null)); - mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null)); - if (mExpandedVisible) { - setDateViewVisibility(false, com.android.internal.R.anim.push_up_out); - } - } - - @Override - void tickerDone() { - if (SPEW) Slog.d(TAG, "tickerDone"); - mTicking = false; - mIcons.setVisibility(View.VISIBLE); - mTickerView.setVisibility(View.GONE); - mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null)); - mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out, null)); - if (mExpandedVisible) { - setDateViewVisibility(true, com.android.internal.R.anim.push_down_in); - } - } - - void tickerHalting() { - if (SPEW) Slog.d(TAG, "tickerHalting"); - mTicking = false; - mIcons.setVisibility(View.VISIBLE); - mTickerView.setVisibility(View.GONE); - mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null)); - mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out, null)); - if (mExpandedVisible) { - setDateViewVisibility(true, com.android.internal.R.anim.fade_in); - } - } - } - - private Animation loadAnim(int id, Animation.AnimationListener listener) { - Animation anim = AnimationUtils.loadAnimation(StatusBarService.this, id); - if (listener != null) { - anim.setAnimationListener(listener); - } - return anim; - } - - public String viewInfo(View v) { - return "(" + v.getLeft() + "," + v.getTop() + ")(" + v.getRight() + "," + v.getBottom() - + " " + v.getWidth() + "x" + v.getHeight() + ")"; - } - - protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) { - if (checkCallingOrSelfPermission(android.Manifest.permission.DUMP) - != PackageManager.PERMISSION_GRANTED) { - pw.println("Permission Denial: can't dump StatusBar from from pid=" - + Binder.getCallingPid() - + ", uid=" + Binder.getCallingUid()); - return; - } - - synchronized (mQueueLock) { - pw.println("Current Status Bar state:"); - pw.println(" mExpanded=" + mExpanded - + ", mExpandedVisible=" + mExpandedVisible); - pw.println(" mTicking=" + mTicking); - pw.println(" mTracking=" + mTracking); - pw.println(" mAnimating=" + mAnimating - + ", mAnimY=" + mAnimY + ", mAnimVel=" + mAnimVel - + ", mAnimAccel=" + mAnimAccel); - pw.println(" mCurAnimationTime=" + mCurAnimationTime - + " mAnimLastTime=" + mAnimLastTime); - pw.println(" mDisplayHeight=" + mDisplayHeight - + " mAnimatingReveal=" + mAnimatingReveal - + " mViewDelta=" + mViewDelta); - pw.println(" mDisplayHeight=" + mDisplayHeight); - pw.println(" mExpandedParams: " + mExpandedParams); - pw.println(" mExpandedView: " + viewInfo(mExpandedView)); - pw.println(" mExpandedDialog: " + mExpandedDialog); - pw.println(" mTrackingParams: " + mTrackingParams); - pw.println(" mTrackingView: " + viewInfo(mTrackingView)); - pw.println(" mOngoingTitle: " + viewInfo(mOngoingTitle)); - pw.println(" mOngoingItems: " + viewInfo(mOngoingItems)); - pw.println(" mLatestTitle: " + viewInfo(mLatestTitle)); - pw.println(" mLatestItems: " + viewInfo(mLatestItems)); - pw.println(" mNoNotificationsTitle: " + viewInfo(mNoNotificationsTitle)); - pw.println(" mCloseView: " + viewInfo(mCloseView)); - pw.println(" mTickerView: " + viewInfo(mTickerView)); - pw.println(" mScrollView: " + viewInfo(mScrollView) - + " scroll " + mScrollView.getScrollX() + "," + mScrollView.getScrollY()); - pw.println("mNotificationLinearLayout: " + viewInfo(mNotificationLinearLayout)); - } - - if (true) { - // must happen on ui thread - mHandler.post(new Runnable() { - public void run() { - Slog.d(TAG, "mStatusIcons:"); - mStatusIcons.debug(); - } - }); - } - - } - - void onBarViewAttached() { - WindowManager.LayoutParams lp; - int pixelFormat; - Drawable bg; - - /// ---------- Tracking View -------------- - pixelFormat = PixelFormat.RGBX_8888; - bg = mTrackingView.getBackground(); - if (bg != null) { - pixelFormat = bg.getOpacity(); - } - - lp = new WindowManager.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT, - WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, - WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - | WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM, - pixelFormat); -// lp.token = mStatusBarView.getWindowToken(); - lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; - lp.setTitle("TrackingView"); - lp.y = mTrackingPosition; - mTrackingParams = lp; - - WindowManagerImpl.getDefault().addView(mTrackingView, lp); - } - - void onTrackingViewAttached() { - WindowManager.LayoutParams lp; - int pixelFormat; - Drawable bg; - - /// ---------- Expanded View -------------- - pixelFormat = PixelFormat.TRANSLUCENT; - - final int disph = mDisplay.getHeight(); - lp = mExpandedDialog.getWindow().getAttributes(); - lp.width = ViewGroup.LayoutParams.MATCH_PARENT; - lp.height = getExpandedHeight(); - lp.x = 0; - mTrackingPosition = lp.y = -disph; // sufficiently large negative - lp.type = WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL; - lp.flags = WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN - | WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS - | WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL - | WindowManager.LayoutParams.FLAG_DITHER - | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE; - lp.format = pixelFormat; - lp.gravity = Gravity.TOP | Gravity.FILL_HORIZONTAL; - lp.setTitle("StatusBarExpanded"); - mExpandedDialog.getWindow().setAttributes(lp); - mExpandedDialog.getWindow().setFormat(pixelFormat); - mExpandedParams = lp; - - mExpandedDialog.getWindow().requestFeature(Window.FEATURE_NO_TITLE); - mExpandedDialog.setContentView(mExpandedView, - new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, - ViewGroup.LayoutParams.MATCH_PARENT)); - mExpandedDialog.getWindow().setBackgroundDrawable(null); - mExpandedDialog.show(); - FrameLayout hack = (FrameLayout)mExpandedView.getParent(); - } - - void setDateViewVisibility(boolean visible, int anim) { - mDateView.setUpdates(visible); - mDateView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE); - mDateView.startAnimation(loadAnim(anim, null)); - } - - void setNotificationIconVisibility(boolean visible, int anim) { - int old = mNotificationIcons.getVisibility(); - int v = visible ? View.VISIBLE : View.INVISIBLE; - if (old != v) { - mNotificationIcons.setVisibility(v); - mNotificationIcons.startAnimation(loadAnim(anim, null)); - } - } - - void updateExpandedViewPos(int expandedPosition) { - if (SPEW) { - Slog.d(TAG, "updateExpandedViewPos before expandedPosition=" + expandedPosition - + " mTrackingParams.y=" - + ((mTrackingParams == null) ? "???" : mTrackingParams.y) - + " mTrackingPosition=" + mTrackingPosition); - } - - int h = mStatusBarView.getHeight(); - int disph = mDisplay.getHeight(); - - // If the expanded view is not visible, make sure they're still off screen. - // Maybe the view was resized. - if (!mExpandedVisible) { - if (mTrackingView != null) { - mTrackingPosition = -disph; - if (mTrackingParams != null) { - mTrackingParams.y = mTrackingPosition; - WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams); - } - } - if (mExpandedParams != null) { - mExpandedParams.y = -disph; - mExpandedDialog.getWindow().setAttributes(mExpandedParams); - } - return; - } - - // tracking view... - int pos; - if (expandedPosition == EXPANDED_FULL_OPEN) { - pos = h; - } - else if (expandedPosition == EXPANDED_LEAVE_ALONE) { - pos = mTrackingPosition; - } - else { - if (expandedPosition <= disph) { - pos = expandedPosition; - } else { - pos = disph; - } - pos -= disph-h; - } - mTrackingPosition = mTrackingParams.y = pos; - mTrackingParams.height = disph-h; - WindowManagerImpl.getDefault().updateViewLayout(mTrackingView, mTrackingParams); - - if (mExpandedParams != null) { - mCloseView.getLocationInWindow(mPositionTmp); - final int closePos = mPositionTmp[1]; - - mExpandedContents.getLocationInWindow(mPositionTmp); - final int contentsBottom = mPositionTmp[1] + mExpandedContents.getHeight(); - - mExpandedParams.y = pos + mTrackingView.getHeight() - - (mTrackingParams.height-closePos) - contentsBottom; - int max = h; - if (mExpandedParams.y > max) { - mExpandedParams.y = max; - } - int min = mTrackingPosition; - if (mExpandedParams.y < min) { - mExpandedParams.y = min; - } - - boolean visible = (mTrackingPosition + mTrackingView.getHeight()) > h; - if (!visible) { - // if the contents aren't visible, move the expanded view way off screen - // because the window itself extends below the content view. - mExpandedParams.y = -disph; - } - mExpandedDialog.getWindow().setAttributes(mExpandedParams); - - // As long as this isn't just a repositioning that's not supposed to affect - // the user's perception of what's showing, call to say that the visibility - // has changed. (Otherwise, someone else will call to do that). - if (expandedPosition != EXPANDED_LEAVE_ALONE) { - if (SPEW) Slog.d(TAG, "updateExpandedViewPos visibilityChanged(" + visible + ")"); - visibilityChanged(visible); - } - } - - if (SPEW) { - Slog.d(TAG, "updateExpandedViewPos after expandedPosition=" + expandedPosition - + " mTrackingParams.y=" + mTrackingParams.y - + " mTrackingPosition=" + mTrackingPosition - + " mExpandedParams.y=" + mExpandedParams.y - + " mExpandedParams.height=" + mExpandedParams.height); - } - } - - int getExpandedHeight() { - return mDisplay.getHeight() - mStatusBarView.getHeight() - mCloseView.getHeight(); - } - - void updateExpandedHeight() { - if (mExpandedView != null) { - mExpandedParams.height = getExpandedHeight(); - mExpandedDialog.getWindow().setAttributes(mExpandedParams); - } - } - - /** - * The LEDs are turned o)ff when the notification panel is shown, even just a little bit. - * This was added last-minute and is inconsistent with the way the rest of the notifications - * are handled, because the notification isn't really cancelled. The lights are just - * turned off. If any other notifications happen, the lights will turn back on. Steve says - * this is what he wants. (see bug 1131461) - */ - void visibilityChanged(boolean visible) { - if (mPanelSlightlyVisible != visible) { - mPanelSlightlyVisible = visible; - try { - mBarService.onPanelRevealed(); - } catch (RemoteException ex) { - // Won't fail unless the world has ended. - } - } - } - - void performDisableActions(int net) { - int old = mDisabled; - int diff = net ^ old; - mDisabled = net; - - // act accordingly - if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { - if ((net & StatusBarManager.DISABLE_EXPAND) != 0) { - Slog.d(TAG, "DISABLE_EXPAND: yes"); - animateCollapse(); - } - } - if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); - if (mTicking) { - mNotificationIcons.setVisibility(View.INVISIBLE); - mTicker.halt(); - } else { - setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out); - } - } else { - Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); - if (!mExpandedVisible) { - setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in); - } - } - } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - Slog.d(TAG, "DISABLE_NOTIFICATION_TICKER: " - + (((net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) - ? "yes" : "no")); - if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { - mTicker.halt(); - } - } - } - - private View.OnClickListener mClearButtonListener = new View.OnClickListener() { - public void onClick(View v) { - try { - mBarService.onClearAllNotifications(); - } catch (RemoteException ex) { - // system process is dead if we're here. - } - animateCollapse(); - } - }; - - private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() { - public void onReceive(Context context, Intent intent) { - String action = intent.getAction(); - if (Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action) - || Intent.ACTION_SCREEN_OFF.equals(action)) { - animateCollapse(); - } - else if (Intent.ACTION_CONFIGURATION_CHANGED.equals(action)) { - updateResources(); - } - } - }; - - /** - * Reload some of our resources when the configuration changes. - * - * We don't reload everything when the configuration changes -- we probably - * should, but getting that smooth is tough. Someday we'll fix that. In the - * meantime, just update the things that we know change. - */ - void updateResources() { - Resources res = getResources(); - - mClearButton.setText(getText(R.string.status_bar_clear_all_button)); - mOngoingTitle.setText(getText(R.string.status_bar_ongoing_events_title)); - mLatestTitle.setText(getText(R.string.status_bar_latest_events_title)); - mNoNotificationsTitle.setText(getText(R.string.status_bar_no_notifications_title)); - - mEdgeBorder = res.getDimensionPixelSize(R.dimen.status_bar_edge_ignore); - - if (false) Slog.v(TAG, "updateResources"); - } - - // - // tracing - // - - void postStartTracing() { - mHandler.postDelayed(mStartTracing, 3000); - } - - void vibrate() { - android.os.Vibrator vib = (android.os.Vibrator)getSystemService(Context.VIBRATOR_SERVICE); - vib.vibrate(250); - } - - Runnable mStartTracing = new Runnable() { - public void run() { - vibrate(); - SystemClock.sleep(250); - Slog.d(TAG, "startTracing"); - android.os.Debug.startMethodTracing("/data/statusbar-traces/trace"); - mHandler.postDelayed(mStopTracing, 10000); - } - }; - - Runnable mStopTracing = new Runnable() { - public void run() { - android.os.Debug.stopMethodTracing(); - Slog.d(TAG, "stopTracing"); - vibrate(); - } - }; } + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java index 117b126..20fc41f 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarView.java @@ -19,6 +19,7 @@ package com.android.systemui.statusbar; import android.content.Context; import android.content.res.Configuration; import android.graphics.Canvas; +import android.graphics.Rect; import android.os.SystemClock; import android.util.AttributeSet; import android.view.MotionEvent; @@ -34,7 +35,7 @@ public class StatusBarView extends FrameLayout { static final int DIM_ANIM_TIME = 400; - StatusBarService mService; + PhoneStatusBarService mService; boolean mTracking; int mStartX, mStartY; ViewGroup mNotificationIcons; @@ -42,6 +43,13 @@ public class StatusBarView extends FrameLayout { View mDate; FixedSizeDrawable mBackground; + boolean mNightMode = false; + int mStartAlpha = 0, mEndAlpha = 0; + long mEndTime = 0; + + Rect mButtonBounds = new Rect(); + boolean mCapturingEvents = true; + public StatusBarView(Context context, AttributeSet attrs) { super(context, attrs); } @@ -65,9 +73,32 @@ public class StatusBarView extends FrameLayout { } @Override + protected void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + boolean nightMode = (newConfig.uiMode & Configuration.UI_MODE_NIGHT_MASK) + == Configuration.UI_MODE_NIGHT_YES; + if (mNightMode != nightMode) { + mNightMode = nightMode; + mStartAlpha = getCurAlpha(); + mEndAlpha = mNightMode ? 0x80 : 0x00; + mEndTime = SystemClock.uptimeMillis() + DIM_ANIM_TIME; + invalidate(); + } + } + + int getCurAlpha() { + long time = SystemClock.uptimeMillis(); + if (time > mEndTime) { + return mEndAlpha; + } + return mEndAlpha + - (int)(((mEndAlpha-mStartAlpha) * (mEndTime-time) / DIM_ANIM_TIME)); + } + + @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); - mService.updateExpandedViewPos(StatusBarService.EXPANDED_LEAVE_ALONE); + mService.updateExpandedViewPos(PhoneStatusBarService.EXPANDED_LEAVE_ALONE); } @Override @@ -100,6 +131,18 @@ public class StatusBarView extends FrameLayout { mBackground.setFixedBounds(-mDate.getLeft(), -mDate.getTop(), (r-l), (b-t)); } + @Override + protected void dispatchDraw(Canvas canvas) { + super.dispatchDraw(canvas); + int alpha = getCurAlpha(); + if (alpha != 0) { + canvas.drawARGB(alpha, 0, 0, 0); + } + if (alpha != mEndAlpha) { + invalidate(); + } + } + /** * Gets the left position of v in this view. Throws if v is not * a child of this. @@ -138,6 +181,9 @@ public class StatusBarView extends FrameLayout { */ @Override public boolean onTouchEvent(MotionEvent event) { + if (!mCapturingEvents) { + return false; + } if (event.getAction() != MotionEvent.ACTION_DOWN) { mService.interceptTouchEvent(event); } @@ -146,6 +192,13 @@ public class StatusBarView extends FrameLayout { @Override public boolean onInterceptTouchEvent(MotionEvent event) { + if (event.getAction() == MotionEvent.ACTION_DOWN) { + if (mButtonBounds.contains((int)event.getX(), (int)event.getY())) { + mCapturingEvents = false; + return false; + } + } + mCapturingEvents = true; return mService.interceptTouchEvent(event) ? true : super.onInterceptTouchEvent(event); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java b/packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java index 3a697a6..e7b0509 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/Ticker.java @@ -141,7 +141,7 @@ public abstract class Ticker { } }; - Ticker(Context context, StatusBarView sb) { + public Ticker(Context context, View sb) { mContext = context; mTickerView = sb.findViewById(R.id.ticker); @@ -163,7 +163,7 @@ public abstract class Ticker { } - void addEntry(StatusBarNotification n) { + public void addEntry(StatusBarNotification n) { int initialCount = mSegments.size(); // If what's being displayed has the same text and icon, just drop it @@ -212,7 +212,7 @@ public abstract class Ticker { } } - void removeEntry(StatusBarNotification n) { + public void removeEntry(StatusBarNotification n) { for (int i=mSegments.size()-1; i>=0; i--) { Segment seg = mSegments.get(i); if (n.id == seg.notification.id && n.pkg.equals(seg.notification.pkg)) { @@ -221,13 +221,13 @@ public abstract class Ticker { } } - void halt() { + public void halt() { mHandler.removeCallbacks(mAdvanceTicker); mSegments.clear(); tickerHalting(); } - void reflowText() { + public void reflowText() { if (mSegments.size() > 0) { Segment seg = mSegments.get(0); CharSequence text = seg.getText(); @@ -266,8 +266,8 @@ public abstract class Ticker { mHandler.postDelayed(mAdvanceTicker, TICKER_SEGMENT_DELAY); } - abstract void tickerStarting(); - abstract void tickerDone(); - abstract void tickerHalting(); + public abstract void tickerStarting(); + public abstract void tickerDone(); + public abstract void tickerHalting(); } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java b/packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java index 9749ae4..8140811 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/TickerView.java @@ -34,5 +34,9 @@ public class TickerView extends TextSwitcher super.onSizeChanged(w, h, oldw, oldh); mTicker.reflowText(); } + + public void setTicker(Ticker t) { + mTicker = t; + } } diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java b/packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java index 9108eee..c59eb6a 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/TrackingView.java @@ -26,7 +26,7 @@ import android.widget.LinearLayout; public class TrackingView extends LinearLayout { final Display mDisplay; - StatusBarService mService; + PhoneStatusBarService mService; boolean mTracking; int mStartX, mStartY; diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java new file mode 100644 index 0000000..ba682b7 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/InputMethodButton.java @@ -0,0 +1,51 @@ +/* + * 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 android.content.Context; +import android.util.Slog; +import android.view.View; +import android.util.AttributeSet; +import android.widget.ImageView; +import android.view.inputmethod.InputMethodManager; + +import com.android.server.InputMethodManagerService; + +public class InputMethodButton extends ImageView { + + // other services we wish to talk to + InputMethodManager mImm; + + public InputMethodButton(Context context, AttributeSet attrs) { + super(context, attrs); + + // IME hookup + mImm = (InputMethodManager) getContext().getSystemService(Context.INPUT_METHOD_SERVICE); + + // TODO: read the current icon & visibility state directly from the service + + // TODO: register for notifications about changes to visibility & subtype from service + + setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + mImm.showInputMethodSubtypePicker(); + } + }); + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java new file mode 100644 index 0000000..7c7d74c --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationIconArea.java @@ -0,0 +1,56 @@ +/* + * 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 android.content.Context; +import android.content.res.Resources; +import android.os.Handler; +import android.util.AttributeSet; +import android.util.Slog; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ImageView; + +import com.android.systemui.R; + + +public class NotificationIconArea extends LinearLayout { + private static final String TAG = "NotificationIconArea"; + + IconLayout mIconLayout; + DraggerView mDraggerView; + + public NotificationIconArea(Context context, AttributeSet attrs) { + super(context, attrs); + + mIconLayout = (IconLayout)findViewById(R.id.icons); + mDraggerView = (DraggerView) findViewById(R.id.handle); + } + + static class IconLayout extends LinearLayout { + public IconLayout(Context context, AttributeSet attrs) { + super(context, attrs); + } + } + + static class DraggerView extends View { + public DraggerView(Context context, AttributeSet attrs) { + super(context, attrs); + } + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java new file mode 100644 index 0000000..eee0a16 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java @@ -0,0 +1,41 @@ +/* + * 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 android.content.Context; +import android.widget.LinearLayout; +import android.util.AttributeSet; + +public class NotificationPanel extends LinearLayout implements StatusBarPanel { + + public NotificationPanel(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public NotificationPanel(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + } + + 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; + } +} + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/StatusBarPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/StatusBarPanel.java new file mode 100644 index 0000000..8fa01d5 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/StatusBarPanel.java @@ -0,0 +1,21 @@ +/* + * 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; + +public interface StatusBarPanel { + public boolean isInContentArea(int x, int y); +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java new file mode 100644 index 0000000..a0f5be6 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/SystemPanel.java @@ -0,0 +1,712 @@ +/* + * 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 android.app.Notification; +import android.app.PendingIntent; +import android.app.Service; +import android.app.StatusBarManager; +import android.bluetooth.BluetoothAdapter; +import android.content.BroadcastReceiver; +import android.content.ContentResolver; +import android.content.Context; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.res.Resources; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.location.LocationManager; +import android.media.AudioManager; +import android.net.NetworkInfo; +import android.net.wifi.SupplicantState; +import android.net.wifi.WifiConfiguration; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.AsyncTask; +import android.os.Handler; +import android.os.IBinder; +import android.os.IPowerManager; +import android.os.Message; +import android.os.RemoteException; +import android.os.RemoteException; +import android.os.ServiceManager; +import android.provider.Settings; +import android.telephony.PhoneStateListener; +import android.telephony.ServiceState; +import android.telephony.SignalStrength; +import android.telephony.TelephonyManager; +import android.util.AttributeSet; +import android.util.Slog; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.WindowManagerImpl; +import android.widget.Button; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RemoteViews; +import android.widget.ScrollView; +import android.widget.TextSwitcher; +import android.widget.TextView; +import android.widget.Toast; + +import java.util.List; + +import com.android.internal.telephony.IccCard; +import com.android.internal.telephony.TelephonyIntents; +import com.android.internal.telephony.cdma.EriInfo; +import com.android.internal.telephony.cdma.TtyIntent; + +import com.android.systemui.statusbar.*; +import com.android.systemui.R; + +public class SystemPanel extends LinearLayout implements StatusBarPanel { + private static final String TAG = "SystemPanel"; + private static final boolean DEBUG = TabletStatusBarService.DEBUG; + private static final boolean DEBUG_SIGNAL = false; + + private static final int MINIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_DIM + 5; + private static final int MAXIMUM_BACKLIGHT = android.os.Power.BRIGHTNESS_ON; + private static final int DEFAULT_BACKLIGHT = (int) (android.os.Power.BRIGHTNESS_ON * 0.4f); + + private TabletStatusBarService mBar; + private boolean mAirplaneMode; + + private ImageButton mBrightnessButton; + private ImageButton mSoundButton; + private ImageButton mOrientationButton; + private ImageButton mAirplaneButton; + private ImageButton mGpsButton; + private ImageButton mBluetoothButton; + + private ImageView mBatteryMeter; + private ImageView mSignalMeter; + + private TextView mBatteryText; + private TextView mSignalText; + + private final AudioManager mAudioManager; + private final WifiManager mWifiManager; + private final TelephonyManager mPhone; + private final BluetoothAdapter mBluetoothAdapter; + + // state trackers for telephony code + IccCard.State mSimState = IccCard.State.READY; + int mPhoneState = TelephonyManager.CALL_STATE_IDLE; + int mDataState = TelephonyManager.DATA_DISCONNECTED; + ServiceState mServiceState; + SignalStrength mSignalStrength; + + // state for the meters + boolean mWifiEnabled, mWifiConnected; + int mWifiLevel; + String mWifiSsid; + + boolean mDataEnabled, mDataConnected, mDataRoaming; + int mDataLevel; + + 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; + } + + private BroadcastReceiver mReceiver = new BroadcastReceiver() { + @Override + public void onReceive(Context context, Intent intent) { + final String action = intent.getAction(); + if (action.equals(AudioManager.RINGER_MODE_CHANGED_ACTION)) { + refreshSound(); + } else if (action.equals(Intent.ACTION_BATTERY_CHANGED)) { + updateBattery(intent); + } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION) + || action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION) + || action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION) + || action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { + updateWifiState(intent); + } else if (action.equals(TelephonyIntents.ACTION_SIM_STATE_CHANGED)) { + updateSimState(intent); + } else if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { + refreshBluetooth(); + } + } + }; + + private final void updateSimState(Intent intent) { + String stateExtra = intent.getStringExtra(IccCard.INTENT_KEY_ICC_STATE); + if (IccCard.INTENT_VALUE_ICC_ABSENT.equals(stateExtra)) { + mSimState = IccCard.State.ABSENT; + } + else if (IccCard.INTENT_VALUE_ICC_READY.equals(stateExtra)) { + mSimState = IccCard.State.READY; + } + else if (IccCard.INTENT_VALUE_ICC_LOCKED.equals(stateExtra)) { + final String lockedReason = intent.getStringExtra(IccCard.INTENT_KEY_LOCKED_REASON); + if (IccCard.INTENT_VALUE_LOCKED_ON_PIN.equals(lockedReason)) { + mSimState = IccCard.State.PIN_REQUIRED; + } + else if (IccCard.INTENT_VALUE_LOCKED_ON_PUK.equals(lockedReason)) { + mSimState = IccCard.State.PUK_REQUIRED; + } + else { + mSimState = IccCard.State.NETWORK_LOCKED; + } + } else { + mSimState = IccCard.State.UNKNOWN; + } + updateDataState(); + } + + private boolean isCdma() { + return (mSignalStrength != null) && !mSignalStrength.isGsm(); + } + + private boolean isEvdo() { + return ( (mServiceState != null) + && ((mServiceState.getRadioTechnology() + == ServiceState.RADIO_TECHNOLOGY_EVDO_0) + || (mServiceState.getRadioTechnology() + == ServiceState.RADIO_TECHNOLOGY_EVDO_A) + || (mServiceState.getRadioTechnology() + == ServiceState.RADIO_TECHNOLOGY_EVDO_B))); + } + + private boolean hasService() { + if (mServiceState != null) { + switch (mServiceState.getState()) { + case ServiceState.STATE_OUT_OF_SERVICE: + case ServiceState.STATE_POWER_OFF: + return false; + default: + return true; + } + } else { + return false; + } + } + + private int getCdmaLevel() { + if (mSignalStrength == null) return 0; + final int cdmaDbm = mSignalStrength.getCdmaDbm(); + final int cdmaEcio = mSignalStrength.getCdmaEcio(); + int levelDbm = 0; + int levelEcio = 0; + + if (cdmaDbm >= -75) levelDbm = 4; + else if (cdmaDbm >= -85) levelDbm = 3; + else if (cdmaDbm >= -95) levelDbm = 2; + else if (cdmaDbm >= -100) levelDbm = 1; + else levelDbm = 0; + + // Ec/Io are in dB*10 + if (cdmaEcio >= -90) levelEcio = 4; + else if (cdmaEcio >= -110) levelEcio = 3; + else if (cdmaEcio >= -130) levelEcio = 2; + else if (cdmaEcio >= -150) levelEcio = 1; + else levelEcio = 0; + + return (levelDbm < levelEcio) ? levelDbm : levelEcio; + } + + private int getEvdoLevel() { + if (mSignalStrength == null) return 0; + int evdoDbm = mSignalStrength.getEvdoDbm(); + int evdoSnr = mSignalStrength.getEvdoSnr(); + int levelEvdoDbm = 0; + int levelEvdoSnr = 0; + + if (evdoDbm >= -65) levelEvdoDbm = 4; + else if (evdoDbm >= -75) levelEvdoDbm = 3; + else if (evdoDbm >= -90) levelEvdoDbm = 2; + else if (evdoDbm >= -105) levelEvdoDbm = 1; + else levelEvdoDbm = 0; + + if (evdoSnr >= 7) levelEvdoSnr = 4; + else if (evdoSnr >= 5) levelEvdoSnr = 3; + else if (evdoSnr >= 3) levelEvdoSnr = 2; + else if (evdoSnr >= 1) levelEvdoSnr = 1; + else levelEvdoSnr = 0; + + return (levelEvdoDbm < levelEvdoSnr) ? levelEvdoDbm : levelEvdoSnr; + } + + private void updateDataState() { + mDataConnected = hasService() && (mDataState == TelephonyManager.DATA_CONNECTED); + + if (isCdma()) { + // these functions return a value from 0 to 4, inclusive + if ((mPhoneState == TelephonyManager.CALL_STATE_IDLE) && isEvdo()){ + mDataLevel = getEvdoLevel() * 25; + } else { + mDataLevel = getCdmaLevel() * 25; + } + } else { + // GSM + + int asu = (mSignalStrength == null) ? 0 : mSignalStrength.getGsmSignalStrength(); + + // asu on [0,31]; 99 = unknown + // Android has historically shown anything >=12 as "full" + // XXX: tune this based on Industry Best Practices(TM) + if (asu <= 2 || asu == 99) mDataLevel = 0; + else mDataLevel = (int)(((float)Math.max(asu, 15) / 15) * 100); + + mDataRoaming = mPhone.isNetworkRoaming(); + + mDataConnected = mDataConnected + && (mSimState == IccCard.State.READY || mSimState == IccCard.State.UNKNOWN); + } + + if (DEBUG_SIGNAL || DEBUG) { + Slog.d(TAG, "updateDataState: connected=" + mDataConnected + + " level=" + mDataLevel + + " isEvdo=" + isEvdo() + + " isCdma=" + isCdma() + + " mPhoneState=" + mPhoneState + + " mDataState=" + mDataState + ); + } + + refreshSignalMeters(); + } + + private void updateWifiState(Intent intent) { + if (DEBUG) + Slog.d(TAG, "updateWifiState: " + intent); + + final String action = intent.getAction(); + final boolean wasConnected = mWifiConnected; + + if (action.equals(WifiManager.WIFI_STATE_CHANGED_ACTION)) { + mWifiEnabled = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, + WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED; + } else if (action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)) { + final NetworkInfo networkInfo = (NetworkInfo) + intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO); + mWifiConnected = networkInfo != null && networkInfo.isConnected(); + } else if (action.equals(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION)) { + final NetworkInfo.DetailedState detailedState = WifiInfo.getDetailedStateOf( + (SupplicantState)intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE)); + mWifiConnected = detailedState == NetworkInfo.DetailedState.CONNECTED; + } else if (action.equals(WifiManager.RSSI_CHANGED_ACTION)) { + final int newRssi = intent.getIntExtra(WifiManager.EXTRA_NEW_RSSI, -200); + int newSignalLevel = WifiManager.calculateSignalLevel(newRssi, 101); + mWifiLevel = mWifiConnected ? newSignalLevel : 0; + } + + if (mWifiConnected && !wasConnected) { + WifiInfo info = mWifiManager.getConnectionInfo(); + if (DEBUG) + Slog.d(TAG, "updateWifiState: just connected: info=" + info); + + if (info != null) { + // grab the initial signal strength + mWifiLevel = WifiManager.calculateSignalLevel(info.getRssi(), 101); + + // find the SSID + mWifiSsid = info.getSSID(); + if (mWifiSsid == null) { + // OK, it's not in the connectionInfo; we have to go hunting for it + List<WifiConfiguration> networks = mWifiManager.getConfiguredNetworks(); + for (WifiConfiguration net : networks) { + if (net.networkId == info.getNetworkId()) { + mWifiSsid = net.SSID; + break; + } + } + } + } + } + + refreshSignalMeters(); + } + + // figure out what to show: first wifi, then 3G, then nothing + void refreshSignalMeters() { + if (mSignalMeter == null) return; // no UI yet + + Context ctxt = getContext(); + + String text = null; + int level = 0; + + if (mWifiConnected) { + if (mWifiSsid == null) { + text = ctxt.getString(R.string.system_panel_signal_meter_wifi_nossid); + } else { + text = ctxt.getString(R.string.system_panel_signal_meter_wifi_ssid_format, + mWifiSsid); + } + level = mWifiLevel; + } else if (mDataConnected) { + text = ctxt.getString(R.string.system_panel_signal_meter_data_connected); + level = mDataLevel; + } else { + text = ctxt.getString(R.string.system_panel_signal_meter_disconnected); + level = 0; + } + + mSignalMeter.setImageResource(R.drawable.sysbar_signal); + mSignalMeter.setImageLevel(level); + mSignalText.setText(text); + + // hack for now + mBar.setSignalMeter(level, mWifiConnected); + } + + public void setBar(TabletStatusBarService bar) { + mBar = bar; + } + + public void updateBattery(Intent intent) { + final int level = intent.getIntExtra("level", 0); + final boolean plugged = intent.getIntExtra("plugged", 0) != 0; + + mBatteryMeter.setImageResource(R.drawable.sysbar_battery); + mBatteryMeter.setImageLevel(level); + mBatteryText.setText(getContext() + .getString(R.string.system_panel_battery_meter_format, level)); + + // hack for now + mBar.setBatteryMeter(level, plugged); + } + + public SystemPanel(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public SystemPanel(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + // get notified of phone state changes + TelephonyManager telephonyManager = + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE); + telephonyManager.listen(mPhoneStateListener, + PhoneStateListener.LISTEN_SERVICE_STATE + | PhoneStateListener.LISTEN_SIGNAL_STRENGTHS + | PhoneStateListener.LISTEN_CALL_STATE + | PhoneStateListener.LISTEN_DATA_CONNECTION_STATE + | PhoneStateListener.LISTEN_DATA_ACTIVITY); + + // wifi status info + mWifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE); + + // audio status + mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE); + + // mobile data + mPhone = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); + + // Bluetooth + mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); + } + + public void onAttachedToWindow() { + TextView settingsButton = (TextView)findViewById(R.id.settings_button); + settingsButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + getContext().startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS) + .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK)); + mBar.animateCollapse(); + }}); + + mBrightnessButton = (ImageButton)findViewById(R.id.brightness); + mBrightnessButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + rotateBrightness(); + } + }); + + mSoundButton = (ImageButton)findViewById(R.id.sound); + mSoundButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + setSilentMode(!getSilentMode()); + mSoundButton.setAlpha(getSilentMode() ? 0x7F : 0xFF); + } + }); + mOrientationButton = (ImageButton)findViewById(R.id.orientation); + mOrientationButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + Toast.makeText(getContext(), "Orientation control not implemented; please adjust neck angle.", Toast.LENGTH_SHORT).show(); + } + }); + + mAirplaneButton = (ImageButton)findViewById(R.id.airplane); + mAirplaneButton.setAlpha(mAirplaneMode ? 0xFF : 0x7F); + mAirplaneButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + boolean newMode = !getAirplaneMode(); + Toast.makeText(getContext(), "Attempting to turn " + + (newMode ? "on" : "off") + " airplane mode (flaky).", + Toast.LENGTH_SHORT).show(); + setAirplaneMode(newMode); + } + }); + + mGpsButton = (ImageButton)findViewById(R.id.gps); + mGpsButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + toggleGps(); + refreshGps(); + } + }); + + mBluetoothButton = (ImageButton)findViewById(R.id.bluetooth); + mBluetoothButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + toggleBluetooth(); + refreshBluetooth(); + } + }); + + // register for broadcasts + IntentFilter filter = new IntentFilter(); + filter.addAction(AudioManager.RINGER_MODE_CHANGED_ACTION); + filter.addAction(Intent.ACTION_BATTERY_CHANGED); + filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION); + filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION); + filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION); + filter.addAction(WifiManager.RSSI_CHANGED_ACTION); + filter.addAction(TelephonyIntents.ACTION_SIM_STATE_CHANGED); + filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); + getContext().registerReceiver(mReceiver, filter); + + mBatteryMeter = (ImageView)findViewById(R.id.battery_meter); + mBatteryMeter.setImageResource(R.drawable.sysbar_battery); + mBatteryMeter.setImageLevel(0); + mSignalMeter = (ImageView)findViewById(R.id.signal_meter); + mBatteryMeter.setImageResource(R.drawable.sysbar_signal); + mBatteryMeter.setImageLevel(0); + + mBatteryText = (TextView)findViewById(R.id.battery_info); + mSignalText = (TextView)findViewById(R.id.signal_info); + + refreshSignalMeters(); + refreshBluetooth(); + refreshGps(); + } + + public void onDetachedFromWindow() { + getContext().unregisterReceiver(mReceiver); + } + + // ---------------------------------------------------------------------- + +// private boolean isAutoBrightness() { +// Context context = getContext(); +// try { +// IPowerManager power = IPowerManager.Stub.asInterface( +// ServiceManager.getService("power")); +// if (power != null) { +// int brightnessMode = Settings.System.getInt(context.getContentResolver(), +// Settings.System.SCREEN_BRIGHTNESS_MODE); +// return brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; +// } +// } catch (RemoteException e) { +// } catch (Settings.SettingNotFoundException e) { +// } +// return false; +// } + + private void rotateBrightness() { + int icon = R.drawable.ic_sysbar_brightness; + int bg = R.drawable.sysbar_toggle_bg_on; + Context context = getContext(); + try { + IPowerManager power = IPowerManager.Stub.asInterface( + ServiceManager.getService("power")); + if (power != null) { + ContentResolver cr = context.getContentResolver(); + int brightness = Settings.System.getInt(cr, + Settings.System.SCREEN_BRIGHTNESS); + int brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; + //Only get brightness setting if available + if (context.getResources().getBoolean( + com.android.internal.R.bool.config_automatic_brightness_available)) { + brightnessMode = Settings.System.getInt(cr, + Settings.System.SCREEN_BRIGHTNESS_MODE); + } + + // Rotate AUTO -> MINIMUM -> DEFAULT -> MAXIMUM + // Technically, not a toggle... + if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC) { + brightness = MINIMUM_BACKLIGHT; + icon = R.drawable.ic_sysbar_brightness_low; + brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; + } else if (brightness < DEFAULT_BACKLIGHT) { + brightness = DEFAULT_BACKLIGHT; + } else if (brightness < MAXIMUM_BACKLIGHT) { + brightness = MAXIMUM_BACKLIGHT; + } else { + brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC; + brightness = MINIMUM_BACKLIGHT; + icon = R.drawable.ic_sysbar_brightness_auto; + } + + if (context.getResources().getBoolean( + com.android.internal.R.bool.config_automatic_brightness_available)) { + // Set screen brightness mode (automatic or manual) + Settings.System.putInt(context.getContentResolver(), + Settings.System.SCREEN_BRIGHTNESS_MODE, + brightnessMode); + } else { + // Make sure we set the brightness if automatic mode isn't available + brightnessMode = Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL; + } + if (brightnessMode == Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL) { + power.setBacklightBrightness(brightness); + Settings.System.putInt(cr, Settings.System.SCREEN_BRIGHTNESS, brightness); + } + } + } catch (RemoteException e) { + } catch (Settings.SettingNotFoundException e) { + } + + mBrightnessButton.setImageResource(icon); + mBrightnessButton.setBackgroundResource(bg); + } + + PhoneStateListener mPhoneStateListener = new PhoneStateListener() { + @Override + public void onServiceStateChanged(ServiceState serviceState) { + if (DEBUG_SIGNAL || DEBUG) { + Slog.d(TAG, "phone service state changed: " + serviceState.getState()); + } + mServiceState = serviceState; + mAirplaneMode = serviceState.getState() == ServiceState.STATE_POWER_OFF; + if (mAirplaneButton != null) { + mAirplaneButton.setImageResource(mAirplaneMode + ? R.drawable.ic_sysbar_airplane_on + : R.drawable.ic_sysbar_airplane_off); + mAirplaneButton.setBackgroundResource(mAirplaneMode + ? R.drawable.sysbar_toggle_bg_on + : R.drawable.sysbar_toggle_bg_off); + } + updateDataState(); + } + @Override + public void onSignalStrengthsChanged(SignalStrength signalStrength) { + if (DEBUG_SIGNAL || DEBUG) { + Slog.d(TAG, "onSignalStrengthsChanged: " + signalStrength); + } + mSignalStrength = signalStrength; + updateDataState(); + } + @Override + public void onCallStateChanged(int state, String incomingNumber) { + mPhoneState = state; + // In cdma, if a voice call is made, RSSI should switch to 1x. + if (isCdma()) { + updateDataState(); + } + } + + @Override + public void onDataConnectionStateChanged(int state, int networkType) { + if (DEBUG_SIGNAL || DEBUG) { + Slog.d(TAG, "onDataConnectionStateChanged: state=" + state + + " type=" + networkType); + } + mDataState = state; +// updateDataNetType(networkType); + updateDataState(); + } + }; + + private boolean getAirplaneMode() { + return mAirplaneMode; + } + + private void setAirplaneMode(boolean on) { + Settings.System.putInt( + mContext.getContentResolver(), + Settings.System.AIRPLANE_MODE_ON, + on ? 1 : 0); + Intent intent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED); + intent.addFlags(Intent.FLAG_RECEIVER_REPLACE_PENDING); + intent.putExtra("state", on); + getContext().sendBroadcast(intent); + } + + boolean getSilentMode() { + return mAudioManager.getRingerMode() != AudioManager.RINGER_MODE_NORMAL; + } + + void setSilentMode(boolean on) { + if (on) { + mAudioManager.setRingerMode((Settings.System.getInt(mContext.getContentResolver(), + Settings.System.VIBRATE_IN_SILENT, 1) == 1) + ? AudioManager.RINGER_MODE_VIBRATE + : AudioManager.RINGER_MODE_SILENT); + } else { + mAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); + } + } + + void refreshSound() { + boolean silent = getSilentMode(); + mSoundButton.setImageResource(!silent + ? R.drawable.ic_sysbar_sound_on + : R.drawable.ic_sysbar_sound_off); + mSoundButton.setBackgroundResource(!silent + ? R.drawable.sysbar_toggle_bg_on + : R.drawable.sysbar_toggle_bg_off); + } + + void toggleBluetooth() { + if (mBluetoothAdapter == null) return; + if (mBluetoothAdapter.isEnabled()) { + mBluetoothAdapter.disable(); + } else { + mBluetoothAdapter.enable(); + } + } + + void refreshBluetooth() { + boolean on = mBluetoothAdapter != null && mBluetoothAdapter.isEnabled(); + mBluetoothButton.setImageResource(on ? R.drawable.ic_sysbar_bluetooth_on + : R.drawable.ic_sysbar_bluetooth_off); + mBluetoothButton.setBackgroundResource(on + ? R.drawable.sysbar_toggle_bg_on + : R.drawable.sysbar_toggle_bg_off); + } + + private boolean isGpsEnabled() { + ContentResolver res = mContext.getContentResolver(); + return Settings.Secure.isLocationProviderEnabled( + res, LocationManager.GPS_PROVIDER); + } + + private void toggleGps() { + Settings.Secure.setLocationProviderEnabled(mContext.getContentResolver(), + LocationManager.GPS_PROVIDER, !isGpsEnabled()); + } + + private void refreshGps() { + boolean on = isGpsEnabled(); + mGpsButton.setImageResource(on ? R.drawable.ic_sysbar_gps_on + : R.drawable.ic_sysbar_gps_off); + mGpsButton.setBackgroundResource(on + ? R.drawable.sysbar_toggle_bg_on + : R.drawable.sysbar_toggle_bg_off); + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java new file mode 100644 index 0000000..0e26f52 --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarService.java @@ -0,0 +1,847 @@ +/* + * 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 android.app.ActivityManagerNative; +import android.app.PendingIntent; +import android.app.Notification; +import android.app.StatusBarManager; +import android.content.Context; +import android.content.Intent; +import android.content.res.Resources; +import android.graphics.PixelFormat; +import android.graphics.Rect; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.RemoteException; +import android.text.TextUtils; +import android.util.Slog; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewGroup; +import android.view.WindowManager; +import android.view.WindowManagerImpl; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.RemoteViews; +import android.widget.ScrollView; +import android.widget.TextSwitcher; +import android.widget.TextView; + +import com.android.internal.statusbar.StatusBarIcon; +import com.android.internal.statusbar.StatusBarNotification; + +import com.android.systemui.statusbar.*; +import com.android.systemui.recent.RecentApplicationsActivity; +import com.android.systemui.R; + +public class TabletStatusBarService extends StatusBarService { + public static final boolean DEBUG = false; + public static final String TAG = "TabletStatusBarService"; + + public static final int MSG_OPEN_NOTIFICATION_PANEL = 1000; + 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; + + private static final int MAX_IMAGE_LEVEL = 10000; + + int mIconSize; + + H mHandler = new H(); + + // tracking all current notifications + private NotificationData mNotns = new NotificationData(); + + TabletStatusBarView mStatusBarView; + View mNotificationTrigger; + NotificationIconArea mNotificationIconArea; + View mNotificationButtons; + View mSystemInfo; + View mNavigationArea; + + NotificationPanel mNotificationPanel; + SystemPanel mSystemPanel; + + ViewGroup mPile; + TextView mClearButton; + TextView mDoNotDisturbButton; + + ImageView mBatteryMeter; + ImageView mSignalMeter; + ImageView mSignalIcon; + + View mBarContents; + View mCurtains; + + NotificationIconArea.IconLayout mIconLayout; + + TabletTicker mTicker; + View mTickerView; + boolean mTicking; + + // for disabling the status bar + int mDisabled = 0; + + boolean mNotificationsOn = true; + + protected void addPanelWindows() { + final Resources res = getResources(); + final int barHeight= res.getDimensionPixelSize( + com.android.internal.R.dimen.status_bar_height); + + mNotificationPanel = (NotificationPanel)View.inflate(this, + R.layout.sysbar_panel_notifications, null); + mNotificationPanel.setVisibility(View.GONE); + mNotificationPanel.setOnTouchListener( + new TouchOutsideListener(MSG_CLOSE_NOTIFICATION_PANEL, mNotificationPanel)); + + mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel); + + WindowManager.LayoutParams lp = new WindowManager.LayoutParams( + 400, // 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("NotificationPanel"); + lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard; + + WindowManagerImpl.getDefault().addView(mNotificationPanel, lp); + + mSystemPanel = (SystemPanel) View.inflate(this, R.layout.sysbar_panel_system, null); + mSystemPanel.setVisibility(View.GONE); + mSystemPanel.setOnTouchListener(new TouchOutsideListener(MSG_CLOSE_SYSTEM_PANEL, + mSystemPanel)); + + mStatusBarView.setIgnoreChildren(1, mSystemInfo, mSystemPanel); + + lp = new WindowManager.LayoutParams( + 800, + 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.CENTER_HORIZONTAL; + lp.setTitle("SystemPanel"); + lp.windowAnimations = com.android.internal.R.style.Animation_SlidingCard; + + WindowManagerImpl.getDefault().addView(mSystemPanel, lp); + mSystemPanel.setBar(this); + } + + @Override + public void onCreate() { + super.onCreate(); // will add the main bar view + } + + protected View makeStatusBarView() { + Resources res = getResources(); + + mIconSize = res.getDimensionPixelSize(com.android.internal.R.dimen.status_bar_icon_size); + + final TabletStatusBarView sb = (TabletStatusBarView)View.inflate( + this, R.layout.status_bar, null); + mStatusBarView = sb; + + sb.setHandler(mHandler); + + mBarContents = sb.findViewById(R.id.bar_contents); + mCurtains = sb.findViewById(R.id.lights_out); + mSystemInfo = sb.findViewById(R.id.systemInfo); + + mSystemInfo.setOnLongClickListener(new SetLightsOnListener(false)); + + SetLightsOnListener on = new SetLightsOnListener(true); + mCurtains.setOnClickListener(on); + mCurtains.setOnLongClickListener(on); + + // the button to open the notification area + mNotificationTrigger = sb.findViewById(R.id.expand); + + // the more notifications icon + mNotificationIconArea = (NotificationIconArea)sb.findViewById(R.id.notificationIcons); + + // the clear and dnd buttons + mNotificationButtons = sb.findViewById(R.id.notificationButtons); + mClearButton = (TextView)mNotificationButtons.findViewById(R.id.clear_all_button); + mClearButton.setOnClickListener(mClearButtonListener); + mDoNotDisturbButton = (TextView)mNotificationButtons.findViewById(R.id.do_not_disturb); + mDoNotDisturbButton.setOnClickListener(mDoNotDisturbButtonListener); + + + // where the icons go + mIconLayout = (NotificationIconArea.IconLayout) sb.findViewById(R.id.icons); + + mTicker = new TabletTicker((Context)this, (FrameLayout)sb.findViewById(R.id.ticker)); + + // System info (center) + mBatteryMeter = (ImageView) sb.findViewById(R.id.battery); + mSignalMeter = (ImageView) sb.findViewById(R.id.signal); + mSignalIcon = (ImageView) sb.findViewById(R.id.signal_icon); + + // The navigation buttons + mNavigationArea = sb.findViewById(R.id.navigationArea); + + // set the initial view visibility + setAreThereNotifications(); + + // Add the windows + addPanelWindows(); + + mPile = (ViewGroup)mNotificationPanel.findViewById(R.id.content); + mPile.removeAllViews(); + + ScrollView scroller = (ScrollView)mPile.getParent(); + scroller.setFillViewport(true); + + return sb; + } + + protected int getStatusBarGravity() { + return Gravity.BOTTOM | Gravity.FILL_HORIZONTAL; + } + + private class H extends Handler { + public void handleMessage(Message m) { + switch (m.what) { + case MSG_OPEN_NOTIFICATION_PANEL: + if (DEBUG) Slog.d(TAG, "opening notifications panel"); + if (mNotificationPanel.getVisibility() == View.GONE) { + mDoNotDisturbButton.setText(mNotificationsOn + ? R.string.status_bar_do_not_disturb_button + : R.string.status_bar_please_disturb_button); + mNotificationPanel.setVisibility(View.VISIBLE); + setViewVisibility(mNotificationIconArea, View.GONE, + R.anim.notification_icons_out); + setViewVisibility(mNotificationButtons, View.VISIBLE, + R.anim.notification_buttons_in); + } + break; + case MSG_CLOSE_NOTIFICATION_PANEL: + if (DEBUG) Slog.d(TAG, "closing notifications panel"); + if (mNotificationPanel.getVisibility() == View.VISIBLE) { + mNotificationPanel.setVisibility(View.GONE); + setViewVisibility(mNotificationIconArea, View.VISIBLE, + R.anim.notification_icons_in); + setViewVisibility(mNotificationButtons, View.GONE, + R.anim.notification_buttons_out); + } + break; + case MSG_OPEN_SYSTEM_PANEL: + if (DEBUG) Slog.d(TAG, "opening system panel"); + mSystemPanel.setVisibility(View.VISIBLE); + break; + case MSG_CLOSE_SYSTEM_PANEL: + if (DEBUG) Slog.d(TAG, "closing system panel"); + mSystemPanel.setVisibility(View.GONE); + break; + } + } + } + + public void setBatteryMeter(int level, boolean plugged) { + if (DEBUG) Slog.d(TAG, "battery=" + level + (plugged ? " - plugged" : " - unplugged")); + mBatteryMeter.setImageResource(R.drawable.sysbar_batterymini); + // adjust percent to permyriad for ClipDrawable's sake + mBatteryMeter.setImageLevel(level * (MAX_IMAGE_LEVEL / 100)); + } + + public void setSignalMeter(int level, boolean isWifi) { + if (DEBUG) Slog.d(TAG, "signal=" + level); + if (level < 0) { + mSignalMeter.setImageDrawable(null); + mSignalMeter.setImageLevel(0); + mSignalIcon.setImageDrawable(null); + } else { + 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 + : R.drawable.ic_sysbar_wifi_mini); // XXX + } + } + + public void addIcon(String slot, int index, int viewIndex, StatusBarIcon icon) { + if (DEBUG) Slog.d(TAG, "addIcon(" + slot + ") -> " + icon); + } + + public void updateIcon(String slot, int index, int viewIndex, + StatusBarIcon old, StatusBarIcon icon) { + if (DEBUG) Slog.d(TAG, "updateIcon(" + slot + ") -> " + icon); + } + + public void removeIcon(String slot, int index, int viewIndex) { + if (DEBUG) Slog.d(TAG, "removeIcon(" + slot + ")"); + } + + public void addNotification(IBinder key, StatusBarNotification notification) { + if (DEBUG) Slog.d(TAG, "addNotification(" + key + " -> " + notification + ")"); + addNotificationViews(key, notification); + + boolean immersive = false; + try { + immersive = ActivityManagerNative.getDefault().isTopActivityImmersive(); + Slog.d(TAG, "Top activity is " + (immersive?"immersive":"not immersive")); + } catch (RemoteException ex) { + } + if (immersive) { + // TODO: immersive mode popups for tablet + } else if (notification.notification.fullScreenIntent != null) { + // not immersive & a full-screen alert should be shown + Slog.d(TAG, "Notification has fullScreenIntent and activity is not immersive;" + + " sending fullScreenIntent"); + try { + notification.notification.fullScreenIntent.send(); + } catch (PendingIntent.CanceledException e) { + } + } else { + tick(notification); + } + + setAreThereNotifications(); + } + + 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); + return; + } + + final StatusBarNotification oldNotification = oldEntry.notification; + final RemoteViews oldContentView = oldNotification.notification.contentView; + + final RemoteViews contentView = notification.notification.contentView; + + if (false) { + Slog.d(TAG, "old notification: when=" + oldNotification.notification.when + + " ongoing=" + oldNotification.isOngoing() + + " expanded=" + oldEntry.expanded + + " contentView=" + oldContentView); + Slog.d(TAG, "new notification: when=" + notification.notification.when + + " ongoing=" + oldNotification.isOngoing() + + " contentView=" + contentView); + } + + // Can we just reapply the RemoteViews in place? If when didn't change, the order + // didn't change. + if (notification.notification.when == oldNotification.notification.when + && notification.isOngoing() == oldNotification.isOngoing() + && oldEntry.expanded != null + && contentView != null + && oldContentView != null + && contentView.getPackage() != null + && oldContentView.getPackage() != null + && oldContentView.getPackage().equals(contentView.getPackage()) + && oldContentView.getLayoutId() == contentView.getLayoutId()) { + if (DEBUG) Slog.d(TAG, "reusing notification for key: " + key); + oldEntry.notification = notification; + try { + // Reapply the RemoteViews + contentView.reapply(this, oldEntry.content); + // update the contentIntent + final PendingIntent contentIntent = notification.notification.contentIntent; + if (contentIntent != null) { + oldEntry.content.setOnClickListener(new NotificationClicker(contentIntent, + notification.pkg, notification.tag, notification.id)); + } + // Update the icon. + final StatusBarIcon ic = new StatusBarIcon(notification.pkg, + notification.notification.icon, notification.notification.iconLevel, + notification.notification.number); + if (!oldEntry.icon.set(ic)) { + handleNotificationError(key, notification, "Couldn't update icon: " + ic); + return; + } + } + catch (RuntimeException e) { + // It failed to add cleanly. Log, and remove the view from the panel. + Slog.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e); + removeNotificationViews(key); + addNotificationViews(key, notification); + } + } else { + if (DEBUG) Slog.d(TAG, "not reusing notification for key: " + key); + removeNotificationViews(key); + addNotificationViews(key, notification); + } + // TODO: ticker; immersive mode + + setAreThereNotifications(); + } + + public void removeNotification(IBinder key) { + if (DEBUG) Slog.d(TAG, "removeNotification(" + key + ") // TODO"); + removeNotificationViews(key); + setAreThereNotifications(); + } + + public void disable(int state) { + int old = mDisabled; + int diff = state ^ old; + Slog.d(TAG, "disable... old=0x" + Integer.toHexString(old) + + " diff=0x" + Integer.toHexString(diff) + + " state=0x" + Integer.toHexString(state)); + mDisabled = state; + + // act accordingly + if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) { + if ((state & StatusBarManager.DISABLE_EXPAND) != 0) { + Slog.d(TAG, "DISABLE_EXPAND: yes"); + animateCollapse(); + } + } + if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) { + Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes"); + setViewVisibility(mNotificationTrigger, View.GONE, + R.anim.notification_icons_out); + setViewVisibility(mNotificationIconArea, View.GONE, + R.anim.notification_icons_out); + mTicker.halt(); + } else { + Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no"); + setViewVisibility(mNotificationTrigger, View.VISIBLE, + R.anim.notification_icons_in); + setViewVisibility(mNotificationIconArea, View.VISIBLE, + R.anim.notification_icons_in); + } + } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { + if ((state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) { + mTicker.halt(); + } + } + if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { + if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) { + Slog.d(TAG, "DISABLE_SYSTEM_INFO: yes"); + setViewVisibility(mSystemInfo, View.GONE, R.anim.navigation_out); + } else { + Slog.d(TAG, "DISABLE_SYSTEM_INFO: no"); + setViewVisibility(mSystemInfo, View.VISIBLE, R.anim.navigation_in); + } + } + if ((diff & StatusBarManager.DISABLE_NAVIGATION) != 0) { + if ((state & StatusBarManager.DISABLE_NAVIGATION) != 0) { + Slog.d(TAG, "DISABLE_NAVIGATION: yes"); + setViewVisibility(mNavigationArea, View.GONE, R.anim.navigation_out); + } else { + Slog.d(TAG, "DISABLE_NAVIGATION: no"); + setViewVisibility(mNavigationArea, View.VISIBLE, R.anim.navigation_in); + } + } + } + + private boolean hasTicker(Notification n) { + return !TextUtils.isEmpty(n.tickerText) + || !TextUtils.isEmpty(n.tickerTitle) + || !TextUtils.isEmpty(n.tickerSubtitle); + } + + private void tick(StatusBarNotification n) { + // Don't show the ticker when the windowshade is open. + if (mNotificationPanel.getVisibility() == View.VISIBLE) { + return; + } + // Show the ticker if one is requested. Also don't do this + // until status bar window is attached to the window manager, + // because... well, what's the point otherwise? And trying to + // run a ticker without being attached will crash! + if (hasTicker(n.notification) && mStatusBarView.getWindowToken() != null) { + if (0 == (mDisabled & (StatusBarManager.DISABLE_NOTIFICATION_ICONS + | StatusBarManager.DISABLE_NOTIFICATION_TICKER))) { + mTicker.add(n); + } + } + } + + public void animateExpand() { + mHandler.removeMessages(MSG_OPEN_NOTIFICATION_PANEL); + mHandler.sendEmptyMessage(MSG_OPEN_NOTIFICATION_PANEL); + } + + public void animateCollapse() { + mHandler.removeMessages(MSG_CLOSE_NOTIFICATION_PANEL); + mHandler.sendEmptyMessage(MSG_CLOSE_NOTIFICATION_PANEL); + mHandler.removeMessages(MSG_CLOSE_SYSTEM_PANEL); + mHandler.sendEmptyMessage(MSG_CLOSE_SYSTEM_PANEL); + } + + public void setLightsOn(boolean on) { + if (on) { + setViewVisibility(mCurtains, View.GONE, R.anim.lights_out_out); + setViewVisibility(mBarContents, View.VISIBLE, R.anim.status_bar_in); + } else { + animateCollapse(); + setViewVisibility(mCurtains, View.VISIBLE, R.anim.lights_out_in); + setViewVisibility(mBarContents, View.GONE, R.anim.status_bar_out); + } + } + + private void setAreThereNotifications() { + final boolean hasClearable = mNotns.hasClearableItems(); + + //Slog.d(TAG, "setAreThereNotifications hasClerable=" + hasClearable); + + // Show or hide the "Clear all" button. Note that we don't do an animation + // if it's not on screen, so that if someone opens the bar right then they + // don't see the animation in progress. + // (no ongoing notifications are clearable) + if (hasClearable) { + if (mNotificationButtons.getVisibility() == View.VISIBLE) { + setViewVisibility(mClearButton, View.VISIBLE, R.anim.notification_buttons_in); + } else { + mClearButton.setVisibility(View.VISIBLE); + } + } else { + if (mNotificationButtons.getVisibility() == View.VISIBLE) { + setViewVisibility(mClearButton, View.GONE, R.anim.notification_buttons_out); + } else { + mClearButton.setVisibility(View.GONE); + } + } + + /* + mOngoingTitle.setVisibility(ongoing ? View.VISIBLE : View.GONE); + mLatestTitle.setVisibility(latest ? View.VISIBLE : View.GONE); + + if (ongoing || latest) { + mNoNotificationsTitle.setVisibility(View.GONE); + } else { + mNoNotificationsTitle.setVisibility(View.VISIBLE); + } + */ + } + + public void notificationIconsClicked(View v) { + if (DEBUG) Slog.d(TAG, "clicked notification icons"); + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { + int msg = (mNotificationPanel.getVisibility() == View.GONE) + ? MSG_OPEN_NOTIFICATION_PANEL + : MSG_CLOSE_NOTIFICATION_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + } + + public void systemInfoClicked(View v) { + if (DEBUG) Slog.d(TAG, "clicked system info"); + if ((mDisabled & StatusBarManager.DISABLE_EXPAND) == 0) { + int msg = (mSystemPanel.getVisibility() == View.GONE) + ? MSG_OPEN_SYSTEM_PANEL + : MSG_CLOSE_SYSTEM_PANEL; + mHandler.removeMessages(msg); + mHandler.sendEmptyMessage(msg); + } + } + + public void recentButtonClicked(View v) { + if (DEBUG) Slog.d(TAG, "clicked recent apps"); + Intent intent = new Intent(); + intent.setClass(this, RecentApplicationsActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK + | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); + startActivity(intent); + } + + /** + * Cancel this notification and tell the status bar service about the failure. Hold no locks. + */ + void handleNotificationError(IBinder key, StatusBarNotification n, String message) { + removeNotification(key); + try { + mBarService.onNotificationError(n.pkg, n.tag, n.id, n.uid, n.initialPid, message); + } catch (RemoteException ex) { + // The end is nigh. + } + } + + private View.OnClickListener mClearButtonListener = new View.OnClickListener() { + public void onClick(View v) { + try { + mBarService.onClearAllNotifications(); + } catch (RemoteException ex) { + // system process is dead if we're here. + } + animateCollapse(); + } + }; + + private View.OnClickListener mDoNotDisturbButtonListener = new View.OnClickListener() { + public void onClick(View v) { + mNotificationsOn = !mNotificationsOn; + animateCollapse(); + } + }; + + private class NotificationClicker implements View.OnClickListener { + private PendingIntent mIntent; + private String mPkg; + private String mTag; + private int mId; + + NotificationClicker(PendingIntent intent, String pkg, String tag, int id) { + mIntent = intent; + mPkg = pkg; + mTag = tag; + mId = id; + } + + public void onClick(View v) { + try { + // The intent we are sending is for the application, which + // won't have permission to immediately start an activity after + // the user switches to home. We know it is safe to do at this + // point, so make sure new activity switches are now allowed. + ActivityManagerNative.getDefault().resumeAppSwitches(); + } catch (RemoteException e) { + } + + if (mIntent != null) { + int[] pos = new int[2]; + v.getLocationOnScreen(pos); + Intent overlay = new Intent(); + overlay.setSourceBounds( + new Rect(pos[0], pos[1], pos[0]+v.getWidth(), pos[1]+v.getHeight())); + try { + mIntent.send(TabletStatusBarService.this, 0, overlay); + } catch (PendingIntent.CanceledException e) { + // the stack trace isn't very helpful here. Just log the exception message. + Slog.w(TAG, "Sending contentIntent failed: " + e); + } + } + + try { + mBarService.onNotificationClick(mPkg, mTag, mId); + } catch (RemoteException ex) { + // system process is dead if we're here. + } + + // close the shade if it was open + animateCollapse(); + + // If this click was on the intruder alert, hide that instead +// mHandler.sendEmptyMessage(MSG_HIDE_INTRUDER); + } + } + + StatusBarNotification removeNotificationViews(IBinder key) { + NotificationData.Entry entry = mNotns.remove(key); + if (entry == null) { + Slog.w(TAG, "removeNotification for unknown key: " + key); + return null; + } + // Remove the expanded view. + ViewGroup rowParent = (ViewGroup)entry.row.getParent(); + if (rowParent != null) rowParent.removeView(entry.row); + // Remove the icon. +// ViewGroup iconParent = (ViewGroup)entry.icon.getParent(); +// if (iconParent != null) iconParent.removeView(entry.icon); + refreshIcons(); + + return entry.notification; + } + + StatusBarIconView addNotificationViews(IBinder key, StatusBarNotification notification) { + if (DEBUG) { + Slog.d(TAG, "addNotificationViews(key=" + key + ", notification=" + notification); + } + // Construct the icon. + final StatusBarIconView iconView = new StatusBarIconView(this, + notification.pkg + "/0x" + Integer.toHexString(notification.id)); + iconView.setScaleType(ImageView.ScaleType.CENTER_INSIDE); + + final StatusBarIcon ic = new StatusBarIcon(notification.pkg, + notification.notification.icon, + notification.notification.iconLevel, + notification.notification.number); + if (!iconView.set(ic)) { + handleNotificationError(key, notification, "Couldn't attach StatusBarIcon: " + ic); + return null; + } + // Construct the expanded view. + NotificationData.Entry entry = new NotificationData.Entry(key, notification, iconView); + if (!inflateViews(entry, mPile)) { + handleNotificationError(key, notification, "Couldn't expand RemoteViews for: " + + notification); + return null; + } + // Add the icon. + mNotns.add(entry); + refreshIcons(); + + return iconView; + } + + private void refreshIcons() { + // XXX: need to implement a new limited linear layout class + // to avoid removing & readding everything + + int N = mNotns.size(); + LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(mIconSize, mIconSize); + + if (DEBUG) { + Slog.d(TAG, "refreshing icons (" + N + " notifications, mIconLayout=" + + mIconLayout + ", mPile=" + mPile); + } + + mIconLayout.removeAllViews(); + for (int i=0; i<4; i++) { + if (i>=N) break; + mIconLayout.addView(mNotns.get(N-i-1).icon, i, params); + } + + mPile.removeAllViews(); + for (int i=0; i<N; i++) { + mPile.addView(mNotns.get(N-i-1).row); + } + } + + private boolean inflateViews(NotificationData.Entry entry, ViewGroup parent) { + StatusBarNotification sbn = entry.notification; + RemoteViews remoteViews = sbn.notification.contentView; + if (remoteViews == null) { + return false; + } + + // create the row view + LayoutInflater inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE); + View row = inflater.inflate(R.layout.status_bar_latest_event, parent, false); + View vetoButton = row.findViewById(R.id.veto); + if (entry.notification.isClearable()) { + final String _pkg = sbn.pkg; + final String _tag = sbn.tag; + final int _id = sbn.id; + vetoButton.setOnClickListener(new View.OnClickListener() { + public void onClick(View v) { + try { + mBarService.onNotificationClear(_pkg, _tag, _id); + } catch (RemoteException ex) { + // system process is dead if we're here. + } + // animateCollapse(); + } + }); + } else { + vetoButton.setVisibility(View.INVISIBLE); + } + + // bind the click event to the content area + ViewGroup content = (ViewGroup)row.findViewById(R.id.content); + // XXX: update to allow controls within notification views + content.setDescendantFocusability(ViewGroup.FOCUS_BLOCK_DESCENDANTS); +// content.setOnFocusChangeListener(mFocusChangeListener); + PendingIntent contentIntent = sbn.notification.contentIntent; + if (contentIntent != null) { + content.setOnClickListener(new NotificationClicker(contentIntent, + sbn.pkg, sbn.tag, sbn.id)); + } + + View expanded = null; + Exception exception = null; + try { + expanded = remoteViews.apply(this, content); + } + catch (RuntimeException e) { + exception = e; + } + if (expanded == null) { + String ident = sbn.pkg + "/0x" + Integer.toHexString(sbn.id); + Slog.e(TAG, "couldn't inflate view for notification " + ident, exception); + return false; + } else { + content.addView(expanded); + row.setDrawingCacheEnabled(true); + } + + entry.row = row; + entry.content = content; + entry.expanded = expanded; + + return true; + } + + public class SetLightsOnListener implements View.OnLongClickListener, + View.OnClickListener { + private boolean mOn; + + SetLightsOnListener(boolean on) { + mOn = on; + } + + public void onClick(View v) { + try { + mBarService.setLightsOn(mOn); + } catch (RemoteException ex) { + // system process + } + } + + public boolean onLongClick(View v) { + try { + mBarService.setLightsOn(mOn); + } catch (RemoteException ex) { + // system process + } + return true; + } + + } + + public class TouchOutsideListener implements View.OnTouchListener { + private int mMsg; + private StatusBarPanel mPanel; + + public TouchOutsideListener(int msg, StatusBarPanel panel) { + mMsg = msg; + mPanel = panel; + } + + public boolean onTouch(View v, MotionEvent ev) { + final int action = ev.getAction(); + if (action == MotionEvent.ACTION_OUTSIDE + || (action == MotionEvent.ACTION_DOWN + && !mPanel.isInContentArea((int)ev.getX(), (int)ev.getY()))) { + mHandler.removeMessages(mMsg); + mHandler.sendEmptyMessage(mMsg); + return true; + } + return false; + } + } + + private void setViewVisibility(View v, int vis, int anim) { + if (v.getVisibility() != vis) { + //Slog.d(TAG, "setViewVisibility vis=" + (vis == View.VISIBLE) + " v=" + v); + v.setAnimation(AnimationUtils.loadAnimation((Context)this, anim)); + v.setVisibility(vis); + } + } +} + + diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java new file mode 100644 index 0000000..d836e4a --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBarView.java @@ -0,0 +1,83 @@ +/* + * 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 android.content.Context; +import android.os.Handler; +import android.util.AttributeSet; +import android.view.View; +import android.view.MotionEvent; +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 int[] mPos = new int[2]; + + public TabletStatusBarView(Context context) { + super(context); + } + + public TabletStatusBarView(Context context, AttributeSet attrs) { + super(context, attrs); + } + + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (ev.getAction() == MotionEvent.ACTION_DOWN) { + mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_NOTIFICATION_PANEL); + mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_NOTIFICATION_PANEL); + mHandler.removeMessages(TabletStatusBarService.MSG_CLOSE_SYSTEM_PANEL); + mHandler.sendEmptyMessage(TabletStatusBarService.MSG_CLOSE_SYSTEM_PANEL); + + for (int i=0; i<mPanels.length; i++) { + if (mPanels[i].getVisibility() == View.VISIBLE) { + if (eventInside(mIgnoreChildren[i], ev)) { + return true; + } + } + } + } + return super.onInterceptTouchEvent(ev); + } + + private boolean eventInside(View v, MotionEvent ev) { + // assume that x and y are window coords because we are. + final int x = (int)ev.getX(); + final int y = (int)ev.getY(); + + final int[] p = mPos; + v.getLocationInWindow(p); + + final int l = p[0]; + final int t = p[1]; + final int r = p[0] + v.getWidth(); + final int b = p[1] + v.getHeight(); + + return x >= l && x < r && y >= t && y < b; + } + + public void setHandler(Handler h) { + mHandler = h; + } + + public void setIgnoreChildren(int index, View ignore, View panel) { + mIgnoreChildren[index] = ignore; + mPanels[index] = panel; + } +} diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java new file mode 100644 index 0000000..3c3139f --- /dev/null +++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletTicker.java @@ -0,0 +1,179 @@ +/* + * 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 android.app.Notification; +import android.content.Context; +import android.graphics.Bitmap; +import android.os.Handler; +import android.os.Message; +import android.util.Slog; +import android.view.Gravity; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.android.internal.statusbar.StatusBarNotification; + +import com.android.systemui.R; + +import java.util.Arrays; + +public class TabletTicker extends Handler { + private static final String TAG = "StatusBar.TabletTicker"; + + private static final int MSG_ADVANCE = 1; + + private static final int ADVANCE_DELAY = 5000; // 5 seconds + + private Context mContext; + private FrameLayout mParent; + + private StatusBarNotification mCurrentNotification; + private View mCurrentView; + + private StatusBarNotification[] mQueue; + private int mQueuePos; + + public TabletTicker(Context context, FrameLayout parent) { + mContext = context; + mParent = parent; + + // TODO: Make this a configuration value. + // 3 is enough to let us see most cases, but not get so far behind that it's annoying. + mQueue = new StatusBarNotification[3]; + } + + public void add(StatusBarNotification notification) { + if (false) { + Slog.d(TAG, "add mCurrentNotification=" + mCurrentNotification + + " mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue)); + } + mQueue[mQueuePos] = notification; + + // If nothing is running now, start the next one + if (mCurrentNotification == null) { + sendEmptyMessage(MSG_ADVANCE); + } + + if (mQueuePos < mQueue.length - 1) { + mQueuePos++; + } + } + + public void halt() { + removeMessages(MSG_ADVANCE); + if (mCurrentView != null) { + final int N = mQueue.length; + for (int i=0; i<N; i++) { + mQueue[i] = null; + } + mQueuePos = 0; + sendEmptyMessage(MSG_ADVANCE); + } + } + + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_ADVANCE: + advance(); + break; + } + } + + private void advance() { + // Out with the old... + if (mCurrentView != null) { + mParent.removeView(mCurrentView); + mCurrentView = null; + mCurrentNotification = null; + } + + // In with the new... + final StatusBarNotification next = dequeue(); + if (next != null) { + mCurrentNotification = next; + mCurrentView = makeTickerView(next); + mParent.addView(mCurrentView); + sendEmptyMessageDelayed(MSG_ADVANCE, ADVANCE_DELAY); + } + } + + private StatusBarNotification dequeue() { + StatusBarNotification notification = mQueue[0]; + if (false) { + Slog.d(TAG, "dequeue mQueuePos=" + mQueuePos + " mQueue=" + Arrays.toString(mQueue)); + } + final int N = mQueuePos; + for (int i=0; i<N; i++) { + mQueue[i] = mQueue[i+1]; + } + mQueue[N] = null; + if (mQueuePos > 0) { + mQueuePos--; + } + return notification; + } + + private View makeTickerView(StatusBarNotification notification) { + final Notification n = notification.notification; + + LayoutInflater inflater = (LayoutInflater)mContext.getSystemService( + Context.LAYOUT_INFLATER_SERVICE); + + int layoutId; + ViewGroup group; + if (n.tickerTitle != null || n.tickerSubtitle != null) { + group = (ViewGroup)inflater.inflate(R.layout.ticker, mParent, false); + if (n.tickerTitle != null) { + final TextView title = (TextView)group.findViewById(R.id.title); + title.setText(n.tickerTitle); + } + if (n.tickerSubtitle != null) { + final TextView subtitle = (TextView)group.findViewById(R.id.subtitle); + subtitle.setText(n.tickerSubtitle); + } + } else { + group = (ViewGroup)inflater.inflate(R.layout.ticker_compat, mParent, false); + TextView tv = (TextView)group.findViewById(R.id.text); + tv.setText(n.tickerText); + } + + // No more than 2 icons. + if (n.tickerIcons != null) { + int N = n.tickerIcons.length; + if (N > 2) { + N = 2; + } + for (int i=N-1; i>= 0; i--) { + Bitmap b = n.tickerIcons[i]; + if (b != null) { + ImageView iv = (ImageView)inflater.inflate(R.layout.ticker_icon, group, false); + iv.setImageBitmap(b); + group.addView(iv, 0); + } + } + } + + return group; + } +} + |