summaryrefslogtreecommitdiffstats
path: root/packages
diff options
context:
space:
mode:
Diffstat (limited to 'packages')
-rw-r--r--packages/Keyguard/res/layout/keyguard_bouncer.xml6
-rw-r--r--packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml1
-rw-r--r--packages/Keyguard/res/layout/keyguard_pin_view.xml52
-rw-r--r--packages/Keyguard/res/layout/keyguard_status_view.xml3
-rw-r--r--packages/Keyguard/res/values-sw600dp-land/dimens.xml1
-rw-r--r--packages/Keyguard/res/values-sw600dp/dimens.xml2
-rw-r--r--packages/Keyguard/res/values/dimens.xml4
-rw-r--r--packages/Keyguard/res/values/strings.xml4
-rw-r--r--packages/Keyguard/res/values/styles.xml2
-rw-r--r--packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java99
-rw-r--r--packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java8
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java5
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java4
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java4
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java47
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java60
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java7
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java7
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java4
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java5
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java8
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java5
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java8
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java8
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java2
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java8
-rw-r--r--packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java12
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_lock_24dp.pngbin385 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.pngbin5533 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.pngbin3270 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.pngbin3361 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/search_light.pngbin685 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-hdpi/search_light_land.pngbin695 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_lock_24dp.pngbin297 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.pngbin3699 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.pngbin1936 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.pngbin1849 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/search_light.pngbin537 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-mdpi/search_light_land.pngbin555 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.pngbin504 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.pngbin4767 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.pngbin4506 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.pngbin2650 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.pngbin2528 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.pngbin1391 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.pngbin6316 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.pngbin5734 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.pngbin1207 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.pngbin8622 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.pngbin7491 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_lock_24dp.pngbin471 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_lock_open_24dp.pngbin1007 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.pngbin7546 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.pngbin4390 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.pngbin4340 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/search_light.pngbin939 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xhdpi/search_light_land.pngbin959 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxhdpi/ic_lock_24dp.pngbin629 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.pngbin7494 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.pngbin6225 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.pngbin5571 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxhdpi/search_light.pngbin3651 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxhdpi/search_light_land.pngbin2356 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxxhdpi/ic_lock_24dp.pngbin825 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable-xxxhdpi/ic_lock_open_24dp.pngbin828 -> 0 bytes
-rw-r--r--packages/SystemUI/res/drawable/ic_account_circle.xml28
-rw-r--r--packages/SystemUI/res/drawable/ic_lock_24dp.xml28
-rw-r--r--packages/SystemUI/res/drawable/ic_lock_open_24dp.xml28
-rw-r--r--packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml2
-rw-r--r--packages/SystemUI/res/drawable/ic_ringer_audible.xml28
-rw-r--r--packages/SystemUI/res/drawable/ic_ringer_silent.xml28
-rw-r--r--packages/SystemUI/res/drawable/ic_ringer_vibrate.xml28
-rw-r--r--packages/SystemUI/res/drawable/ic_vol_zen_off.xml30
-rw-r--r--packages/SystemUI/res/drawable/ic_vol_zen_on.xml28
-rw-r--r--packages/SystemUI/res/drawable/notification_header_bg.xml2
-rw-r--r--packages/SystemUI/res/drawable/qs_panel_background.xml13
-rw-r--r--packages/SystemUI/res/drawable/ripple_drawable.xml21
-rw-r--r--packages/SystemUI/res/layout-ldrtl/navigation_bar.xml42
-rw-r--r--packages/SystemUI/res/layout-sw600dp/heads_up.xml30
-rw-r--r--packages/SystemUI/res/layout-sw600dp/navigation_bar.xml42
-rw-r--r--packages/SystemUI/res/layout/heads_up.xml46
-rw-r--r--packages/SystemUI/res/layout/keyguard_bottom_area.xml23
-rw-r--r--packages/SystemUI/res/layout/navigation_bar.xml49
-rw-r--r--packages/SystemUI/res/layout/qs_detail.xml (renamed from packages/SystemUI/res/layout/qs_zen_mode_detail.xml)52
-rw-r--r--packages/SystemUI/res/layout/qs_panel.xml5
-rw-r--r--packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml3
-rw-r--r--packages/SystemUI/res/layout/recents_task_view.xml23
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded.xml7
-rw-r--r--packages/SystemUI/res/layout/status_bar_expanded_header.xml25
-rw-r--r--packages/SystemUI/res/layout/super_status_bar.xml8
-rw-r--r--packages/SystemUI/res/layout/user_switcher_host.xml2
-rw-r--r--packages/SystemUI/res/layout/volume_panel.xml68
-rw-r--r--packages/SystemUI/res/layout/volume_panel_item.xml42
-rw-r--r--packages/SystemUI/res/layout/zen_mode_condition.xml (renamed from packages/SystemUI/res/layout/qs_zen_mode_detail_condition.xml)37
-rw-r--r--packages/SystemUI/res/layout/zen_mode_panel.xml53
-rw-r--r--packages/SystemUI/res/values-sw600dp/dimens.xml4
-rw-r--r--packages/SystemUI/res/values/attrs.xml8
-rw-r--r--packages/SystemUI/res/values/colors.xml6
-rw-r--r--packages/SystemUI/res/values/config.xml7
-rw-r--r--packages/SystemUI/res/values/dimens.xml23
-rw-r--r--packages/SystemUI/res/values/strings.xml23
-rw-r--r--packages/SystemUI/res/values/styles.xml30
-rw-r--r--packages/SystemUI/src/com/android/systemui/SwipeHelper.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/SystemUIApplication.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSPanel.java14
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTile.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/QSTileView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java168
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/RingerModeTile.java108
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeDetail.java273
-rw-r--r--packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeTile.java87
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/Constants.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java20
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/RecentsService.java10
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java12
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java4
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java62
-rw-r--r--packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java27
-rw-r--r--packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java1
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/AlphaImageView.java48
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java291
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java96
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java11
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java69
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java6
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java106
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java28
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java9
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java398
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java51
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java300
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java22
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java73
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java148
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java21
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java193
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java35
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java23
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java222
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java107
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java73
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java144
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java2
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java5
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java64
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java101
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java66
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java8
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java24
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java369
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java57
-rw-r--r--packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java248
166 files changed, 3717 insertions, 1978 deletions
diff --git a/packages/Keyguard/res/layout/keyguard_bouncer.xml b/packages/Keyguard/res/layout/keyguard_bouncer.xml
index 975a139..489c5f5 100644
--- a/packages/Keyguard/res/layout/keyguard_bouncer.xml
+++ b/packages/Keyguard/res/layout/keyguard_bouncer.xml
@@ -18,12 +18,6 @@
android:layout_width="match_parent"
android:layout_height="match_parent">
- <View android:id="@+id/bouncer_background"
- android:background="#cc000000"
- android:clickable="true"
- android:layout_width="match_parent"
- android:layout_height="match_parent"/>
-
<include
style="@style/BouncerSecurityContainer"
layout="@layout/keyguard_simple_host_view"
diff --git a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
index b2d0219..78b5746 100644
--- a/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
+++ b/packages/Keyguard/res/layout/keyguard_emergency_carrier_area.xml
@@ -37,6 +37,7 @@
android:textAppearance="?android:attr/textAppearanceMedium"
android:textSize="@dimen/kg_status_line_font_size"
android:textColor="?android:attr/textColorSecondary"
+ android:visibility="gone"
androidprv:allCaps="@bool/kg_use_all_caps" />
<LinearLayout
diff --git a/packages/Keyguard/res/layout/keyguard_pin_view.xml b/packages/Keyguard/res/layout/keyguard_pin_view.xml
index a804c8c..a8e330b 100644
--- a/packages/Keyguard/res/layout/keyguard_pin_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_pin_view.xml
@@ -41,28 +41,16 @@
android:layout_weight="1"
android:layoutDirection="ltr"
>
- <LinearLayout
+ <RelativeLayout
+ android:id="@+id/row0"
android:layout_width="match_parent"
android:layout_height="0dp"
- android:orientation="horizontal"
android:layout_weight="1"
>
- <TextView android:id="@+id/pinEntry"
- android:editable="true"
- android:layout_width="0dip"
- android:layout_height="match_parent"
- android:layout_weight="1"
- android:gravity="center"
- android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
- android:singleLine="true"
- android:cursorVisible="false"
- android:background="@null"
- android:textAppearance="@style/TextAppearance.NumPadKey"
- android:imeOptions="flagForceAscii|actionDone"
- />
- <ImageButton android:id="@+id/delete_button"
+ <ImageButton android:id="@+id/delete_button"
android:layout_width="wrap_content"
android:layout_height="match_parent"
+ android:layout_alignParentEnd="true"
android:gravity="center_vertical"
android:src="@drawable/ic_input_delete"
android:clickable="true"
@@ -73,13 +61,30 @@
android:background="?android:attr/selectableItemBackground"
android:contentDescription="@string/keyboardview_keycode_delete"
/>
- </LinearLayout>
- <View
- android:layout_width="wrap_content"
- android:layout_height="1dp"
- android:background="#55FFFFFF"
- />
+ <TextView android:id="@+id/pinEntry"
+ android:editable="true"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_toStartOf="@+id/delete_button"
+ android:layout_alignParentStart="true"
+ android:gravity="center"
+ android:layout_marginStart="@dimen/keyguard_lockscreen_pin_margin_left"
+ android:singleLine="true"
+ android:cursorVisible="false"
+ android:background="@null"
+ android:textAppearance="@style/TextAppearance.NumPadKey"
+ android:imeOptions="flagForceAscii|actionDone"
+ />
+ <View
+ android:id="@+id/divider"
+ android:layout_width="match_parent"
+ android:layout_height="1dp"
+ android:layout_alignParentBottom="true"
+ android:background="#55FFFFFF"
+ />
+ </RelativeLayout>
<LinearLayout
+ android:id="@+id/row1"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
@@ -114,6 +119,7 @@
/>
</LinearLayout>
<LinearLayout
+ android:id="@+id/row2"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
@@ -148,6 +154,7 @@
/>
</LinearLayout>
<LinearLayout
+ android:id="@+id/row3"
android:layout_width="match_parent"
android:layout_height="0dp"
android:orientation="horizontal"
@@ -182,6 +189,7 @@
/>
</LinearLayout>
<LinearLayout
+ android:id="@+id/row4"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
diff --git a/packages/Keyguard/res/layout/keyguard_status_view.xml b/packages/Keyguard/res/layout/keyguard_status_view.xml
index f79819f..112e371 100644
--- a/packages/Keyguard/res/layout/keyguard_status_view.xml
+++ b/packages/Keyguard/res/layout/keyguard_status_view.xml
@@ -39,13 +39,12 @@
android:id="@+id/clock_view"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:layout_gravity="center_horizontal|top"
+ android:layout_gravity="center_horizontal"
android:textColor="@color/clock_white"
android:singleLine="true"
style="@style/widget_big_thin"
android:format12Hour="@string/keyguard_widget_12_hours_format"
android:format24Hour="@string/keyguard_widget_24_hours_format"
- android:baselineAligned="true"
android:layout_marginBottom="@dimen/bottom_text_spacing_digital" />
<include layout="@layout/keyguard_status_area" />
diff --git a/packages/Keyguard/res/values-sw600dp-land/dimens.xml b/packages/Keyguard/res/values-sw600dp-land/dimens.xml
index 5615ff7..13a6f62 100644
--- a/packages/Keyguard/res/values-sw600dp-land/dimens.xml
+++ b/packages/Keyguard/res/values-sw600dp-land/dimens.xml
@@ -26,5 +26,4 @@
<!-- Overload default clock widget parameters -->
<dimen name="widget_big_font_size">88dp</dimen>
- <dimen name="bottom_text_spacing_digital">-24dp</dimen>
</resources> \ No newline at end of file
diff --git a/packages/Keyguard/res/values-sw600dp/dimens.xml b/packages/Keyguard/res/values-sw600dp/dimens.xml
index a5e93dc..b954792 100644
--- a/packages/Keyguard/res/values-sw600dp/dimens.xml
+++ b/packages/Keyguard/res/values-sw600dp/dimens.xml
@@ -65,7 +65,7 @@
<!-- Overload default clock widget parameters -->
<dimen name="widget_big_font_size">96dp</dimen>
<dimen name="widget_label_font_size">16sp</dimen>
- <dimen name="bottom_text_spacing_digital">-24dp</dimen>
+ <dimen name="bottom_text_spacing_digital">-8dp</dimen>
<!-- EmergencyCarrierArea overlap - amount to overlap the emergency button and carrier text.
Should be 0 on devices with plenty of room (e.g. tablets) -->
diff --git a/packages/Keyguard/res/values/dimens.xml b/packages/Keyguard/res/values/dimens.xml
index 6224aed..01d9ab3 100644
--- a/packages/Keyguard/res/values/dimens.xml
+++ b/packages/Keyguard/res/values/dimens.xml
@@ -155,10 +155,12 @@
<dimen name="eca_overlap">-10dip</dimen>
<!-- Default clock parameters -->
- <dimen name="bottom_text_spacing_digital">-18dp</dimen>
+ <dimen name="bottom_text_spacing_digital">-6dp</dimen>
<dimen name="label_font_size">14dp</dimen>
<dimen name="widget_label_font_size">14sp</dimen>
<dimen name="widget_big_font_size">68dp</dimen>
<dimen name="big_font_size">120dp</dimen>
+ <!-- The y translation to apply at the start in appear animations. -->
+ <dimen name="appear_y_translation_start">24dp</dimen>
</resources>
diff --git a/packages/Keyguard/res/values/strings.xml b/packages/Keyguard/res/values/strings.xml
index d20b269..8cf07fa 100644
--- a/packages/Keyguard/res/values/strings.xml
+++ b/packages/Keyguard/res/values/strings.xml
@@ -97,9 +97,9 @@
<string name="keyguard_sim_unlock_progress_dialog_message">Unlocking SIM card\u2026</string>
<!-- Time format strings for fall-back clock widget -->
- <string name="keyguard_widget_12_hours_format" translatable="false">h&#58;mm</string>
+ <string name="keyguard_widget_12_hours_format" translatable="false">h\uee01mm</string>
<!-- Time format strings for fall-back clock widget -->
- <string name="keyguard_widget_24_hours_format" translatable="false">kk&#58;mm</string>
+ <string name="keyguard_widget_24_hours_format" translatable="false">kk\uee01mm</string>
<!-- Accessibility description sent when user changes the current lock screen widget. [CHAR_LIMIT=none] -->
<string name="keyguard_accessibility_widget_changed">%1$s. Widget %2$d of %3$d.</string>
diff --git a/packages/Keyguard/res/values/styles.xml b/packages/Keyguard/res/values/styles.xml
index 5ab00d2..11142cf 100644
--- a/packages/Keyguard/res/values/styles.xml
+++ b/packages/Keyguard/res/values/styles.xml
@@ -59,8 +59,6 @@
<!-- Built-in clock widget stuff -->
<style name="widget_label">
- <item name="android:textStyle">bold</item>
- <item name="android:fontFamily">sans-serif-light</item>
<item name="android:textSize">@dimen/widget_label_font_size</item>
</style>
<style name="big_thin">
diff --git a/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java b/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java
new file mode 100644
index 0000000..ea896d5
--- /dev/null
+++ b/packages/Keyguard/src/com/android/keyguard/AppearAnimationUtils.java
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2014 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.keyguard;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.TimeInterpolator;
+import android.content.Context;
+import android.view.View;
+import android.view.ViewPropertyAnimator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+
+/**
+ * A class to make nice appear transitions for views in a tabular layout.
+ */
+public class AppearAnimationUtils {
+
+ public static final long APPEAR_DURATION = 220;
+
+ private final Interpolator mLinearOutSlowIn;
+ private final float mStartTranslation;
+
+ public AppearAnimationUtils(Context ctx) {
+ mLinearOutSlowIn = AnimationUtils.loadInterpolator(
+ ctx, android.R.interpolator.linear_out_slow_in);
+ mStartTranslation =
+ ctx.getResources().getDimensionPixelOffset(R.dimen.appear_y_translation_start);
+ }
+
+ public void startAppearAnimation(View[][] views, final Runnable finishListener) {
+ long maxDelay = 0;
+ ViewPropertyAnimator maxDelayAnimator = null;
+ for (int row = 0; row < views.length; row++) {
+ View[] columns = views[row];
+ for (int col = 0; col < columns.length; col++) {
+ long delay = calculateDelay(row, col);
+ ViewPropertyAnimator animator = startAppearAnimation(columns[col], delay);
+ if (animator != null && delay > maxDelay) {
+ maxDelay = delay;
+ maxDelayAnimator = animator;
+ }
+ }
+ }
+ if (maxDelayAnimator != null) {
+ maxDelayAnimator.setListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ finishListener.run();
+ }
+ });
+ } else {
+ finishListener.run();
+ }
+ }
+
+ private ViewPropertyAnimator startAppearAnimation(View view, long delay) {
+ if (view == null) return null;
+ view.setAlpha(0f);
+ view.setTranslationY(mStartTranslation);
+ view.animate()
+ .alpha(1f)
+ .translationY(0)
+ .setInterpolator(mLinearOutSlowIn)
+ .setDuration(APPEAR_DURATION)
+ .setStartDelay(delay)
+ .setListener(null);
+ if (view.hasOverlappingRendering()) {
+ view.animate().withLayer();
+ }
+ return view.animate();
+ }
+
+ private long calculateDelay(int row, int col) {
+ return (long) (row * 40 + col * (Math.pow(row, 0.4) + 0.4) * 20);
+ }
+
+ public TimeInterpolator getInterpolator() {
+ return mLinearOutSlowIn;
+ }
+
+ public float getStartTranslation() {
+ return mStartTranslation;
+ }
+}
diff --git a/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java b/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java
index 6d392fc..a592db9 100644
--- a/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/EmergencyCarrierArea.java
@@ -17,13 +17,12 @@
package com.android.keyguard;
import android.content.Context;
+import android.content.res.TypedArray;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.widget.LinearLayout;
-import com.android.keyguard.R;
-
public class EmergencyCarrierArea extends LinearLayout {
private CarrierText mCarrierText;
@@ -48,6 +47,7 @@ public class EmergencyCarrierArea extends LinearLayout {
mEmergencyButton.setOnTouchListener(new OnTouchListener(){
@Override
public boolean onTouch(View v, MotionEvent event) {
+ if (mCarrierText.getVisibility() != View.VISIBLE) return false;
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
mCarrierText.animate().alpha(0);
@@ -59,4 +59,8 @@ public class EmergencyCarrierArea extends LinearLayout {
return false;
}});
}
+
+ public void setCarrierTextVisible(boolean visible) {
+ mCarrierText.setVisibility(visible ? View.VISIBLE : View.GONE);
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
index f69fa5f..69abc7a 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardAccountView.java
@@ -328,5 +328,10 @@ public class KeyguardAccountView extends LinearLayout implements KeyguardSecurit
@Override
public void hideBouncer(int duration) {
}
+
+ @Override
+ public void startAppearAnimation() {
+ // TODO.
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java
index 701d15f..c9fe93c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardFaceUnlockView.java
@@ -349,4 +349,8 @@ public class KeyguardFaceUnlockView extends LinearLayout implements KeyguardSecu
hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
}
+ @Override
+ public void startAppearAnimation() {
+ // TODO.
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
index 2685447..d2bf30c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardHostView.java
@@ -112,7 +112,9 @@ public class KeyguardHostView extends KeyguardViewBase {
}
public interface OnDismissAction {
- /* returns true if the dismiss should be deferred */
+ /**
+ * @return true if the dismiss should be deferred
+ */
boolean onDismiss();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
index ede23ef..d589283 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardMessageArea.java
@@ -48,35 +48,19 @@ class KeyguardMessageArea extends TextView {
*/
private static final long ANNOUNCEMENT_DELAY = 250;
- static final int CHARGING_ICON = 0; //R.drawable.ic_lock_idle_charging;
- static final int BATTERY_LOW_ICON = 0; //R.drawable.ic_lock_idle_low_battery;
-
static final int SECURITY_MESSAGE_DURATION = 5000;
protected static final int FADE_DURATION = 750;
private static final String TAG = "KeyguardMessageArea";
- // are we showing battery information?
- boolean mShowingBatteryInfo = false;
-
// is the bouncer up?
boolean mShowingBouncer = false;
- // last known plugged in state
- boolean mCharging = false;
-
- // last known battery level
- int mBatteryLevel = 100;
-
KeyguardUpdateMonitor mUpdateMonitor;
// Timeout before we reset the message to show charging/owner info
long mTimeout = SECURITY_MESSAGE_DURATION;
- // Shadowed text values
- protected boolean mBatteryCharged;
- protected boolean mBatteryIsLow;
-
private Handler mHandler;
CharSequence mMessage;
@@ -146,16 +130,6 @@ class KeyguardMessageArea extends TextView {
}
private KeyguardUpdateMonitorCallback mInfoCallback = new KeyguardUpdateMonitorCallback() {
- @Override
- public void onRefreshBatteryInfo(KeyguardUpdateMonitor.BatteryStatus status) {
- mShowingBatteryInfo = status.isPluggedIn() || status.isBatteryLow();
- mCharging = status.status == BatteryManager.BATTERY_STATUS_CHARGING
- || status.status == BatteryManager.BATTERY_STATUS_FULL;
- mBatteryLevel = status.level;
- mBatteryCharged = status.isCharged();
- mBatteryIsLow = status.isBatteryLow();
- update();
- }
public void onScreenTurnedOff(int why) {
setSelected(false);
};
@@ -212,7 +186,7 @@ class KeyguardMessageArea extends TextView {
*/
void update() {
MutableInt icon = new MutableInt(0);
- CharSequence status = concat(getChargeInfo(icon), getOwnerInfo(), getCurrentMessage());
+ CharSequence status = concat(getOwnerInfo(), getCurrentMessage());
setCompoundDrawablesWithIntrinsicBounds(icon.value, 0, 0, 0);
setText(status);
}
@@ -248,25 +222,6 @@ class KeyguardMessageArea extends TextView {
return info;
}
- private CharSequence getChargeInfo(MutableInt icon) {
- CharSequence string = null;
- if (mShowingBatteryInfo && !mShowingMessage) {
- // Battery status
- if (mCharging) {
- // Charging, charged or waiting to charge.
- string = getContext().getString(mBatteryCharged
- ? R.string.keyguard_charged
- : R.string.keyguard_plugged_in, mBatteryLevel);
- icon.value = CHARGING_ICON;
- } else if (mBatteryIsLow) {
- // Battery is low
- string = getContext().getString(R.string.keyguard_low_battery);
- icon.value = BATTERY_LOW_ICON;
- }
- }
- return string;
- }
-
private void hideMessage(int duration, boolean thenUpdate) {
if (duration > 0) {
Animator anim = ObjectAnimator.ofFloat(this, "alpha", 0f);
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
index ca2d615..1f3c176 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPINView.java
@@ -22,6 +22,7 @@ import android.text.TextWatcher;
import android.text.method.DigitsKeyListener;
import android.util.AttributeSet;
import android.view.View;
+import android.view.ViewGroup;
import android.widget.TextView.OnEditorActionListener;
/**
@@ -30,12 +31,21 @@ import android.widget.TextView.OnEditorActionListener;
public class KeyguardPINView extends KeyguardAbsKeyInputView
implements KeyguardSecurityView, OnEditorActionListener, TextWatcher {
+ private final AppearAnimationUtils mAppearAnimationUtils;
+ private ViewGroup mKeyguardBouncerFrame;
+ private ViewGroup mRow0;
+ private ViewGroup mRow1;
+ private ViewGroup mRow2;
+ private ViewGroup mRow3;
+ private View mDivider;
+
public KeyguardPINView(Context context) {
this(context, null);
}
public KeyguardPINView(Context context, AttributeSet attrs) {
super(context, attrs);
+ mAppearAnimationUtils = new AppearAnimationUtils(context);
}
protected void resetState() {
@@ -56,6 +66,12 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView
protected void onFinishInflate() {
super.onFinishInflate();
+ mKeyguardBouncerFrame = (ViewGroup) findViewById(R.id.keyguard_bouncer_frame);
+ mRow0 = (ViewGroup) findViewById(R.id.row0);
+ mRow1 = (ViewGroup) findViewById(R.id.row1);
+ mRow2 = (ViewGroup) findViewById(R.id.row2);
+ mRow3 = (ViewGroup) findViewById(R.id.row3);
+ mDivider = findViewById(R.id.divider);
final View ok = findViewById(R.id.key_enter);
if (ok != null) {
ok.setOnClickListener(new View.OnClickListener() {
@@ -114,4 +130,48 @@ public class KeyguardPINView extends KeyguardAbsKeyInputView
public int getWrongPasswordStringId() {
return R.string.kg_wrong_pin;
}
+
+ @Override
+ public void startAppearAnimation() {
+ enableClipping(false);
+ setTranslationY(mAppearAnimationUtils.getStartTranslation());
+ animate()
+ .setDuration(500)
+ .setInterpolator(mAppearAnimationUtils.getInterpolator())
+ .translationY(0);
+ mAppearAnimationUtils.startAppearAnimation(new View[][] {
+ new View[] {
+ mRow0, null, null
+ },
+ new View[] {
+ findViewById(R.id.key1), findViewById(R.id.key2), findViewById(R.id.key3)
+ },
+ new View[] {
+ findViewById(R.id.key4), findViewById(R.id.key5), findViewById(R.id.key6)
+ },
+ new View[] {
+ findViewById(R.id.key7), findViewById(R.id.key8), findViewById(R.id.key9)
+ },
+ new View[] {
+ null, findViewById(R.id.key0), findViewById(R.id.key_enter)
+ },
+ new View[] {
+ null, mEcaView, null
+ }},
+ new Runnable() {
+ @Override
+ public void run() {
+ enableClipping(true);
+ }
+ });
+ }
+
+ private void enableClipping(boolean enable) {
+ mKeyguardBouncerFrame.setClipToPadding(enable);
+ mKeyguardBouncerFrame.setClipChildren(enable);
+ mRow1.setClipToPadding(enable);
+ mRow2.setClipToPadding(enable);
+ mRow3.setClipToPadding(enable);
+ setClipChildren(enable);
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
index e733afc..0c385da 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPasswordView.java
@@ -198,4 +198,11 @@ public class KeyguardPasswordView extends KeyguardAbsKeyInputView
public int getWrongPasswordStringId() {
return R.string.kg_wrong_password;
}
+
+ @Override
+ public void startAppearAnimation() {
+ // TODO: Fancy animation.
+ setAlpha(0);
+ animate().alpha(1).withLayer().setDuration(200);
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
index 98122fc..5853ff9 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPatternView.java
@@ -400,4 +400,11 @@ public class KeyguardPatternView extends LinearLayout implements KeyguardSecurit
KeyguardSecurityViewHelper.
hideBouncer(mSecurityMessageDisplay, mEcaView, mBouncerFrame, duration);
}
+
+ @Override
+ public void startAppearAnimation() {
+ // TODO: Fancy animation.
+ setAlpha(0);
+ animate().alpha(1).withLayer().setDuration(200);
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
index 94edc07..382cbec 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityContainer.java
@@ -81,6 +81,10 @@ public class KeyguardSecurityContainer extends FrameLayout implements KeyguardSe
getSecurityView(mCurrentSecuritySelection).onPause();
}
+ public void startAppearAnimation() {
+ getSecurityView(mCurrentSecuritySelection).startAppearAnimation();
+ }
+
void updateSecurityViews(boolean isBouncing) {
int children = mSecurityViewFlipper.getChildCount();
for (int i = 0; i < children; i++) {
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
index dfeacf3..86bd877 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityView.java
@@ -84,4 +84,9 @@ public interface KeyguardSecurityView {
* @param duration millisends for the transisiton animation.
*/
void hideBouncer(int duration);
+
+ /**
+ * Starts the animation which should run when the security view appears.
+ */
+ void startAppearAnimation();
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
index 07239d1..178ca5e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSecurityViewFlipper.java
@@ -159,6 +159,14 @@ public class KeyguardSecurityViewFlipper extends ViewFlipper implements Keyguard
}
@Override
+ public void startAppearAnimation() {
+ KeyguardSecurityView ksv = getSecurityView();
+ if (ksv != null) {
+ ksv.startAppearAnimation();
+ }
+ }
+
+ @Override
protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
return p instanceof LayoutParams;
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
index 03e7b07..98baa04 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSelectorView.java
@@ -244,4 +244,9 @@ public class KeyguardSelectorView extends LinearLayout implements KeyguardSecuri
KeyguardSecurityViewHelper.
hideBouncer(mSecurityMessageDisplay, mFadeView, mBouncerFrame, duration);
}
+
+ @Override
+ public void startAppearAnimation() {
+ // noop.
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
index 4791956..09c4e7c 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPinView.java
@@ -135,6 +135,9 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView
mPasswordEntry.requestFocus();
mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
+ if (mEcaView instanceof EmergencyCarrierArea) {
+ ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
+ }
}
@Override
@@ -270,5 +273,10 @@ public class KeyguardSimPinView extends KeyguardAbsKeyInputView
mCheckSimPinThread.start();
}
}
+
+ @Override
+ public void startAppearAnimation() {
+ // noop.
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
index b9c7f51..6215d34 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimPukView.java
@@ -186,6 +186,9 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView
mPasswordEntry.requestFocus();
mSecurityMessageDisplay.setTimeout(0); // don't show ownerinfo/charging status by default
+ if (mEcaView instanceof EmergencyCarrierArea) {
+ ((EmergencyCarrierArea) mEcaView).setCarrierTextVisible(true);
+ }
}
@Override
@@ -339,6 +342,11 @@ public class KeyguardSimPukView extends KeyguardAbsKeyInputView
protected void verifyPasswordAndUnlock() {
mStateMachine.next();
}
+
+ @Override
+ public void startAppearAnimation() {
+ // noop.
+ }
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java
index 5d5168c..3f6ced6 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardSimpleHostView.java
@@ -39,7 +39,7 @@ public class KeyguardSimpleHostView extends KeyguardViewBase {
@Override
public void cleanUp() {
- // TODO Auto-generated method stub
+ getSecurityContainer().onPause();
}
@Override
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
index ae55c4a..bef94fa 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardStatusView.java
@@ -95,6 +95,10 @@ public class KeyguardStatusView extends GridLayout {
final boolean screenOn = KeyguardUpdateMonitor.getInstance(mContext).isScreenOn();
setEnableMarquee(screenOn);
refresh();
+
+ // Disable elegant text height because our fancy colon makes the ymin value huge for no
+ // reason.
+ mClockView.setElegantTextHeight(false);
}
protected void refresh() {
@@ -164,6 +168,10 @@ public class KeyguardStatusView extends GridLayout {
clockView24 = DateFormat.getBestDateTimePattern(locale, clockView24Skel);
+ // Use fancy colon.
+ clockView24 = clockView24.replace(':', '\uee01');
+ clockView12 = clockView12.replace(':', '\uee01');
+
cacheKey = key;
}
}
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
index a9206e7..3e444fa 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardViewBase.java
@@ -237,15 +237,17 @@ public abstract class KeyguardViewBase extends FrameLayout implements SecurityCa
if (DEBUG) Log.d(TAG, "screen on, instance " + Integer.toHexString(hashCode()));
mSecurityContainer.showPrimarySecurityScreen(false);
mSecurityContainer.onResume(KeyguardSecurityView.SCREEN_ON);
-
- // This is a an attempt to fix bug 7137389 where the device comes back on but the entire
- // layout is blank but forcing a layout causes it to reappear (e.g. with with
- // hierarchyviewer).
- requestLayout();
requestFocus();
}
/**
+ * Starts the animation when the Keyguard gets shown.
+ */
+ public void startAppearAnimation() {
+ mSecurityContainer.startAppearAnimation();
+ }
+
+ /**
* Verify that the user can get past the keyguard securely. This is called,
* for example, when the phone disables the keyguard but then wants to launch
* something else that requires secure access.
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-hdpi/ic_lock_24dp.png
deleted file mode 100644
index c779437..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_lock_24dp.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png
deleted file mode 100644
index 18257e0..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_qs_default_user.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
deleted file mode 100644
index 8ddb375..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png
deleted file mode 100644
index 57a3b99..0000000
--- a/packages/SystemUI/res/drawable-hdpi/ic_sysbar_highlight_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/search_light.png b/packages/SystemUI/res/drawable-hdpi/search_light.png
deleted file mode 100644
index 3c0dc4e..0000000
--- a/packages/SystemUI/res/drawable-hdpi/search_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-hdpi/search_light_land.png b/packages/SystemUI/res/drawable-hdpi/search_light_land.png
deleted file mode 100644
index 731f19b..0000000
--- a/packages/SystemUI/res/drawable-hdpi/search_light_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-mdpi/ic_lock_24dp.png
deleted file mode 100644
index 98ba690..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_lock_24dp.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png
deleted file mode 100644
index a35c30d..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_qs_default_user.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
deleted file mode 100644
index 71e1303..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png
deleted file mode 100644
index 1de0a3a..0000000
--- a/packages/SystemUI/res/drawable-mdpi/ic_sysbar_highlight_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/search_light.png b/packages/SystemUI/res/drawable-mdpi/search_light.png
deleted file mode 100644
index 8010ce7..0000000
--- a/packages/SystemUI/res/drawable-mdpi/search_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-mdpi/search_light_land.png b/packages/SystemUI/res/drawable-mdpi/search_light_land.png
deleted file mode 100644
index a4d82f0..0000000
--- a/packages/SystemUI/res/drawable-mdpi/search_light_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png
deleted file mode 100644
index b30cf15..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png
deleted file mode 100644
index 8014b70..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png
deleted file mode 100644
index 41a34e2..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-hdpi/ic_sysbar_highlight_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png
deleted file mode 100644
index 9c623e5..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png
deleted file mode 100644
index a011aa1..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-mdpi/ic_sysbar_highlight_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png
deleted file mode 100644
index 31eb8f7..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png
deleted file mode 100644
index 61a36e3..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png
deleted file mode 100644
index 52bf290..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xhdpi/ic_sysbar_highlight_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png
deleted file mode 100644
index c76d0e1..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/heads_up_window_bg.9.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png
deleted file mode 100644
index e5d4273..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png
deleted file mode 100644
index 1cc5009..0000000
--- a/packages/SystemUI/res/drawable-sw600dp-xxhdpi/ic_sysbar_highlight_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-xhdpi/ic_lock_24dp.png
deleted file mode 100644
index 61947ea..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_lock_24dp.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_lock_open_24dp.png b/packages/SystemUI/res/drawable-xhdpi/ic_lock_open_24dp.png
deleted file mode 100644
index 467d558..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_lock_open_24dp.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png
deleted file mode 100644
index d14a67f..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_qs_default_user.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
deleted file mode 100644
index c44aafc..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png
deleted file mode 100644
index 05da6da..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/ic_sysbar_highlight_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/search_light.png b/packages/SystemUI/res/drawable-xhdpi/search_light.png
deleted file mode 100644
index 6d46fdd..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/search_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xhdpi/search_light_land.png b/packages/SystemUI/res/drawable-xhdpi/search_light_land.png
deleted file mode 100644
index b62c74e..0000000
--- a/packages/SystemUI/res/drawable-xhdpi/search_light_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-xxhdpi/ic_lock_24dp.png
deleted file mode 100644
index 0b563b1..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_lock_24dp.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png b/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png
deleted file mode 100644
index 07f16c3..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_qs_default_user.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png
deleted file mode 100644
index 0df6203..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png b/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png
deleted file mode 100644
index b400b14..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/ic_sysbar_highlight_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/search_light.png b/packages/SystemUI/res/drawable-xxhdpi/search_light.png
deleted file mode 100644
index 7742207..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/search_light.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxhdpi/search_light_land.png b/packages/SystemUI/res/drawable-xxhdpi/search_light_land.png
deleted file mode 100644
index f364577..0000000
--- a/packages/SystemUI/res/drawable-xxhdpi/search_light_land.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_24dp.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_24dp.png
deleted file mode 100644
index 3600ee6..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_24dp.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_open_24dp.png b/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_open_24dp.png
deleted file mode 100644
index e7d2a9a..0000000
--- a/packages/SystemUI/res/drawable-xxxhdpi/ic_lock_open_24dp.png
+++ /dev/null
Binary files differ
diff --git a/packages/SystemUI/res/drawable/ic_account_circle.xml b/packages/SystemUI/res/drawable/ic_account_circle.xml
new file mode 100644
index 0000000..a7e8514
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_account_circle.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="24dp"
+ android:height="24dp"/>
+
+ <viewport
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"/>
+
+ <path
+ android:fill="#FFFFFFFF"
+ android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0c5.5,0.0 10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM12.0,5.0c1.7,0.0 3.0,1.3 3.0,3.0c0.0,1.7 -1.3,3.0 -3.0,3.0c-1.7,0.0 -3.0,-1.3 -3.0,-3.0C9.0,6.3 10.3,5.0 12.0,5.0zM12.0,19.2c-2.5,0.0 -4.7,-1.3 -6.0,-3.2c0.0,-2.0 4.0,-3.1 6.0,-3.1c2.0,0.0 6.0,1.1 6.0,3.1C16.7,17.9 14.5,19.2 12.0,19.2z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
new file mode 100644
index 0000000..b2e486c
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_lock_24dp.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="24.0dp"
+ android:height="24.0dp"/>
+
+ <viewport
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"/>
+
+ <path
+ android:fill="@color/keyguard_affordance"
+ android:pathData="M18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM12.0,17.0c-1.1,0.0 -2.0,-0.9 -2.0,-2.0s0.9,-2.0 2.0,-2.0c1.1,0.0 2.0,0.9 2.0,2.0S13.1,17.0 12.0,17.0zM15.1,8.0L8.9,8.0L8.9,6.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1L15.1,8.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
new file mode 100644
index 0000000..28b16dd
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_lock_open_24dp.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="24.0dp"
+ android:height="24.0dp"/>
+
+ <viewport
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"/>
+
+ <path
+ android:fill="@color/keyguard_affordance"
+ android:pathData="M12.0,17.0c1.1,0.0 2.0,-0.9 2.0,-2.0s-0.9,-2.0 -2.0,-2.0c-1.1,0.0 -2.0,0.9 -2.0,2.0S10.9,17.0 12.0,17.0zM18.0,8.0l-1.0,0.0L17.0,6.0c0.0,-2.8 -2.2,-5.0 -5.0,-5.0C9.2,1.0 7.0,3.2 7.0,6.0l1.9,0.0c0.0,-1.7 1.4,-3.1 3.1,-3.1c1.7,0.0 3.1,1.4 3.1,3.1l0.0,2.0L6.0,8.0c-1.1,0.0 -2.0,0.9 -2.0,2.0l0.0,10.0c0.0,1.1 0.9,2.0 2.0,2.0l12.0,0.0c1.1,0.0 2.0,-0.9 2.0,-2.0L20.0,10.0C20.0,8.9 19.1,8.0 18.0,8.0zM18.0,20.0L6.0,20.0L6.0,10.0l12.0,0.0L18.0,20.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml
index 3a20c58..787eec5 100644
--- a/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml
+++ b/packages/SystemUI/res/drawable/ic_qs_ringer_audible.xml
@@ -24,5 +24,5 @@ Copyright (C) 2014 The Android Open Source Project
<path
android:fill="#FFFFFFFF"
- android:pathData="M6.6,3.6L5.2,2.2C2.8,4.0 1.2,6.8 1.0,10.0l2.0,0.0C3.2,7.3 4.5,5.0 6.6,3.6zM20.0,10.0l2.0,0.0c-0.2,-3.2 -1.7,-6.0 -4.1,-7.8l-1.4,1.4C18.5,5.0 19.8,7.3 20.0,10.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0l-2.0,-2.0L18.0,10.5zM11.5,22.0c0.1,0.0 0.3,0.0 0.4,0.0c0.7,-0.1 1.2,-0.6 1.4,-1.2c0.1,-0.2 0.2,-0.5 0.2,-0.8l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0z" />
+ android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/>
</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_audible.xml b/packages/SystemUI/res/drawable/ic_ringer_audible.xml
new file mode 100644
index 0000000..2969948
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_ringer_audible.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="32dp"
+ android:height="32dp"/>
+
+ <viewport
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"/>
+
+ <path
+ android:fill="#FFFFFFFF"
+ android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,16.0l0.0,-5.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7c-2.9,0.7 -5.0,3.2 -5.0,6.3L5.0,16.0l-2.0,2.0l0.0,1.0l17.0,0.0l0.0,-1.0L18.0,16.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_silent.xml b/packages/SystemUI/res/drawable/ic_ringer_silent.xml
new file mode 100644
index 0000000..b5837f6
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_ringer_silent.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="32dp"
+ android:height="32dp"/>
+
+ <viewport
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"/>
+
+ <path
+ android:fill="#FFFFFFFF"
+ android:pathData="M11.5,22.0c1.1,0.0 2.0,-0.9 2.0,-2.0l-4.0,0.0C9.5,21.1 10.4,22.0 11.5,22.0zM18.0,10.5c0.0,-3.1 -2.1,-5.6 -5.0,-6.3L13.0,3.5C13.0,2.7 12.3,2.0 11.5,2.0C10.7,2.0 10.0,2.7 10.0,3.5l0.0,0.7C9.5,4.3 9.0,4.5 8.6,4.7l9.4,9.4L18.0,10.5zM17.7,19.0l2.0,2.0l1.3,-1.3L4.3,3.0L3.0,4.3l2.9,2.9C5.3,8.2 5.0,9.3 5.0,10.5L5.0,16.0l-2.0,2.0l0.0,1.0L17.7,19.0z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml b/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml
new file mode 100644
index 0000000..d8ded58
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_ringer_vibrate.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="32dp"
+ android:height="32dp"/>
+
+ <viewport
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"/>
+
+ <path
+ android:fill="#FFFFFFFF"
+ android:pathData="M0.0,15.0l2.0,0.0L2.0,9.0L0.0,9.0L0.0,15.0zM3.0,17.0l2.0,0.0L5.0,7.0L3.0,7.0L3.0,17.0zM22.0,9.0l0.0,6.0l2.0,0.0L24.0,9.0L22.0,9.0zM19.0,17.0l2.0,0.0L21.0,7.0l-2.0,0.0L19.0,17.0zM16.5,3.0l-9.0,0.0C6.7,3.0 6.0,3.7 6.0,4.5l0.0,15.0C6.0,20.3 6.7,21.0 7.5,21.0l9.0,0.0c0.8,0.0 1.5,-0.7 1.5,-1.5l0.0,-15.0C18.0,3.7 17.3,3.0 16.5,3.0zM16.0,19.0L8.0,19.0L8.0,5.0l8.0,0.0L16.0,19.0z"/>
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_vol_zen_off.xml b/packages/SystemUI/res/drawable/ic_vol_zen_off.xml
new file mode 100644
index 0000000..ea5ab70
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_vol_zen_off.xml
@@ -0,0 +1,30 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="32dp"
+ android:height="32dp"/>
+
+ <viewport
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"/>
+
+ <path
+ android:fill="#00000000"
+ android:stroke="#CCCCCC"
+ android:strokeWidth="1.0"
+ android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0c5.5,0.0 10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM4.0,12.0c0.0,-4.4 3.6,-8.0 8.0,-8.0c1.8,0.0 3.5,0.6 4.9,1.7L5.7,16.9C4.6,15.5 4.0,13.8 4.0,12.0zM12.0,20.0c-1.8,0.0 -3.5,-0.6 -4.9,-1.7L18.3,7.1C19.4,8.5 20.0,10.2 20.0,12.0C20.0,16.4 16.4,20.0 12.0,20.0z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/ic_vol_zen_on.xml b/packages/SystemUI/res/drawable/ic_vol_zen_on.xml
new file mode 100644
index 0000000..44024f3
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ic_vol_zen_on.xml
@@ -0,0 +1,28 @@
+<!--
+Copyright (C) 2014 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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <size
+ android:width="32dp"
+ android:height="32dp"/>
+
+ <viewport
+ android:viewportWidth="24.0"
+ android:viewportHeight="24.0"/>
+
+ <path
+ android:fill="#FFFFFFFF"
+ android:pathData="M12.0,2.0C6.5,2.0 2.0,6.5 2.0,12.0s4.5,10.0 10.0,10.0c5.5,0.0 10.0,-4.5 10.0,-10.0S17.5,2.0 12.0,2.0zM4.0,12.0c0.0,-4.4 3.6,-8.0 8.0,-8.0c1.8,0.0 3.5,0.6 4.9,1.7L5.7,16.9C4.6,15.5 4.0,13.8 4.0,12.0zM12.0,20.0c-1.8,0.0 -3.5,-0.6 -4.9,-1.7L18.3,7.1C19.4,8.5 20.0,10.2 20.0,12.0C20.0,16.4 16.4,20.0 12.0,20.0z" />
+</vector>
diff --git a/packages/SystemUI/res/drawable/notification_header_bg.xml b/packages/SystemUI/res/drawable/notification_header_bg.xml
index 09d0d7d..5daec20 100644
--- a/packages/SystemUI/res/drawable/notification_header_bg.xml
+++ b/packages/SystemUI/res/drawable/notification_header_bg.xml
@@ -19,13 +19,11 @@
<item android:state_pressed="true">
<shape>
<solid android:color="@color/background_color_1_press" />
- <corners android:radius="@*android:dimen/notification_quantum_rounded_rect_radius" />
</shape>
</item>
<item>
<shape>
<solid android:color="@color/background_color_1" />
- <corners android:radius="@*android:dimen/notification_quantum_rounded_rect_radius" />
</shape>
</item>
</selector> \ No newline at end of file
diff --git a/packages/SystemUI/res/drawable/qs_panel_background.xml b/packages/SystemUI/res/drawable/qs_panel_background.xml
index c324976..a1a5362 100644
--- a/packages/SystemUI/res/drawable/qs_panel_background.xml
+++ b/packages/SystemUI/res/drawable/qs_panel_background.xml
@@ -13,11 +13,8 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<inset xmlns:android="http://schemas.android.com/apk/res/android"
- android:insetLeft="@dimen/notification_side_padding"
- android:insetRight="@dimen/notification_side_padding">
- <shape>
- <solid android:color="@color/system_primary_color" />
- <corners android:radius="@*android:dimen/notification_quantum_rounded_rect_radius" />
- </shape>
-</inset>
+<shape xmlns:android="http://schemas.android.com/apk/res/android">
+ <solid android:color="@color/system_primary_color" />
+ <corners
+ android:radius="@*android:dimen/notification_quantum_rounded_rect_radius"/>
+</shape>
diff --git a/packages/SystemUI/res/drawable/ripple_drawable.xml b/packages/SystemUI/res/drawable/ripple_drawable.xml
new file mode 100644
index 0000000..d2bff42
--- /dev/null
+++ b/packages/SystemUI/res/drawable/ripple_drawable.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2014 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
+ -->
+
+<ripple xmlns:android="http://schemas.android.com/apk/res/android"
+ android:tint="?android:attr/colorControlHighlight"
+ android:tintMode="src_over"
+ android:pinned="true" />
diff --git a/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml b/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml
index 5f12706..a291495 100644
--- a/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml
+++ b/packages/SystemUI/res/layout-ldrtl/navigation_bar.xml
@@ -55,7 +55,7 @@
systemui:keyCode="4"
android:layout_weight="0"
android:scaleType="center"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_back"
/>
<View
@@ -71,7 +71,7 @@
systemui:keyCode="3"
systemui:keyRepeat="false"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_home"
/>
<View
@@ -85,7 +85,7 @@
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_recent"
/>
<FrameLayout
@@ -99,7 +99,7 @@
android:contentDescription="@string/accessibility_menu"
android:src="@drawable/ic_sysbar_menu"
android:visibility="invisible"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
systemui:keyCode="82" />
<com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/ime_switcher"
@@ -109,7 +109,7 @@
android:scaleType="centerInside"
android:src="@drawable/ic_ime_switcher_default"
android:visibility="invisible"
- systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ android:background="@drawable/ripple_drawable" />
</FrameLayout>
</LinearLayout>
@@ -158,17 +158,6 @@
/>
</LinearLayout>
- <com.android.systemui.statusbar.policy.KeyButtonView
- android:layout_width="80dp"
- android:id="@+id/search_light"
- android:layout_height="match_parent"
- android:layout_gravity="center_horizontal"
- android:src="@drawable/search_light"
- android:scaleType="center"
- android:visibility="gone"
- android:contentDescription="@string/accessibility_search_light"
- />
-
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="match_parent"
@@ -212,7 +201,7 @@
android:layout_weight="0"
android:visibility="invisible"
android:contentDescription="@string/accessibility_menu"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land" />
+ android:background="@drawable/ripple_drawable" />
<com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/ime_switcher"
android:layout_height="@dimen/navigation_extra_key_width"
@@ -221,7 +210,7 @@
android:scaleType="centerInside"
android:src="@drawable/ic_ime_switcher_default"
android:visibility="invisible"
- systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ android:background="@drawable/ripple_drawable" />
</FrameLayout>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/back"
android:layout_height="80dp"
@@ -231,7 +220,7 @@
systemui:keyCode="4"
android:layout_weight="0"
android:contentDescription="@string/accessibility_back"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ android:background="@drawable/ripple_drawable"
/>
<View
android:layout_height="match_parent"
@@ -247,7 +236,7 @@
systemui:keyRepeat="false"
android:layout_weight="0"
android:contentDescription="@string/accessibility_home"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ android:background="@drawable/ripple_drawable"
/>
<View
android:layout_height="match_parent"
@@ -261,7 +250,7 @@
android:src="@drawable/ic_sysbar_recent_land"
android:layout_weight="0"
android:contentDescription="@string/accessibility_recent"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ android:background="@drawable/ripple_drawable"
/>
<View
android:layout_height="40dp"
@@ -316,17 +305,6 @@
/>
</LinearLayout>
- <com.android.systemui.statusbar.policy.KeyButtonView
- android:id="@+id/search_light"
- android:layout_height="80dp"
- android:layout_width="match_parent"
- android:layout_gravity="center_vertical"
- android:src="@drawable/search_light"
- android:scaleType="center"
- android:visibility="gone"
- android:contentDescription="@string/accessibility_search_light"
- />
-
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout-sw600dp/heads_up.xml b/packages/SystemUI/res/layout-sw600dp/heads_up.xml
deleted file mode 100644
index f7035fe..0000000
--- a/packages/SystemUI/res/layout-sw600dp/heads_up.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
-/*
-** Copyright 2014, 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.policy.HeadsUpNotificationView
- xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- >
- <FrameLayout
- android:id="@+id/content_holder"
- android:layout_height="wrap_content"
- android:layout_width="@dimen/notification_panel_width"
- android:background="@drawable/heads_up_window_bg"
- />
-</com.android.systemui.statusbar.policy.HeadsUpNotificationView>
diff --git a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
index 6a2e3c6..f8b7bae 100644
--- a/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
+++ b/packages/SystemUI/res/layout-sw600dp/navigation_bar.xml
@@ -59,7 +59,7 @@
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_back"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
@@ -69,7 +69,7 @@
systemui:keyCode="3"
systemui:keyRepeat="true"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_home"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
@@ -77,7 +77,7 @@
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_recent"
/>
<Space
@@ -98,7 +98,7 @@
systemui:keyCode="82"
android:visibility="invisible"
android:contentDescription="@string/accessibility_menu"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
/>
<com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/ime_switcher"
@@ -109,7 +109,7 @@
android:src="@drawable/ic_ime_switcher_default"
android:visibility="invisible"
android:contentDescription="@string/accessibility_ime_switch_button"
- systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ android:background="@drawable/ripple_drawable" />
</FrameLayout>
</LinearLayout>
@@ -156,17 +156,6 @@
/>
</LinearLayout>
- <com.android.systemui.statusbar.policy.KeyButtonView
- android:layout_width="128dp"
- android:id="@+id/search_light"
- android:layout_height="match_parent"
- android:layout_gravity="center_horizontal"
- android:src="@drawable/search_light"
- android:scaleType="center"
- android:visibility="gone"
- android:contentDescription="@string/accessibility_search_light"
- />
-
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="match_parent"
@@ -216,7 +205,7 @@
android:src="@drawable/ic_sysbar_back"
systemui:keyCode="4"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_back"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/home"
@@ -226,7 +215,7 @@
systemui:keyCode="3"
systemui:keyRepeat="true"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_home"
/>
<com.android.systemui.statusbar.policy.KeyButtonView android:id="@+id/recent_apps"
@@ -234,7 +223,7 @@
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_recent"
/>
<Space
@@ -255,7 +244,7 @@
systemui:keyCode="82"
android:visibility="invisible"
android:contentDescription="@string/accessibility_menu"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
/>
<com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/ime_switcher"
@@ -266,7 +255,7 @@
android:visibility="invisible"
android:contentDescription="@string/accessibility_ime_switch_button"
android:scaleType="centerInside"
- systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ android:background="@drawable/ripple_drawable" />
</FrameLayout>
</LinearLayout>
@@ -313,17 +302,6 @@
/>
</LinearLayout>
- <com.android.systemui.statusbar.policy.KeyButtonView
- android:layout_width="162dp"
- android:id="@+id/search_light"
- android:layout_height="match_parent"
- android:layout_gravity="center_horizontal"
- android:src="@drawable/search_light"
- android:scaleType="center"
- android:visibility="gone"
- android:contentDescription="@string/accessibility_search_light"
- />
-
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/heads_up.xml b/packages/SystemUI/res/layout/heads_up.xml
index 7d9cfa1..236fdc3 100644
--- a/packages/SystemUI/res/layout/heads_up.xml
+++ b/packages/SystemUI/res/layout/heads_up.xml
@@ -1,26 +1,30 @@
<?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.
-*/
+ Copyright (C) 2014 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.policy.HeadsUpNotificationView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
- android:layout_width="match_parent"
- android:id="@+id/content_holder"
- android:background="@drawable/notification_panel_bg"
- /> \ No newline at end of file
+ android:layout_height="match_parent"
+ android:layout_width="match_parent">
+
+ <FrameLayout
+ android:layout_height="wrap_content"
+ android:layout_marginStart="@dimen/notification_side_padding"
+ android:layout_marginEnd="@dimen/notification_side_padding"
+ android:elevation="16dp"
+ android:id="@+id/content_holder"
+ style="@style/NotificationsQuickSettings" />
+
+</com.android.systemui.statusbar.policy.HeadsUpNotificationView> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/keyguard_bottom_area.xml b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
index 2ec3766..9bf42b2 100644
--- a/packages/SystemUI/res/layout/keyguard_bottom_area.xml
+++ b/packages/SystemUI/res/layout/keyguard_bottom_area.xml
@@ -22,7 +22,7 @@
android:layout_height="match_parent"
android:layout_width="match_parent"
>
- <com.android.systemui.statusbar.phone.SwipeAffordanceView
+ <com.android.systemui.statusbar.AlphaImageView
android:id="@+id/camera_button"
android:layout_height="64dp"
android:layout_width="64dp"
@@ -30,11 +30,9 @@
android:tint="#ffffffff"
android:src="@drawable/ic_camera_alt_24dp"
android:scaleType="center"
- android:contentDescription="@string/accessibility_camera_button"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
- systemui:swipeDirection="start"/>
+ android:contentDescription="@string/accessibility_camera_button" />
- <com.android.systemui.statusbar.phone.SwipeAffordanceView
+ <com.android.systemui.statusbar.AlphaImageView
android:id="@+id/phone_button"
android:layout_height="64dp"
android:layout_width="64dp"
@@ -42,9 +40,7 @@
android:tint="#ffffffff"
android:src="@drawable/ic_phone_24dp"
android:scaleType="center"
- android:contentDescription="@string/accessibility_phone_button"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
- systemui:swipeDirection="end"/>
+ android:contentDescription="@string/accessibility_phone_button" />
<com.android.systemui.statusbar.phone.KeyguardIndicationTextView
android:id="@+id/keyguard_indication_text"
@@ -53,17 +49,16 @@
android:layout_marginBottom="100dp"
android:layout_gravity="bottom|center_horizontal"
android:textStyle="italic"
- android:textAppearance="?android:attr/textAppearanceMedium"/>
+ android:textColor="#ffffff"
+ android:textAppearance="?android:attr/textAppearanceSmall"/>
- <ImageView
+ <com.android.systemui.statusbar.AlphaImageView
android:id="@+id/lock_icon"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_gravity="bottom|center_horizontal"
android:src="@drawable/ic_lock_24dp"
android:scaleType="center"
- android:alpha="0.7"
- android:layerType="hardware"
- android:tint="#ffffffff"/>
+ android:tint="#ffffffff" />
-</com.android.systemui.statusbar.phone.KeyguardBottomAreaView> \ No newline at end of file
+</com.android.systemui.statusbar.phone.KeyguardBottomAreaView>
diff --git a/packages/SystemUI/res/layout/navigation_bar.xml b/packages/SystemUI/res/layout/navigation_bar.xml
index 7470409..7616cb1 100644
--- a/packages/SystemUI/res/layout/navigation_bar.xml
+++ b/packages/SystemUI/res/layout/navigation_bar.xml
@@ -55,7 +55,7 @@
systemui:keyCode="4"
android:layout_weight="0"
android:scaleType="center"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_back"
/>
<View
@@ -71,7 +71,7 @@
systemui:keyCode="3"
systemui:keyRepeat="false"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_home"
/>
<View
@@ -85,7 +85,7 @@
android:layout_height="match_parent"
android:src="@drawable/ic_sysbar_recent"
android:layout_weight="0"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
android:contentDescription="@string/accessibility_recent"
/>
<FrameLayout
@@ -99,7 +99,7 @@
android:contentDescription="@string/accessibility_menu"
android:src="@drawable/ic_sysbar_menu"
android:visibility="invisible"
- systemui:glowBackground="@drawable/ic_sysbar_highlight"
+ android:background="@drawable/ripple_drawable"
systemui:keyCode="82" />
<com.android.systemui.statusbar.policy.KeyButtonView
@@ -110,7 +110,7 @@
android:scaleType="centerInside"
android:src="@drawable/ic_ime_switcher_default"
android:visibility="invisible"
- systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ android:background="@drawable/ripple_drawable" />
</FrameLayout>
</LinearLayout>
@@ -160,22 +160,6 @@
/>
</LinearLayout>
- <FrameLayout
- android:layout_width="match_parent"
- android:layout_height="match_parent">
-
- <com.android.systemui.statusbar.policy.KeyButtonView
- android:layout_width="80dp"
- android:id="@+id/search_light"
- android:layout_height="match_parent"
- android:layout_gravity="center"
- android:src="@drawable/search_light"
- android:scaleType="center"
- android:visibility="gone"
- android:contentDescription="@string/accessibility_search_light"
- />
- </FrameLayout>
-
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="match_parent"
@@ -219,7 +203,7 @@
android:scaleType="centerInside"
android:src="@drawable/ic_ime_switcher_default"
android:visibility="invisible"
- systemui:glowBackground="@drawable/ic_sysbar_highlight" />
+ android:background="@drawable/ripple_drawable" />
<com.android.systemui.statusbar.policy.KeyButtonView
android:id="@+id/menu"
@@ -228,7 +212,7 @@
android:contentDescription="@string/accessibility_menu"
android:src="@drawable/ic_sysbar_menu_land"
android:visibility="invisible"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ android:background="@drawable/ripple_drawable"
systemui:keyCode="82" />
</FrameLayout>
@@ -238,7 +222,7 @@
android:src="@drawable/ic_sysbar_recent_land"
android:layout_weight="0"
android:contentDescription="@string/accessibility_recent"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ android:background="@drawable/ripple_drawable"
/>
<View
android:layout_height="match_parent"
@@ -254,7 +238,7 @@
systemui:keyRepeat="false"
android:layout_weight="0"
android:contentDescription="@string/accessibility_home"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ android:background="@drawable/ripple_drawable"
/>
<View
android:layout_height="match_parent"
@@ -270,7 +254,7 @@
systemui:keyCode="4"
android:layout_weight="0"
android:contentDescription="@string/accessibility_back"
- systemui:glowBackground="@drawable/ic_sysbar_highlight_land"
+ android:background="@drawable/ripple_drawable"
/>
<View
android:layout_height="40dp"
@@ -325,19 +309,6 @@
/>
</LinearLayout>
- <com.android.systemui.statusbar.policy.KeyButtonView
- android:id="@+id/search_light"
- android:layout_height="80dp"
- android:layout_width="match_parent"
- android:layout_gravity="center_vertical"
- android:src="@drawable/search_light_land"
- android:scaleType="center"
- android:visibility="gone"
- android:contentDescription="@string/accessibility_search_light"
- />
-
- <!-- No camera button in landscape mode -->
-
<com.android.systemui.statusbar.policy.DeadZone
android:id="@+id/deadzone"
android:layout_height="match_parent"
diff --git a/packages/SystemUI/res/layout/qs_zen_mode_detail.xml b/packages/SystemUI/res/layout/qs_detail.xml
index 85b294d..e73b431 100644
--- a/packages/SystemUI/res/layout/qs_zen_mode_detail.xml
+++ b/packages/SystemUI/res/layout/qs_detail.xml
@@ -14,64 +14,44 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.systemui.qs.tiles.ZenModeDetail xmlns:android="http://schemas.android.com/apk/res/android"
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:background="@color/system_secondary_color" >
+ android:background="@color/system_primary_color" >
<ImageView
android:id="@android:id/button1"
- android:src="@drawable/ic_qs_close"
android:layout_width="64dp"
android:layout_height="64dp"
android:layout_alignParentStart="true"
- android:padding="@dimen/qs_panel_padding" />
-
- <Switch
- android:id="@android:id/checkbox"
- android:layout_width="wrap_content"
- android:layout_height="64dp"
- android:layout_alignParentEnd="true"
- android:gravity="center"
- android:padding="@dimen/qs_panel_padding" />
+ android:contentDescription="@string/accessibility_quick_settings_close"
+ android:padding="@dimen/qs_panel_padding"
+ android:src="@drawable/ic_qs_close" />
<TextView
android:id="@android:id/title"
android:layout_width="match_parent"
android:layout_height="64dp"
+ android:layout_alignParentTop="true"
android:layout_toEndOf="@android:id/button1"
android:layout_toStartOf="@android:id/checkbox"
- android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
android:gravity="center_vertical"
- android:paddingStart="@dimen/qs_panel_padding"
- android:text="@string/zen_mode_title" />
+ android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
- <View
+ <ImageView
android:id="@android:id/custom"
android:layout_width="match_parent"
- android:layout_height="2dp"
+ android:layout_height="wrap_content"
android:layout_below="@android:id/title"
- android:background="#888" />
+ android:layout_marginLeft="16dip"
+ android:layout_marginRight="16dip"
+ android:scaleType="fitXY"
+ android:src="?android:attr/dividerHorizontal" />
- <ListView
+ <FrameLayout
android:id="@android:id/content"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:layout_above="@android:id/button2"
- android:layout_below="@android:id/custom"
- android:divider="#00000000"
- android:dividerHeight="0px" />
-
- <TextView
- android:id="@android:id/button2"
- style="@style/QSBorderless"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:layout_alignParentBottom="true"
- android:layout_alignParentEnd="true"
- android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
- android:padding="@dimen/qs_panel_padding"
- android:text="@string/quick_settings_more_settings"
- android:textAllCaps="true" />
+ android:layout_below="@android:id/custom" />
-</com.android.systemui.qs.tiles.ZenModeDetail> \ No newline at end of file
+</RelativeLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/qs_panel.xml b/packages/SystemUI/res/layout/qs_panel.xml
index 85de645..398787f 100644
--- a/packages/SystemUI/res/layout/qs_panel.xml
+++ b/packages/SystemUI/res/layout/qs_panel.xml
@@ -16,11 +16,10 @@
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/quick_settings_container"
- android:paddingLeft="@dimen/notification_side_padding"
- android:paddingRight="@dimen/notification_side_padding"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:background="@drawable/qs_panel_background" >
+ android:background="@drawable/qs_panel_background"
+ android:elevation="2dp">
<com.android.systemui.qs.QSPanel
android:id="@+id/quick_settings_panel"
android:background="#0000"
diff --git a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
index 1efda8c..97ed9a0 100644
--- a/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
+++ b/packages/SystemUI/res/layout/quick_settings_brightness_dialog.xml
@@ -15,7 +15,8 @@
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:systemui="http://schemas.android.com/apk/res/com.android.systemui"
- style="@style/BrightnessDialogContainer">
+ style="@style/BrightnessDialogContainer"
+ android:clickable="true">
<ImageView
android:id="@+id/brightness_icon"
diff --git a/packages/SystemUI/res/layout/recents_task_view.xml b/packages/SystemUI/res/layout/recents_task_view.xml
index 7de421c..85d2f16 100644
--- a/packages/SystemUI/res/layout/recents_task_view.xml
+++ b/packages/SystemUI/res/layout/recents_task_view.xml
@@ -25,36 +25,37 @@
<com.android.systemui.recents.views.TaskBarView
android:id="@+id/task_view_bar"
android:layout_width="match_parent"
- android:layout_height="wrap_content"
+ android:layout_height="56dp"
android:layout_gravity="top|center_horizontal"
android:background="@color/recents_task_bar_default_background_color">
<ImageView
android:id="@+id/application_icon"
android:layout_width="@dimen/recents_task_view_application_icon_size"
android:layout_height="@dimen/recents_task_view_application_icon_size"
- android:layout_gravity="center_vertical|start"
- android:padding="8dp" />
+ android:layout_marginStart="16dp"
+ android:layout_gravity="center_vertical|start" />
<TextView
android:id="@+id/activity_description"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_gravity="center_vertical|left"
- android:layout_marginStart="@dimen/recents_task_view_application_icon_size"
- android:layout_marginEnd="@dimen/recents_task_view_application_icon_size"
- android:textSize="22sp"
+ android:layout_gravity="center_vertical|start"
+ android:layout_marginStart="64dp"
+ android:layout_marginEnd="64dp"
+ android:textSize="16sp"
android:textColor="#ffffffff"
android:text="@string/recents_empty_message"
- android:fontFamily="sans-serif-light"
+ android:fontFamily="sans-serif-medium"
android:singleLine="true"
android:maxLines="2"
android:ellipsize="marquee"
android:fadingEdge="horizontal" />
<ImageView
android:id="@+id/dismiss_task"
- android:layout_width="@dimen/recents_task_view_application_icon_size"
- android:layout_height="@dimen/recents_task_view_application_icon_size"
+ android:layout_width="48dp"
+ android:layout_height="48dp"
+ android:layout_marginEnd="4dp"
android:layout_gravity="center_vertical|end"
- android:padding="23dp"
+ android:padding="18dp"
android:src="@drawable/recents_dismiss_light" />
</com.android.systemui.recents.views.TaskBarView>
</com.android.systemui.recents.views.TaskView>
diff --git a/packages/SystemUI/res/layout/status_bar_expanded.xml b/packages/SystemUI/res/layout/status_bar_expanded.xml
index 2ec9935..cde83bf 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded.xml
@@ -59,8 +59,8 @@
android:id="@+id/scroll_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:visibility="invisible"
android:scrollbars="none"
+ android:overScrollMode="never"
android:fillViewport="true">
<LinearLayout
android:layout_width="match_parent"
@@ -70,7 +70,9 @@
layout="@layout/qs_panel"
android:layout_marginTop="@dimen/status_bar_header_height_expanded"
android:layout_width="match_parent"
- android:layout_height="wrap_content"/>
+ android:layout_height="wrap_content"
+ android:layout_marginLeft="@dimen/notification_side_padding"
+ android:layout_marginRight="@dimen/notification_side_padding"/>
<!-- A view to reserve space for the collapsed stack -->
<View
@@ -79,7 +81,6 @@
</LinearLayout>
</com.android.systemui.statusbar.phone.ObservableScrollView>
-
<com.android.systemui.statusbar.stack.NotificationStackScrollLayout
android:id="@+id/notification_stack_scroller"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/status_bar_expanded_header.xml b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
index 89fa988..7f34041 100644
--- a/packages/SystemUI/res/layout/status_bar_expanded_header.xml
+++ b/packages/SystemUI/res/layout/status_bar_expanded_header.xml
@@ -25,7 +25,7 @@
android:paddingStart="@dimen/notification_side_padding"
android:paddingEnd="@dimen/notification_side_padding"
android:baselineAligned="false"
- android:elevation="10dp"
+ android:elevation="4dp"
>
<View
@@ -65,22 +65,13 @@
/>
</RelativeLayout>
- <com.android.keyguard.CarrierText
- android:id="@+id/keyguard_carrier_text"
- android:layout_width="wrap_content"
- android:layout_height="@dimen/status_bar_header_height_keyguard"
- android:layout_marginLeft="8dp"
- android:gravity="center_vertical"
- android:ellipsize="marquee"
- android:textAppearance="?android:attr/textAppearanceMedium" />
-
<com.android.systemui.statusbar.phone.MultiUserSwitch android:id="@+id/multi_user_switch"
android:layout_width="40dp"
android:layout_height="@dimen/status_bar_header_height"
android:layout_alignParentEnd="true"
android:background="@null"
android:scaleType="centerInside"
- android:padding="6dp"
+ android:padding="8dp"
/>
<ImageButton android:id="@+id/settings_button"
@@ -98,6 +89,18 @@
android:layout_marginEnd="4dp"
/>
+ <com.android.keyguard.CarrierText
+ android:id="@+id/keyguard_carrier_text"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/status_bar_header_height_keyguard"
+ android:layout_marginLeft="8dp"
+ android:layout_toStartOf="@id/system_icons_container"
+ android:gravity="center_vertical"
+ android:ellipsize="marquee"
+ android:textAppearance="?android:attr/textAppearanceSmall"
+ android:textColor="#ffffff"
+ android:singleLine="true" />
+
<include
layout="@layout/quick_settings_brightness_dialog"
android:id="@+id/brightness_container"
diff --git a/packages/SystemUI/res/layout/super_status_bar.xml b/packages/SystemUI/res/layout/super_status_bar.xml
index 26616cd..e84300d 100644
--- a/packages/SystemUI/res/layout/super_status_bar.xml
+++ b/packages/SystemUI/res/layout/super_status_bar.xml
@@ -26,6 +26,10 @@
android:fitsSystemWindows="true"
android:descendantFocusability="afterDescendants">
+ <View android:id="@+id/scrim_behind"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
<include layout="@layout/status_bar"
android:layout_width="match_parent"
android:layout_height="@dimen/status_bar_height" />
@@ -40,4 +44,8 @@
android:visibility="gone" />
</com.android.systemui.statusbar.phone.PanelHolder>
+ <View android:id="@+id/scrim_in_front"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
+
</com.android.systemui.statusbar.phone.StatusBarWindowView>
diff --git a/packages/SystemUI/res/layout/user_switcher_host.xml b/packages/SystemUI/res/layout/user_switcher_host.xml
index 70c5042..816af57 100644
--- a/packages/SystemUI/res/layout/user_switcher_host.xml
+++ b/packages/SystemUI/res/layout/user_switcher_host.xml
@@ -27,7 +27,7 @@
<FrameLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:layout_marginTop="@*android:dimen/volume_panel_top"
+ android:layout_marginTop="@dimen/volume_panel_top"
android:background="@*android:drawable/dialog_full_holo_dark">
<ListView android:id="@android:id/list"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/layout/volume_panel.xml b/packages/SystemUI/res/layout/volume_panel.xml
new file mode 100644
index 0000000..046862f
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_panel.xml
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2007 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/visible_panel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal" >
+
+ <FrameLayout
+ android:id="@+id/slider_panel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:minHeight="64dip"
+ android:layout_toLeftOf="@+id/expand_button_divider" />
+
+ <ImageView
+ android:id="@+id/expand_button_divider"
+ android:layout_width="wrap_content"
+ android:layout_height="32dip"
+ android:layout_gravity="top"
+ android:layout_marginBottom="16dip"
+ android:layout_marginTop="16dip"
+ android:layout_toLeftOf="@+id/expand_button"
+ android:scaleType="fitXY"
+ android:src="?android:attr/dividerVertical" />
+
+ <ImageView
+ android:id="@+id/expand_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentRight="true"
+ android:layout_gravity="top"
+ style="@style/BorderlessButton.Tiny"
+ android:padding="16dip" />
+
+ <ImageView
+ android:id="@+id/zen_panel_divider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_below="@+id/slider_panel"
+ android:layout_marginLeft="16dip"
+ android:layout_marginRight="16dip"
+ android:scaleType="fitXY"
+ android:src="?android:attr/dividerHorizontal" />
+
+ <ViewStub
+ android:id="@+id/zen_panel_stub"
+ android:layout_below="@+id/zen_panel_divider"
+ android:inflatedId="@+id/zen_panel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout="@layout/zen_mode_panel" />
+
+</RelativeLayout>
diff --git a/packages/SystemUI/res/layout/volume_panel_item.xml b/packages/SystemUI/res/layout/volume_panel_item.xml
new file mode 100644
index 0000000..98cb8f4
--- /dev/null
+++ b/packages/SystemUI/res/layout/volume_panel_item.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="80dip"
+ android:orientation="horizontal"
+ android:layout_marginTop="8dip"
+ android:layout_marginBottom="8dip"
+ android:gravity="start|center_vertical">
+
+ <ImageView
+ android:id="@+id/stream_icon"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:paddingLeft="16dip"
+ android:background="?android:attr/selectableItemBackground"
+ android:contentDescription="@null" />
+
+ <SeekBar
+ style="?android:attr/seekBarStyle"
+ android:id="@+id/seekbar"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:padding="16dip"
+ android:layout_marginEnd="16dip" />
+
+</LinearLayout>
diff --git a/packages/SystemUI/res/layout/qs_zen_mode_detail_condition.xml b/packages/SystemUI/res/layout/zen_mode_condition.xml
index fd27aaf..8b34400 100644
--- a/packages/SystemUI/res/layout/qs_zen_mode_detail_condition.xml
+++ b/packages/SystemUI/res/layout/zen_mode_condition.xml
@@ -16,44 +16,47 @@
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="match_parent" >
+ android:layout_height="wrap_content" >
<RadioButton
android:id="@android:id/checkbox"
android:layout_width="32dp"
- android:layout_height="64dp"
+ android:layout_height="@dimen/zen_mode_condition_height"
android:layout_alignParentStart="true"
- android:layout_marginStart="@dimen/qs_panel_padding"
android:gravity="center" />
<TextView
android:id="@android:id/title"
android:layout_width="match_parent"
- android:layout_height="64dp"
+ android:layout_height="@dimen/zen_mode_condition_height"
android:layout_toEndOf="@android:id/checkbox"
android:layout_toStartOf="@android:id/button1"
android:ellipsize="end"
- android:textAppearance="@style/TextAppearance.StatusBar.Expanded.Clock"
android:gravity="center_vertical"
android:maxLines="1"
- android:text="@string/accessibility_back" />
+ android:textAppearance="@style/TextAppearance.QS.DetailItemPrimary" />
<ImageView
android:id="@android:id/button1"
- android:src="@drawable/ic_qs_minus"
- android:layout_width="64dp"
- android:layout_height="64dp"
+ style="@style/BorderlessButton"
+ android:layout_width="@dimen/zen_mode_condition_height"
+ android:layout_height="@dimen/zen_mode_condition_height"
android:layout_alignParentEnd="true"
- android:layout_marginEnd="48dp"
- android:padding="@dimen/qs_panel_padding"
- android:paddingRight="0px" />
+ android:layout_centerVertical="true"
+ android:layout_marginEnd="@dimen/zen_mode_condition_height"
+ android:contentDescription="@string/accessibility_quick_settings_less_time"
+ android:padding="@dimen/zen_mode_condition_detail_button_padding"
+ android:src="@drawable/ic_qs_minus" />
<ImageView
android:id="@android:id/button2"
- android:src="@drawable/ic_qs_plus"
- android:layout_width="64dp"
- android:layout_height="64dp"
+ style="@style/BorderlessButton"
+ android:layout_width="@dimen/zen_mode_condition_height"
+ android:layout_height="@dimen/zen_mode_condition_height"
android:layout_alignParentEnd="true"
- android:padding="@dimen/qs_panel_padding" />
+ android:layout_centerVertical="true"
+ android:contentDescription="@string/accessibility_quick_settings_more_time"
+ android:padding="@dimen/zen_mode_condition_detail_button_padding"
+ android:src="@drawable/ic_qs_plus" />
-</RelativeLayout>
+</RelativeLayout> \ No newline at end of file
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
new file mode 100644
index 0000000..0936cc2
--- /dev/null
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2014 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.
+-->
+<!-- extends LinearLayout -->
+<com.android.systemui.volume.ZenModePanel xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@+id/zen_mode_panel"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="@color/system_primary_color"
+ android:orientation="vertical"
+ android:paddingTop="@dimen/qs_panel_padding"
+ android:paddingLeft="@dimen/qs_panel_padding"
+ android:paddingRight="@dimen/qs_panel_padding" >
+
+ <TextView
+ android:id="@android:id/title"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentStart="true"
+ android:layout_marginBottom="8dp"
+ android:text="@string/zen_mode_title"
+ android:textAppearance="@style/TextAppearance.QS.DetailHeader" />
+
+ <LinearLayout
+ android:id="@android:id/content"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" />
+
+ <TextView
+ android:id="@android:id/button2"
+ style="@style/BorderlessButton"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_alignParentEnd="true"
+ android:layout_gravity="end"
+ android:text="@string/quick_settings_more_settings"
+ android:textAppearance="@style/TextAppearance.QS.DetailButton" />
+
+</com.android.systemui.volume.ZenModePanel> \ No newline at end of file
diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml
index 22815f3..5750faa 100644
--- a/packages/SystemUI/res/values-sw600dp/dimens.xml
+++ b/packages/SystemUI/res/values-sw600dp/dimens.xml
@@ -57,6 +57,6 @@
<!-- The margin between the clock and the notifications on Keyguard. See
keyguard_clock_height_fraction_* for the difference between min and max.-->
- <dimen name="keyguard_clock_notifications_margin_min">32dp</dimen>
- <dimen name="keyguard_clock_notifications_margin_max">32dp</dimen>
+ <dimen name="keyguard_clock_notifications_margin_min">36dp</dimen>
+ <dimen name="keyguard_clock_notifications_margin_max">36dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/attrs.xml b/packages/SystemUI/res/values/attrs.xml
index 8fd1206..c453618 100644
--- a/packages/SystemUI/res/values/attrs.xml
+++ b/packages/SystemUI/res/values/attrs.xml
@@ -20,8 +20,6 @@
<attr name="keyCode" format="integer" />
<!-- does this button generate longpress / repeat events? -->
<attr name="keyRepeat" format="boolean" />
- <!-- drawable to use for a swelling, glowing background on press -->
- <attr name="glowBackground" format="reference" />
</declare-styleable>
<declare-styleable name="ToggleSlider">
<attr name="text" format="string" />
@@ -45,12 +43,6 @@
<declare-styleable name="BatteryMeterView">
<attr name="frameColor" format="color" />
</declare-styleable>
- <declare-styleable name="SwipeAffordanceView">
- <attr name="swipeDirection" format="enum">
- <enum name="start" value="0" />
- <enum name="end" value="1" />
- </attr>
- </declare-styleable>
<declare-styleable name="Clock">
<attr name="amPmStyle" format="enum">
<enum name="normal" value="0" />
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index e5ed3d6..e6fa535 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -31,8 +31,6 @@
<drawable name="recents_callout_line">#99ffffff</drawable>
<drawable name="notification_item_background_legacy_color">#ffaaaaaa</drawable>
<drawable name="heads_up_notification_bg_pressed">#ff33B5E5</drawable>
- <color name="notification_panel_scrim_color">#A0000000</color>
- <color name="notification_panel_scrim_color_keyguard">#80000000</color>
<color name="batterymeter_frame_color">#66FFFFFF</color><!-- 40% white -->
<color name="batterymeter_charge_color">#FFFFFFFF</color>
<color name="batterymeter_bolt_color">#FFFFFFFF</color>
@@ -69,12 +67,14 @@
<!-- The recents task bar light text color to be drawn on top of dark backgrounds. -->
<color name="recents_task_bar_light_text_color">#ffeeeeee</color>
<!-- The recents task bar dark text color to be drawn on top of light backgrounds. -->
- <color name="recents_task_bar_dark_text_color">#ff222222</color>
+ <color name="recents_task_bar_dark_text_color">#ff333333</color>
<!-- The recents task bar light dismiss icon color to be drawn on top of dark backgrounds. -->
<color name="recents_task_bar_light_dismiss_color">#ffeeeeee</color>
<!-- The recents task bar dark dismiss icon color to be drawn on top of light backgrounds. -->
<color name="recents_task_bar_dark_dismiss_color">#ff333333</color>
+ <color name="keyguard_affordance">#ffffffff</color>
+
<!-- Our quantum color palette (deep teal) -->
<color name="primary_color">#ff7fcac3</color>
<color name="background_color_1">#ff384248</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index 0bd4f18..0184df2 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -113,9 +113,9 @@
<!-- The min animation duration for animating views that are newly visible. -->
<integer name="recents_filter_animate_new_views_min_duration">125</integer>
<!-- The min animation duration for animating the task bar in. -->
- <integer name="recents_animate_task_bar_enter_duration">225</integer>
+ <integer name="recents_animate_task_bar_enter_duration">300</integer>
<!-- The min animation duration for animating the task bar out. -->
- <integer name="recents_animate_task_bar_exit_duration">175</integer>
+ <integer name="recents_animate_task_bar_exit_duration">150</integer>
<!-- The animation duration for animating in the info pane. -->
<integer name="recents_animate_task_view_info_pane_duration">150</integer>
<!-- The animation duration for animating the removal of a task view. -->
@@ -135,5 +135,8 @@
<!-- Defines the implementation of the velocity tracker to be used for the panel expansion. Can
be 'platform' or 'noisy' (i.e. for noisy touch screens). -->
<string name="velocity_tracker_impl" translatable="false">platform</string>
+
+ <!-- Wait on the touch feedback this long before performing an action. -->
+ <integer name="feedback_start_delay">300</integer>
</resources>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index e9dcea2..e65d9a6 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -196,6 +196,12 @@
<dimen name="qs_dual_tile_height">109dp</dimen>
<dimen name="qs_dual_tile_padding">12dp</dimen>
+ <!-- How far the expanded QS panel peeks from the header in collapsed state. -->
+ <dimen name="qs_peek_height">8dp</dimen>
+
+ <dimen name="zen_mode_condition_detail_button_padding">8dp</dimen>
+ <dimen name="zen_mode_condition_height">48dp</dimen>
+
<!-- used by DessertCase -->
<dimen name="dessert_case_cell_size">192dp</dimen>
@@ -206,7 +212,7 @@
<dimen name="glowpadview_inner_radius">15dip</dimen>
<!-- The size of the application icon in the recents task view. -->
- <dimen name="recents_task_view_application_icon_size">60dp</dimen>
+ <dimen name="recents_task_view_application_icon_size">32dp</dimen>
<!-- The size of the activity icon in the recents task view. -->
<dimen name="recents_task_view_activity_icon_size">60dp</dimen>
@@ -215,10 +221,13 @@
<dimen name="recents_task_view_rounded_corners_radius">2dp</dimen>
<!-- The min translation in the Z index for the last task. -->
- <dimen name="recents_task_view_z_min">3dp</dimen>
+ <dimen name="recents_task_view_z_min">5dp</dimen>
<!-- The translation in the Z index for each task above the last task. -->
- <dimen name="recents_task_view_z_increment">5dp</dimen>
+ <dimen name="recents_task_view_z_increment">10dp</dimen>
+
+ <!-- The amount of bottom inset in the shadow outline. -->
+ <dimen name="recents_task_view_shadow_outline_bottom_inset">5dp</dimen>
<!-- The amount to translate when animating the removal of a task. -->
<dimen name="recents_task_view_remove_anim_translation_x">100dp</dimen>
@@ -288,4 +297,12 @@
<dimen name="keyguard_clock_notifications_margin_min">22dp</dimen>
<dimen name="keyguard_clock_notifications_margin_max">36dp</dimen>
+ <!-- The minimum amount the user needs to swipe to go to the camera / phone. -->
+ <dimen name="keyguard_min_swipe_amount">75dp</dimen>
+
+ <!-- Volume panel dialog y offset -->
+ <dimen name="volume_panel_top">16dp</dimen>
+
+ <!-- Volume panel dialog width -->
+ <dimen name="volume_panel_width">300dp</dimen>
</resources>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index f5bc353..ef3956e 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -388,6 +388,12 @@
<string name="accessibility_quick_settings_location">Location <xliff:g id="state" example="Off">%s</xliff:g>.</string>
<!-- Content description of the alarm tile in quick settings (not shown on the screen). [CHAR LIMIT=NONE] -->
<string name="accessibility_quick_settings_alarm">Alarm set for <xliff:g id="time" example="Wed 3:30 PM">%s</xliff:g>.</string>
+ <!-- Content description of quick settings detail panel close button (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_close">Close panel</string>
+ <!-- Content description of zen mode time condition plus button (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_more_time">More time</string>
+ <!-- Content description of zen mode time condition minus button (not shown on the screen). [CHAR LIMIT=NONE] -->
+ <string name="accessibility_quick_settings_less_time">Less time</string>
<!-- Title of dialog shown when 2G-3G data usage has exceeded limit and has been disabled. [CHAR LIMIT=48] -->
<string name="data_usage_disabled_dialog_3g_title">2G-3G data disabled</string>
@@ -512,6 +518,8 @@
<string name="quick_settings_tethering_label">Tethering</string>
<!-- QuickSettings: Hotspot. [CHAR LIMIT=NONE] -->
<string name="quick_settings_hotspot_label">Hotspot</string>
+ <!-- QuickSettings: Notifications [CHAR LIMIT=NONE] -->
+ <string name="quick_settings_notifications_label">Notifications</string>
<!-- Recents: The empty recents string. [CHAR LIMIT=NONE] -->
<string name="recents_empty_message">RECENTS</string>
@@ -563,4 +571,19 @@
<string name="keyguard_unlock">Swipe up to unlock</string>
<string name="bugreport_tile_extended" translatable="false">%s\n%s (%s)</string>
+
+ <!-- Zen mode condition: no exit criteria. [CHAR LIMIT=NONE] -->
+ <string name="zen_mode_forever">Until you turn this off</string>
+
+ <!-- Zen mode condition: time duration in minutes. [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_duration_minutes">
+ <item quantity="one">For one minute</item>
+ <item quantity="other">For %d minutes</item>
+ </plurals>
+
+ <!-- Zen mode condition: time duration in hours. [CHAR LIMIT=NONE] -->
+ <plurals name="zen_mode_duration_hours">
+ <item quantity="one">For one hour</item>
+ <item quantity="other">For %d hours</item>
+ </plurals>
</resources>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 19888a8..6a12232 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -133,6 +133,32 @@
<item name="android:fadingEdge">horizontal</item>
</style>
+ <style name="TextAppearance.QS">
+ <item name="android:textStyle">normal</item>
+ <item name="android:textColor">#ffffff</item>
+ <item name="android:fontFamily">sans-serif</item>
+ </style>
+
+ <style name="TextAppearance.QS.DetailHeader">
+ <item name="android:textSize">20sp</item>
+ <item name="android:fontFamily">sans-serif-medium</item>
+ </style>
+
+ <style name="TextAppearance.QS.DetailItemPrimary">
+ <item name="android:textSize">16sp</item>
+ </style>
+
+ <style name="TextAppearance.QS.DetailItemSecondary">
+ <item name="android:textSize">14sp</item>
+ <item name="android:textColor">#7fcac3</item>
+ </style>
+
+ <style name="TextAppearance.QS.DetailButton">
+ <item name="android:textSize">14sp</item>
+ <item name="android:textAllCaps">true</item>
+ <item name="android:fontFamily">sans-serif-medium</item>
+ </style>
+
<style name="BaseBrightnessDialogContainer">
<item name="android:layout_width">match_parent</item>
<item name="android:layout_height">wrap_content</item>
@@ -192,9 +218,9 @@
<item name="android:colorControlActivated">@color/system_accent_color</item>
</style>
- <style name="QSBorderless" parent="@android:style/Widget.Quantum.Button.Borderless" />
+ <style name="BorderlessButton" parent="@android:style/Widget.Quantum.Button.Borderless" />
- <style name="QSBorderless.Tiny">
+ <style name="BorderlessButton.Tiny">
<item name="android:minHeight">12dip</item>
<item name="android:minWidth">12dip</item>
</style>
diff --git a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
index 6387a92..1b12cb0 100644
--- a/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/SwipeHelper.java
@@ -56,6 +56,7 @@ public class SwipeHelper implements Gefingerpoken {
static final float ALPHA_FADE_END = 0.5f; // fraction of thumbnail width
// beyond which alpha->0
private float mMinAlpha = 0f;
+ private float mMaxAlpha = 1f;
private float mPagingTouchSlop;
private Callback mCallback;
@@ -140,6 +141,10 @@ public class SwipeHelper implements Gefingerpoken {
mMinAlpha = minAlpha;
}
+ public void setMaxAlpha(float maxAlpha) {
+ mMaxAlpha = maxAlpha;
+ }
+
private float getAlphaForOffset(View view) {
float viewSize = getSize(view);
final float fadeSize = ALPHA_FADE_END * viewSize;
@@ -150,7 +155,7 @@ public class SwipeHelper implements Gefingerpoken {
} else if (pos < viewSize * (1.0f - ALPHA_FADE_START)) {
result = 1.0f + (viewSize * ALPHA_FADE_START + pos) / fadeSize;
}
- return Math.max(mMinAlpha, result);
+ return Math.min(Math.max(mMinAlpha, result), mMaxAlpha);
}
private void updateAlphaFromOffset(View animView, boolean dismissable) {
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
index d7ce255..630ba13 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIApplication.java
@@ -42,12 +42,12 @@ public class SystemUIApplication extends Application {
private final Class<?>[] SERVICES = new Class[] {
com.android.systemui.keyguard.KeyguardViewMediator.class,
com.android.systemui.recent.Recents.class,
+ com.android.systemui.volume.VolumeUI.class,
com.android.systemui.statusbar.SystemBars.class,
com.android.systemui.usb.StorageNotification.class,
com.android.systemui.power.PowerUI.class,
com.android.systemui.media.RingtonePlayer.class,
com.android.systemui.settings.SettingsUI.class,
- com.android.systemui.volume.VolumeUI.class,
};
/**
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
index 41c0e78..4c7f3df 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardService.java
@@ -202,6 +202,12 @@ public class KeyguardService extends Service {
checkPermission();
mKeyguardViewMediator.onBootCompleted();
}
+
+ @Override
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ checkPermission();
+ mKeyguardViewMediator.startKeyguardExitAnimation(fadeoutDuration);
+ }
};
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index e73e904..7110d8d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -46,7 +46,8 @@ import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.view.ViewGroup;
-import android.view.WindowManager;
+import android.view.IWindowManager;
+import android.view.WindowManagerGlobal;
import android.view.WindowManagerPolicy;
import com.android.internal.policy.IKeyguardExitCallback;
@@ -62,6 +63,7 @@ import com.android.keyguard.analytics.KeyguardAnalytics;
import com.android.keyguard.analytics.Session;
import com.android.systemui.SystemUI;
import com.android.systemui.statusbar.phone.PhoneStatusBar;
+import com.android.systemui.statusbar.phone.ScrimController;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.StatusBarWindowManager;
@@ -136,6 +138,7 @@ public class KeyguardViewMediator extends SystemUI {
private static final int SET_OCCLUDED = 12;
private static final int KEYGUARD_TIMEOUT = 13;
private static final int DISMISS = 17;
+ private static final int START_KEYGUARD_EXIT_ANIM = 18;
/**
* The default amount of time we stay awake (used for all key input)
@@ -179,6 +182,9 @@ public class KeyguardViewMediator extends SystemUI {
/** High level access to the power manager for WakeLocks */
private PowerManager mPM;
+ /** High level access to the window manager for dismissing keyguard animation */
+ private IWindowManager mWM;
+
/** UserManager for querying number of users */
private UserManager mUserManager;
@@ -439,6 +445,7 @@ public class KeyguardViewMediator extends SystemUI {
private void setup() {
mPM = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWM = WindowManagerGlobal.getWindowManagerService();
mUserManager = (UserManager) mContext.getSystemService(Context.USER_SERVICE);
mShowKeyguardWakeLock = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "show keyguard");
mShowKeyguardWakeLock.setReferenceCounted(false);
@@ -1075,6 +1082,9 @@ public class KeyguardViewMediator extends SystemUI {
case DISMISS:
handleDismiss();
break;
+ case START_KEYGUARD_EXIT_ANIM:
+ handleStartKeyguardExitAnimation((Long) msg.obj);
+ break;
}
}
};
@@ -1206,6 +1216,19 @@ public class KeyguardViewMediator extends SystemUI {
private void handleHide() {
synchronized (KeyguardViewMediator.this) {
if (DEBUG) Log.d(TAG, "handleHide");
+ try {
+
+ // Don't actually hide the Keyguard at the moment, wait for window manager until
+ // it tells us it's safe to do so with startKeyguardExitAnimation.
+ mWM.keyguardGoingAway();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error while calling WindowManager", e);
+ }
+ }
+ }
+
+ private void handleStartKeyguardExitAnimation(long fadeoutDuration) {
+ synchronized (KeyguardViewMediator.this) {
// only play "unlock" noises if not on a call (since the incall UI
// disables the keyguard)
@@ -1316,12 +1339,18 @@ public class KeyguardViewMediator extends SystemUI {
}
public StatusBarKeyguardViewManager registerStatusBar(PhoneStatusBar phoneStatusBar,
- ViewGroup container, StatusBarWindowManager statusBarWindowManager) {
+ ViewGroup container, StatusBarWindowManager statusBarWindowManager,
+ ScrimController scrimController) {
mStatusBarKeyguardViewManager.registerStatusBar(phoneStatusBar, container,
- statusBarWindowManager);
+ statusBarWindowManager, scrimController);
return mStatusBarKeyguardViewManager;
}
+ public void startKeyguardExitAnimation(long fadeoutDuration) {
+ Message msg = mHandler.obtainMessage(START_KEYGUARD_EXIT_ANIM, fadeoutDuration);
+ mHandler.sendMessage(msg);
+ }
+
public ViewMediatorCallback getViewMediatorCallback() {
return mViewMediatorCallback;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index bdac7a0..626fc0d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -191,15 +191,23 @@ public class QSPanel extends ViewGroup {
final int ch = record.row == 0 ? mLargeCellHeight : mCellHeight;
record.tileView.measure(exactly(cw), exactly(ch));
}
- final int actualHeight = rows == 0 ? 0 : getRowTop(rows);
- mDetail.measure(exactly(width), exactly(actualHeight));
- setMeasuredDimension(width, actualHeight);
+ int h = rows == 0 ? 0 : getRowTop(rows);
+ mDetail.measure(exactly(width), unspecified());
+ if (mDetail.getVisibility() == VISIBLE && mDetail.getChildCount() > 0) {
+ final int dmh = mDetail.getMeasuredHeight();
+ if (dmh > 0) h = dmh;
+ }
+ setMeasuredDimension(width, h);
}
private static int exactly(int size) {
return MeasureSpec.makeMeasureSpec(size, MeasureSpec.EXACTLY);
}
+ private static int unspecified() {
+ return MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+ }
+
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
final int w = getWidth();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 835a5c4..c76ee8c 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -26,6 +26,7 @@ import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
+import com.android.systemui.R;
import com.android.systemui.qs.QSTile.State;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.CastController;
@@ -35,6 +36,7 @@ import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.TetheringController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.volume.VolumeComponent;
import java.util.List;
import java.util.Objects;
@@ -49,12 +51,12 @@ import java.util.Objects;
public abstract class QSTile<TState extends State> implements Listenable {
protected final String TAG = "QSTile." + getClass().getSimpleName();
protected static final boolean DEBUG = false;
- public static final int FEEDBACK_START_DELAY = 400;
protected final Host mHost;
protected final Context mContext;
protected final H mHandler;
protected final Handler mUiHandler = new Handler(Looper.getMainLooper());
+ private final int mFeedbackStartDelay;
private Callback mCallback;
protected final TState mState = newTileState();
@@ -68,6 +70,7 @@ public abstract class QSTile<TState extends State> implements Listenable {
mHost = host;
mContext = host.getContext();
mHandler = new H(host.getLooper());
+ mFeedbackStartDelay = mContext.getResources().getInteger(R.integer.feedback_start_delay);
}
public boolean supportsDualTargets() {
@@ -116,6 +119,10 @@ public abstract class QSTile<TState extends State> implements Listenable {
mHandler.obtainMessage(H.USER_SWITCH, newUserId).sendToTarget();
}
+ protected void postAfterFeedback(Runnable runnable) {
+ mHandler.postDelayed(runnable, mFeedbackStartDelay);
+ }
+
// call only on tile worker looper
private void handleSetCallback(Callback callback) {
@@ -213,6 +220,7 @@ public abstract class QSTile<TState extends State> implements Listenable {
ZenModeController getZenModeController();
TetheringController getTetheringController();
CastController getCastController();
+ VolumeComponent getVolumeComponent();
}
public static class State {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
index 5eecc20..2edd8d5 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTileView.java
@@ -84,7 +84,8 @@ public class QSTileView extends ViewGroup {
removeView(mLabel);
}
final Resources res = mContext.getResources();
- mLabel = new TextView(mDual ? new ContextThemeWrapper(mContext, R.style.QSBorderless_Tiny)
+ mLabel = new TextView(mDual
+ ? new ContextThemeWrapper(mContext, R.style.BorderlessButton_Tiny)
: mContext);
mLabel.setId(android.R.id.title);
mLabel.setTextColor(res.getColor(R.color.qs_tile_text));
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java
index fa41837..07ea825 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/BugreportTile.java
@@ -58,13 +58,13 @@ public class BugreportTile extends QSTile<QSTile.State> {
@Override
protected void handleClick() {
- mHandler.postDelayed(new Runnable() {
+ postAfterFeedback(new Runnable() {
@Override
public void run() {
mHost.collapsePanels();
mUiHandler.post(mShowDialog);
}
- }, FEEDBACK_START_DELAY);
+ });
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
index 907c77e..6793051 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/CastTile.java
@@ -65,12 +65,12 @@ public class CastTile extends QSTile<QSTile.BooleanState> {
@Override
protected void handleClick() {
- mHandler.postDelayed(new Runnable() {
+ postAfterFeedback(new Runnable() {
public void run() {
mHost.collapsePanels();
mUiHandler.post(mShowDialog);
}
- }, FEEDBACK_START_DELAY);
+ });
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java
new file mode 100644
index 0000000..20bbf8b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/NotificationsTile.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2014 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.qs.tiles;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.media.AudioManager;
+import android.util.Log;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.View.OnAttachStateChangeListener;
+import android.view.ViewGroup;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.qs.QSTile;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.volume.VolumeComponent;
+import com.android.systemui.volume.VolumePanel;
+import com.android.systemui.volume.ZenModePanel;
+
+/** Quick settings tile: Notifications **/
+public class NotificationsTile extends QSTile<NotificationsTile.NotificationsState> {
+ private final ZenModeController mZenController;
+ private final AudioManager mAudioManager;
+
+ public NotificationsTile(Host host) {
+ super(host);
+ mZenController = host.getZenModeController();
+ mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ }
+
+ @Override
+ public View createDetailView(Context context, ViewGroup root) {
+ final Context themedContext = new ContextThemeWrapper(mContext, R.style.QSAccentTheme);
+ final View v = LayoutInflater.from(themedContext).inflate(R.layout.qs_detail, root, false);
+ final TextView title = (TextView) v.findViewById(android.R.id.title);
+ title.setText(R.string.quick_settings_notifications_label);
+ final View close = v.findViewById(android.R.id.button1);
+ close.setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ showDetail(false);
+ }
+ });
+ final ViewGroup content = (ViewGroup) v.findViewById(android.R.id.content);
+ final VolumeComponent volumeComponent = mHost.getVolumeComponent();
+ final VolumePanel vp = new VolumePanel(mContext, content, mZenController);
+ v.addOnAttachStateChangeListener(new OnAttachStateChangeListener() {
+ @Override
+ public void onViewDetachedFromWindow(View v) {
+ volumeComponent.setVolumePanel(null);
+ }
+
+ @Override
+ public void onViewAttachedToWindow(View v) {
+ volumeComponent.setVolumePanel(vp);
+ }
+ });
+ vp.setZenModePanelCallback(new ZenModePanel.Callback() {
+ @Override
+ public void onMoreSettings() {
+ mHost.startSettingsActivity(ZenModePanel.ZEN_SETTINGS);
+ }
+
+ @Override
+ public void onInteraction() {
+ // noop
+ }
+ });
+ vp.postVolumeChanged(AudioManager.STREAM_RING, AudioManager.FLAG_SHOW_UI);
+ return v;
+ }
+
+ @Override
+ protected NotificationsState newTileState() {
+ return new NotificationsState();
+ }
+
+ @Override
+ public void setListening(boolean listening) {
+ if (listening) {
+ mZenController.addCallback(mCallback);
+ final IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
+ mContext.registerReceiver(mReceiver, filter);
+ } else {
+ mZenController.removeCallback(mCallback);
+ mContext.unregisterReceiver(mReceiver);
+ }
+ }
+
+ @Override
+ protected void handleClick() {
+ showDetail(true);
+ }
+
+ @Override
+ protected void handleUpdateState(NotificationsState state, Object arg) {
+ state.visible = true;
+ state.zen = arg instanceof Boolean ? (Boolean) arg : mZenController.isZen();
+ state.ringerMode = mAudioManager.getRingerMode();
+ if (state.zen) {
+ state.iconId = R.drawable.ic_qs_zen_on;
+ } else if (state.ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
+ state.iconId = R.drawable.ic_qs_ringer_vibrate;
+ } else if (state.ringerMode == AudioManager.RINGER_MODE_SILENT) {
+ state.iconId = R.drawable.ic_qs_ringer_silent;
+ } else {
+ state.iconId = R.drawable.ic_qs_ringer_audible;
+ }
+ state.label = mContext.getString(R.string.quick_settings_notifications_label);
+ }
+
+ private final ZenModeController.Callback mCallback = new ZenModeController.Callback() {
+ @Override
+ public void onZenChanged(boolean zen) {
+ if (DEBUG) Log.d(TAG, "onZenChanged " + zen);
+ refreshState(zen);
+ }
+ };
+
+ public static final class NotificationsState extends QSTile.State {
+ public boolean zen;
+ public int ringerMode;
+
+ @Override
+ public boolean copyTo(State other) {
+ final NotificationsState o = (NotificationsState) other;
+ final boolean changed = o.zen != zen || o.ringerMode != ringerMode;
+ o.zen = zen;
+ o.ringerMode = ringerMode;
+ return super.copyTo(other) || changed;
+ }
+
+ @Override
+ protected StringBuilder toStringBuilder() {
+ final StringBuilder rt = super.toStringBuilder();
+ rt.insert(rt.length() - 1, ",zen=" + zen + ",ringerMode=" + ringerMode);
+ return rt;
+ }
+ }
+
+ private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(intent.getAction())) {
+ refreshState();
+ }
+ }
+ };
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/RingerModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/RingerModeTile.java
deleted file mode 100644
index c5e9b52..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/RingerModeTile.java
+++ /dev/null
@@ -1,108 +0,0 @@
-/*
- * Copyright (C) 2014 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.qs.tiles;
-
-import android.content.BroadcastReceiver;
-import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
-import android.media.AudioManager;
-
-import com.android.systemui.R;
-import com.android.systemui.qs.QSTile;
-
-/** Quick settings tile: Ringer mode **/
-public class RingerModeTile extends QSTile<RingerModeTile.IntState> {
-
- private final AudioManager mAudioManager;
-
- public RingerModeTile(Host host) {
- super(host);
- mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
- }
-
- @Override
- protected IntState newTileState() {
- return new IntState();
- }
-
- @Override
- public void setListening(boolean listening) {
- if (listening) {
- final IntentFilter filter = new IntentFilter(AudioManager.RINGER_MODE_CHANGED_ACTION);
- mContext.registerReceiver(mReceiver, filter);
- } else {
- mContext.unregisterReceiver(mReceiver);
- }
- }
-
- @Override
- protected void handleClick() {
- final int oldValue = (Integer) mState.value;
- final int newValue =
- oldValue == AudioManager.RINGER_MODE_NORMAL ? AudioManager.RINGER_MODE_VIBRATE
- : oldValue == AudioManager.RINGER_MODE_VIBRATE ? AudioManager.RINGER_MODE_SILENT
- : AudioManager.RINGER_MODE_NORMAL;
-
- mAudioManager.setRingerMode(newValue);
- }
-
- @Override
- protected void handleUpdateState(IntState state, Object arg) {
- final int ringerMode = mAudioManager.getRingerMode();
- state.visible = true;
- state.value = ringerMode;
- if (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {
- state.iconId = R.drawable.ic_qs_ringer_vibrate;
- state.label = "Vibrate";
- } else if (ringerMode == AudioManager.RINGER_MODE_SILENT) {
- state.iconId = R.drawable.ic_qs_ringer_silent;
- state.label = "Silent";
- } else {
- state.iconId = R.drawable.ic_qs_ringer_audible;
- state.label = "Audible";
- }
- }
-
- private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (AudioManager.RINGER_MODE_CHANGED_ACTION.equals(intent.getAction())) {
- refreshState();
- }
- }
- };
-
- public static class IntState extends QSTile.State {
- public int value;
-
- @Override
- public boolean copyTo(State other) {
- final IntState o = (IntState) other;
- final boolean changed = o.value != value;
- o.value = value;
- return super.copyTo(other) || changed;
- }
-
- @Override
- protected StringBuilder toStringBuilder() {
- final StringBuilder rt = super.toStringBuilder();
- rt.insert(rt.length() - 1, ",value=" + value);
- return rt;
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
index ef7fb89..a1e70b9 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/WifiTile.java
@@ -83,7 +83,7 @@ public class WifiTile extends QSTile<QSTile.SignalState> {
boolean wifiConnected = cb.enabled && (cb.wifiSignalIconId > 0) && (cb.enabledDesc != null);
boolean wifiNotConnected = (cb.wifiSignalIconId > 0) && (cb.enabledDesc == null);
- state.enabled = wifiConnected;
+ state.enabled = cb.enabled;
state.connected = wifiConnected;
state.activityIn = cb.enabled && cb.activityIn;
state.activityOut = cb.enabled && cb.activityOut;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeDetail.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeDetail.java
deleted file mode 100644
index f30f791..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeDetail.java
+++ /dev/null
@@ -1,273 +0,0 @@
-/*
- * Copyright (C) 2014 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.qs.tiles;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.Settings;
-import android.service.notification.Condition;
-import android.util.AttributeSet;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
-import android.widget.ImageView;
-import android.widget.ListView;
-import android.widget.RadioButton;
-import android.widget.RelativeLayout;
-import android.widget.Switch;
-import android.widget.TextView;
-
-import com.android.systemui.R;
-import com.android.systemui.qs.QSTile;
-import com.android.systemui.statusbar.policy.ZenModeController;
-
-import java.util.HashSet;
-
-/** Quick settings control panel: Zen mode **/
-public class ZenModeDetail extends RelativeLayout {
- private static final String TAG = "ZenModeDetail";
- private static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
- private static final int[] MINUTES = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 };
-
- private final H mHandler = new H();
-
- private int mMinutesIndex = 3;
- private Context mContext;
- private ZenModeTile mTile;
- private QSTile.Host mHost;
- private ZenModeController mController;
-
- private Switch mSwitch;
- private ConditionAdapter mAdapter;
-
- public ZenModeDetail(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public void init(ZenModeTile tile) {
- mTile = tile;
- mHost = mTile.getHost();
- mContext = getContext();
- mController = mHost.getZenModeController();
-
- final ImageView close = (ImageView) findViewById(android.R.id.button1);
- close.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mTile.showDetail(false);
- }
- });
- mSwitch = (Switch) findViewById(android.R.id.checkbox);
- mSwitch.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- mController.setZen(isChecked);
- }
- });
- mSwitch.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- final boolean isChecked = mSwitch.isChecked();
- mController.setZen(isChecked);
- if (!isChecked) {
- mTile.showDetail(false);
- }
- }
- });
-
- final View moreSettings = findViewById(android.R.id.button2);
- moreSettings.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- mHost.startSettingsActivity(ZEN_SETTINGS);
- mTile.showDetail(false);
- }
- });
- final ListView conditions = (ListView) findViewById(android.R.id.content);
- mAdapter = new ConditionAdapter(mContext);
- conditions.setAdapter(mAdapter);
- mAdapter.add(updateTimeCondition());
-
- updateZen(mController.isZen());
- }
-
- private Condition updateTimeCondition() {
- final int minutes = MINUTES[mMinutesIndex];
- final long millis = System.currentTimeMillis() + minutes * 60 * 1000;
- final Uri id = new Uri.Builder().scheme(Condition.SCHEME).authority("android")
- .appendPath("countdown").appendPath(Long.toString(millis)).build();
- final int num = minutes < 60 ? minutes : minutes / 60;
- final String units = minutes < 60 ? "minutes" : minutes == 60 ? "hour" : "hours";
- return new Condition(id, "For " + num + " " + units, "", "", 0, Condition.STATE_TRUE,
- Condition.FLAG_RELEVANT_NOW);
- }
-
- private void editTimeCondition(int delta) {
- final int i = mMinutesIndex + delta;
- if (i < 0 || i >= MINUTES.length) return;
- mMinutesIndex = i;
- mAdapter.remove(mAdapter.getItem(0));
- final Condition c = updateTimeCondition();
- mAdapter.insert(c, 0);
- select(c);
- }
-
- private void select(Condition condition) {
- mController.select(condition);
- }
-
- private void updateZen(boolean zen) {
- mHandler.obtainMessage(H.UPDATE_ZEN, zen ? 1 : 0, 0).sendToTarget();
- }
-
- private void updateConditions(Condition[] conditions) {
- if (conditions == null) return;
- mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget();
- }
-
- private void handleUpdateZen(boolean zen) {
- mSwitch.setChecked(zen);
- }
-
- private void handleUpdateConditions(Condition[] conditions) {
- for (int i = mAdapter.getCount() - 1; i > 0; i--) {
- mAdapter.remove(mAdapter.getItem(i));
- }
- for (Condition condition : conditions) {
- mAdapter.add(condition);
- }
- }
-
- @Override
- protected void onAttachedToWindow() {
- super.onAttachedToWindow();
- mController.addCallback(mCallback);
- mController.requestConditions(true);
- }
-
- @Override
- protected void onDetachedFromWindow() {
- super.onDetachedFromWindow();
- mController.removeCallback(mCallback);
- mController.requestConditions(false);
- }
-
- private final class H extends Handler {
- private static final int UPDATE_ZEN = 1;
- private static final int UPDATE_CONDITIONS = 2;
-
- public H() {
- super(Looper.getMainLooper());
- }
-
- @Override
- public void handleMessage(Message msg) {
- if (msg.what == UPDATE_ZEN) {
- handleUpdateZen(msg.arg1 == 1);
- } else if (msg.what == UPDATE_CONDITIONS) {
- handleUpdateConditions((Condition[])msg.obj);
- }
- }
- }
-
- private final ZenModeController.Callback mCallback = new ZenModeController.Callback() {
- @Override
- public void onZenChanged(boolean zen) {
- updateZen(zen);
- }
- public void onConditionsChanged(Condition[] conditions) {
- updateConditions(conditions);
- }
- };
-
- private final class ConditionAdapter extends ArrayAdapter<Condition> {
- private final LayoutInflater mInflater;
- private final HashSet<RadioButton> mRadioButtons = new HashSet<RadioButton>();
-
- public ConditionAdapter(Context context) {
- super(context, 0);
- mInflater = LayoutInflater.from(new ContextThemeWrapper(context, R.style.QSWhiteTheme));
- }
-
- @Override
- public View getView(int position, View convertView, ViewGroup parent) {
- final Condition condition = getItem(position);
- final boolean enabled = condition.state == Condition.STATE_TRUE;
-
- final View row = convertView != null ? convertView : mInflater
- .inflate(R.layout.qs_zen_mode_detail_condition, parent, false);
- final RadioButton rb = (RadioButton) row.findViewById(android.R.id.checkbox);
- mRadioButtons.add(rb);
- rb.setEnabled(enabled);
- rb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
- @Override
- public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
- if (isChecked) {
- for (RadioButton otherButton : mRadioButtons) {
- if (otherButton == rb) continue;
- otherButton.setChecked(false);
- }
- select(condition);
- }
- }
- });
- final TextView title = (TextView) row.findViewById(android.R.id.title);
- title.setText(condition.summary);
- title.setEnabled(enabled);
- title.setAlpha(enabled ? 1 : .5f);
- final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1);
- button1.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- rb.setChecked(true);
- editTimeCondition(-1);
- }
- });
-
- final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2);
- button2.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- rb.setChecked(true);
- editTimeCondition(1);
- }
- });
- title.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- rb.setChecked(true);
- }
- });
- if (position != 0) {
- button1.setVisibility(View.GONE);
- button2.setVisibility(View.GONE);
- }
- if (position == 0 && mRadioButtons.size() == 1) {
- rb.setChecked(true);
- }
- return row;
- }
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeTile.java
deleted file mode 100644
index bfa9c19..0000000
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ZenModeTile.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Copyright (C) 2014 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.qs.tiles;
-
-import android.content.Context;
-import android.util.Log;
-import android.view.ContextThemeWrapper;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import com.android.systemui.R;
-import com.android.systemui.qs.QSTile;
-import com.android.systemui.statusbar.policy.ZenModeController;
-
-/** Quick settings tile: Zen mode **/
-public class ZenModeTile extends QSTile<QSTile.BooleanState> {
- private final ZenModeController mController;
-
- public ZenModeTile(Host host) {
- super(host);
- mController = host.getZenModeController();
- }
-
- @Override
- public View createDetailView(Context context, ViewGroup root) {
- final Context themedContext = new ContextThemeWrapper(mContext, R.style.QSAccentTheme);
- final ZenModeDetail v = (ZenModeDetail) LayoutInflater.from(themedContext)
- .inflate(R.layout.qs_zen_mode_detail, root, false);
- v.init(this);
- return v;
- }
-
- @Override
- protected BooleanState newTileState() {
- return new BooleanState();
- }
-
- @Override
- public void setListening(boolean listening) {
- if (listening) {
- mController.addCallback(mCallback);
- } else {
- mController.removeCallback(mCallback);
- }
- }
-
- @Override
- protected void handleClick() {
- final boolean newZen = !mState.value;
- mController.setZen(newZen);
- if (newZen) {
- showDetail(true);
- }
- }
-
- @Override
- protected void handleUpdateState(BooleanState state, Object arg) {
- final boolean zen = arg instanceof Boolean ? (Boolean)arg : mController.isZen();
- state.value = zen;
- state.visible = true;
- state.iconId = zen ? R.drawable.ic_qs_zen_on : R.drawable.ic_qs_zen_off;
- state.label = mContext.getString(R.string.zen_mode_title);
- }
-
- private final ZenModeController.Callback mCallback = new ZenModeController.Callback() {
- @Override
- public void onZenChanged(boolean zen) {
- if (DEBUG) Log.d(TAG, "onZenChanged " + zen);
- refreshState(zen);
- }
- };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
index be1d47a..ca9bb94 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/AlternateRecentsComponent.java
@@ -35,6 +35,7 @@ import android.os.IBinder;
import android.os.Message;
import android.os.Messenger;
import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.util.DisplayMetrics;
import android.view.Display;
@@ -49,7 +50,7 @@ import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
/** A proxy implementation for the recents component */
-public class AlternateRecentsComponent {
+public class AlternateRecentsComponent implements ActivityOptions.OnAnimationStartedListener {
/** A handler for messages from the recents implementation */
class RecentsMessageHandler extends Handler {
@@ -126,6 +127,7 @@ public class AlternateRecentsComponent {
final public static int MSG_SHOW_RECENTS = 4;
final public static int MSG_HIDE_RECENTS = 5;
final public static int MSG_TOGGLE_RECENTS = 6;
+ final public static int MSG_START_ENTER_ANIMATION = 7;
final public static String EXTRA_ANIMATING_WITH_THUMBNAIL = "recents.animatingWithThumbnail";
final public static String EXTRA_FROM_ALT_TAB = "recents.triggeredFromAltTab";
@@ -405,7 +407,7 @@ public class AlternateRecentsComponent {
}
return ActivityOptions.makeThumbnailScaleDownAnimation(mStatusBarView, thumbnail,
- taskRect.left, taskRect.top, null);
+ taskRect.left, taskRect.top, this);
}
/** Returns whether the recents is currently running */
@@ -529,4 +531,18 @@ public class AlternateRecentsComponent {
mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
}
}
+
+
+ /**** OnAnimationStartedListener Implementation ****/
+
+ @Override
+ public void onAnimationStarted() {
+ // Notify recents to start the enter animation
+ try {
+ Message msg = Message.obtain(null, MSG_START_ENTER_ANIMATION, 0, 0);
+ mService.send(msg);
+ } catch (RemoteException re) {
+ re.printStackTrace();
+ }
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/Constants.java b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
index e979afd..4db81bf 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/Constants.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/Constants.java
@@ -36,7 +36,7 @@ public class Constants {
// Enables the search bar layout
public static final boolean EnableSearchLayout = true;
// Enables the dynamic shadows behind each task
- public static final boolean EnableShadows = false;
+ public static final boolean EnableShadows = true;
// This disables the bitmap and icon caches
public static final boolean DisableBackgroundCache = false;
// For debugging, this enables us to create mock recents tasks
@@ -113,4 +113,4 @@ public class Constants {
public static final int StackPeekNumCards = 3;
}
}
-} \ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
index befe8b4..df387c1 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsActivity.java
@@ -98,6 +98,9 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
// If there are no filtered stacks, dismiss recents and launch the first task
dismissRecentsIfVisible();
}
+ } else if (action.equals(RecentsService.ACTION_START_ENTER_ANIMATION)) {
+ // Try and start the enter animation
+ mRecentsView.startOnEnterAnimation();
}
}
};
@@ -345,6 +348,7 @@ public class RecentsActivity extends Activity implements RecentsView.RecentsView
IntentFilter filter = new IntentFilter();
filter.addAction(RecentsService.ACTION_HIDE_RECENTS_ACTIVITY);
filter.addAction(RecentsService.ACTION_TOGGLE_RECENTS_ACTIVITY);
+ filter.addAction(RecentsService.ACTION_START_ENTER_ANIMATION);
registerReceiver(mServiceBroadcastReceiver, filter);
// Register the broadcast receiver to handle messages when the screen is turned off
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
index 03f7e36..1ae7a0d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsConfiguration.java
@@ -46,7 +46,9 @@ public class RecentsConfiguration {
public float animationPxMovementPerSecond;
- public Interpolator defaultBezierInterpolator;
+ public Interpolator fastOutSlowInInterpolator;
+ public Interpolator fastOutLinearInInterpolator;
+ public Interpolator linearOutSlowInInterpolator;
public int filteringCurrentViewsMinAnimDuration;
public int filteringNewViewsMinAnimDuration;
@@ -59,6 +61,7 @@ public class RecentsConfiguration {
public int taskViewRemoveAnimTranslationXPx;
public int taskViewTranslationZMinPx;
public int taskViewTranslationZIncrementPx;
+ public int taskViewShadowOutlineBottomInsetPx;
public int taskViewRoundedCornerRadiusPx;
public int searchBarSpaceHeightPx;
@@ -130,6 +133,8 @@ public class RecentsConfiguration {
taskViewTranslationZMinPx = res.getDimensionPixelSize(R.dimen.recents_task_view_z_min);
taskViewTranslationZIncrementPx =
res.getDimensionPixelSize(R.dimen.recents_task_view_z_increment);
+ taskViewShadowOutlineBottomInsetPx =
+ res.getDimensionPixelSize(R.dimen.recents_task_view_shadow_outline_bottom_inset);
searchBarSpaceHeightPx = res.getDimensionPixelSize(R.dimen.recents_search_bar_space_height);
taskBarViewDefaultBackgroundColor =
@@ -141,8 +146,12 @@ public class RecentsConfiguration {
taskBarViewDarkTextColor =
res.getColor(R.color.recents_task_bar_dark_text_color);
- defaultBezierInterpolator = AnimationUtils.loadInterpolator(context,
+ fastOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
com.android.internal.R.interpolator.fast_out_slow_in);
+ fastOutLinearInInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.fast_out_linear_in);
+ linearOutSlowInInterpolator = AnimationUtils.loadInterpolator(context,
+ com.android.internal.R.interpolator.linear_out_slow_in);
// Check if the developer options are enabled
ContentResolver cr = context.getContentResolver();
@@ -167,6 +176,13 @@ public class RecentsConfiguration {
appWidgetId).apply();
}
+ /** Called when the configuration has changed, and we want to reset any configuration specific
+ * members. */
+ public void updateOnConfigurationChange() {
+ launchedFromAltTab = false;
+ launchedWithThumbnailAnimation = false;
+ }
+
/** Returns whether the search bar app widget exists */
public boolean hasSearchBarAppWidget() {
return searchBarAppWidgetId >= 0;
diff --git a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
index c4c910b..0c2c11d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/RecentsService.java
@@ -55,7 +55,8 @@ class SystemUIMessageHandler extends Handler {
if (msg.what == AlternateRecentsComponent.MSG_UPDATE_FOR_CONFIGURATION) {
RecentsTaskLoader.initialize(context);
- RecentsConfiguration.reinitialize(context);
+ RecentsConfiguration config = RecentsConfiguration.reinitialize(context);
+ config.updateOnConfigurationChange();
try {
Bundle data = msg.getData();
@@ -73,7 +74,6 @@ class SystemUIMessageHandler extends Handler {
// Get the task stack and search bar bounds
Rect taskStackBounds = new Rect();
- RecentsConfiguration config = RecentsConfiguration.getInstance();
config.getTaskStackBounds(windowRect.width(), windowRect.height(), taskStackBounds);
// Calculate the target task rect for when there is one task.
@@ -136,6 +136,11 @@ class SystemUIMessageHandler extends Handler {
Constants.Log.App.TimeRecentsStartupKey, "receivedToggleRecents");
Console.logTraceTime(Constants.Log.App.TimeRecentsLaunchTask,
Constants.Log.App.TimeRecentsLaunchKey, "receivedToggleRecents");
+ } else if (msg.what == AlternateRecentsComponent.MSG_START_ENTER_ANIMATION) {
+ // Send a broadcast to start the enter animation
+ Intent intent = new Intent(RecentsService.ACTION_START_ENTER_ANIMATION);
+ intent.setPackage(context.getPackageName());
+ context.sendBroadcast(intent);
}
}
}
@@ -144,6 +149,7 @@ class SystemUIMessageHandler extends Handler {
public class RecentsService extends Service {
final static String ACTION_HIDE_RECENTS_ACTIVITY = "action_hide_recents_activity";
final static String ACTION_TOGGLE_RECENTS_ACTIVITY = "action_toggle_recents_activity";
+ final static String ACTION_START_ENTER_ANIMATION = "action_start_enter_animation";
final static String EXTRA_TRIGGERED_FROM_ALT_TAB = "extra_triggered_from_alt_tab";
Messenger mSystemUIMessenger = new Messenger(new SystemUIMessageHandler(this));
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
index cad9ce5..6005275 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/RecentsView.java
@@ -158,6 +158,18 @@ public class RecentsView extends FrameLayout implements TaskStackView.TaskStackV
return false;
}
+ /** Requests all task stacks to start their enter-recents animation */
+ public void startOnEnterAnimation() {
+ int childCount = getChildCount();
+ for (int i = 0; i < childCount; i++) {
+ View child = getChildAt(i);
+ if (child instanceof TaskStackView) {
+ TaskStackView stackView = (TaskStackView) child;
+ stackView.startOnEnterAnimation();
+ }
+ }
+ }
+
/** Adds the search bar */
public void setSearchBar(View searchBar) {
// Create the search bar (and hide it if we have no recent tasks)
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
index 3ee0545..cae6bd7 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/SwipeHelper.java
@@ -278,6 +278,7 @@ public class SwipeHelper {
if (FADE_OUT_DURING_SWIPE && canAnimViewBeDismissed) {
view.setAlpha(getAlphaForOffset(view));
}
+ mCallback.onSwipeChanged(mCurrView, view.getTranslationX());
}
});
anim.addListener(new AnimatorListenerAdapter() {
@@ -313,6 +314,7 @@ public class SwipeHelper {
if (mCurrView != null) {
float delta = getPos(ev) - mInitialTouchPos;
setSwipeAmount(delta);
+ mCallback.onSwipeChanged(mCurrView, delta);
}
break;
case MotionEvent.ACTION_UP:
@@ -393,6 +395,8 @@ public class SwipeHelper {
void onBeginDrag(View v);
+ void onSwipeChanged(View v, float delta);
+
void onChildDismissed(View v);
void onSnapBackCompleted(View v);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
index 07caa1b..9e6c98e 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskBarView.java
@@ -16,7 +16,6 @@
package com.android.systemui.recents.views;
-import android.animation.ValueAnimator;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.drawable.Drawable;
@@ -81,7 +80,7 @@ class TaskBarView extends FrameLayout {
.alpha(toTransform.dismissAlpha)
.setStartDelay(0)
.setDuration(duration)
- .setInterpolator(config.defaultBezierInterpolator)
+ .setInterpolator(config.fastOutSlowInInterpolator)
.withLayer()
.start();
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
index 75893aa..1fbaf87 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskStackView.java
@@ -23,7 +23,6 @@ import android.animation.ValueAnimator;
import android.app.Activity;
import android.content.ComponentName;
import android.content.Context;
-import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Rect;
import android.graphics.Region;
@@ -88,6 +87,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
int mStackViewsAnimationDuration;
boolean mStackViewsDirty = true;
boolean mAwaitingFirstLayout = true;
+ boolean mStartEnterAnimationRequestedAfterLayout;
int[] mTmpVisibleRange = new int[2];
Rect mTmpRect = new Rect();
Rect mTmpRect2 = new Rect();
@@ -353,7 +353,7 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
mScrollAnimator = ObjectAnimator.ofInt(this, "stackScroll", curScroll, newScroll);
mScrollAnimator.setDuration(Utilities.calculateTranslationAnimationDuration(newScroll -
curScroll, 250));
- mScrollAnimator.setInterpolator(RecentsConfiguration.getInstance().defaultBezierInterpolator);
+ mScrollAnimator.setInterpolator(RecentsConfiguration.getInstance().fastOutSlowInInterpolator);
mScrollAnimator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
public void onAnimationUpdate(ValueAnimator animation) {
@@ -712,19 +712,6 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
setStackScrollToInitialState();
requestSynchronizeStackViewsWithModel();
synchronizeStackViewsWithModel();
-
- // Update the focused task index to be the next item to the top task
- if (config.launchedFromAltTab) {
- focusTask(Math.max(0, mStack.getTaskCount() - 2), false);
- }
-
- // Animate the task bar of the first task view
- if (config.launchedWithThumbnailAnimation) {
- TaskView tv = (TaskView) getChildAt(getChildCount() - 1);
- if (tv != null) {
- tv.animateOnEnterRecents();
- }
- }
}
// Measure each of the children
@@ -767,7 +754,47 @@ public class TaskStackView extends FrameLayout implements TaskStack.TaskStackCal
}
if (mAwaitingFirstLayout) {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+
+ // Update the focused task index to be the next item to the top task
+ if (config.launchedFromAltTab) {
+ focusTask(Math.max(0, mStack.getTaskCount() - 2), false);
+ }
+
+ // Prepare the first view for its enter animation
+ if (config.launchedWithThumbnailAnimation) {
+ TaskView tv = (TaskView) getChildAt(getChildCount() - 1);
+ if (tv != null) {
+ tv.prepareAnimateOnEnterRecents();
+ }
+ }
+
+ // Mark that we have completely the first layout
mAwaitingFirstLayout = false;
+
+ // If the enter animation started already and we haven't completed a layout yet, do the
+ // enter animation now
+ if (mStartEnterAnimationRequestedAfterLayout) {
+ startOnEnterAnimation();
+ }
+ }
+ }
+
+ /** Requests this task stacks to start it's enter-recents animation */
+ public void startOnEnterAnimation() {
+ RecentsConfiguration config = RecentsConfiguration.getInstance();
+ if (!config.launchedWithThumbnailAnimation) return;
+
+ // If we are still waiting to layout, then just defer until then
+ if (mAwaitingFirstLayout) {
+ mStartEnterAnimationRequestedAfterLayout = true;
+ return;
+ }
+
+ // Animate the task bar of the first task view
+ TaskView tv = (TaskView) getChildAt(getChildCount() - 1);
+ if (tv != null) {
+ tv.animateOnEnterRecents();
}
}
@@ -1538,6 +1565,11 @@ class TaskStackViewTouchHandler implements SwipeHelper.Callback {
}
@Override
+ public void onSwipeChanged(View v, float delta) {
+ // Do nothing
+ }
+
+ @Override
public void onChildDismissed(View v) {
TaskView tv = (TaskView) v;
mSv.onTaskDismissed(tv);
diff --git a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
index 8575661..ffa181d 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/views/TaskView.java
@@ -21,7 +21,6 @@ import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Outline;
-import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.graphics.Rect;
@@ -113,7 +112,8 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
// Update the outline
Outline o = new Outline();
- o.setRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight(), radius);
+ o.setRoundRect(0, 0, getMeasuredWidth(), getMeasuredHeight() -
+ config.taskViewShadowOutlineBottomInsetPx, radius);
setOutline(o);
}
@@ -167,7 +167,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
.scaleY(toTransform.scale)
.alpha(toTransform.alpha)
.setDuration(duration)
- .setInterpolator(config.defaultBezierInterpolator)
+ .setInterpolator(config.fastOutSlowInInterpolator)
.withLayer()
.setUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
@Override
@@ -221,14 +221,21 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
fromTransform.alpha = 0f;
}
+ /** Prepares this task view for the enter-recents animations. This is called earlier in the
+ * first layout because the actual animation into recents may take a long time. */
+ public void prepareAnimateOnEnterRecents() {
+ mBarView.setVisibility(View.INVISIBLE);
+ }
+
/** Animates this task view as it enters recents */
public void animateOnEnterRecents() {
RecentsConfiguration config = RecentsConfiguration.getInstance();
- mBarView.setAlpha(0f);
+ mBarView.setVisibility(View.VISIBLE);
+ mBarView.setTranslationY(-mBarView.getMeasuredHeight());
mBarView.animate()
- .alpha(1f)
- .setStartDelay(300)
- .setInterpolator(config.defaultBezierInterpolator)
+ .translationY(0)
+ .setStartDelay(200)
+ .setInterpolator(config.fastOutSlowInInterpolator)
.setDuration(config.taskBarEnterAnimDuration)
.withLayer()
.start();
@@ -238,9 +245,9 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
public void animateOnLeavingRecents(final Runnable r) {
RecentsConfiguration config = RecentsConfiguration.getInstance();
mBarView.animate()
- .alpha(0f)
+ .translationY(-mBarView.getMeasuredHeight())
.setStartDelay(0)
- .setInterpolator(config.defaultBezierInterpolator)
+ .setInterpolator(config.fastOutLinearInInterpolator)
.setDuration(config.taskBarExitAnimDuration)
.withLayer()
.withEndAction(new Runnable() {
@@ -261,7 +268,7 @@ public class TaskView extends FrameLayout implements Task.TaskCallbacks, View.On
animate().translationX(config.taskViewRemoveAnimTranslationXPx)
.alpha(0f)
.setStartDelay(0)
- .setInterpolator(config.defaultBezierInterpolator)
+ .setInterpolator(config.fastOutSlowInInterpolator)
.setDuration(config.taskViewRemoveAnimDuration)
.withLayer()
.withEndAction(new Runnable() {
diff --git a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
index 27881c4..65e1cc6 100644
--- a/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/settings/BrightnessDialog.java
@@ -72,8 +72,7 @@ public class BrightnessDialog extends Dialog implements
window.setGravity(Gravity.TOP);
WindowManager.LayoutParams lp = window.getAttributes();
// Offset from the top
- lp.y = getContext().getResources().getDimensionPixelOffset(
- com.android.internal.R.dimen.volume_panel_top);
+ lp.y = getContext().getResources().getDimensionPixelOffset(R.dimen.volume_panel_top);
lp.type = WindowManager.LayoutParams.TYPE_VOLUME_OVERLAY;
lp.privateFlags |=
WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index e3dac4a..dcd187c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -149,6 +149,7 @@ public abstract class ActivatableNotificationView extends ExpandableOutlineView
super.onFinishInflate();
mBackgroundNormal = (NotificationBackgroundView) findViewById(R.id.backgroundNormal);
mBackgroundDimmed = (NotificationBackgroundView) findViewById(R.id.backgroundDimmed);
+ updateBackground();
updateBackgroundResources();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/AlphaImageView.java b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaImageView.java
new file mode 100644
index 0000000..06dc4e6
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/AlphaImageView.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2014 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.util.AttributeSet;
+import android.widget.ImageView;
+
+/**
+ * An ImageView which does not have overlapping renderings commands and therefore does not need a
+ * layer when alpha is changed.
+ */
+public class AlphaImageView extends ImageView {
+ public AlphaImageView(Context context) {
+ super(context);
+ }
+
+ public AlphaImageView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ }
+
+ public AlphaImageView(Context context, AttributeSet attrs, int defStyleAttr) {
+ super(context, attrs, defStyleAttr);
+ }
+
+ public AlphaImageView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
+ super(context, attrs, defStyleAttr, defStyleRes);
+ }
+
+ @Override
+ public boolean hasOverlappingRendering() {
+ return false;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
index 9435e85..21b41c7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBar.java
@@ -48,6 +48,7 @@ import android.provider.Settings;
import android.service.dreams.DreamService;
import android.service.dreams.IDreamManager;
import android.service.notification.NotificationListenerService;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.text.TextUtils;
import android.util.Log;
@@ -77,19 +78,22 @@ import com.android.systemui.R;
import com.android.systemui.RecentsComponent;
import com.android.systemui.SearchPanelView;
import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.NotificationData.Entry;
import com.android.systemui.statusbar.phone.KeyguardTouchDelegate;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
import java.util.Locale;
+import static com.android.keyguard.KeyguardHostView.OnDismissAction;
+
public abstract class BaseStatusBar extends SystemUI implements
CommandQueue.Callbacks, ActivatableNotificationView.OnActivatedListener {
public static final String TAG = "StatusBar";
public static final boolean DEBUG = false;
public static final boolean MULTIUSER_DEBUG = false;
- private static final boolean USE_NOTIFICATION_LISTENER = false;
+ private static final boolean USE_NOTIFICATION_LISTENER = true;
protected static final int MSG_SHOW_RECENT_APPS = 1019;
protected static final int MSG_HIDE_RECENT_APPS = 1020;
@@ -178,6 +182,7 @@ public abstract class BaseStatusBar extends SystemUI implements
*/
protected int mState;
protected boolean mBouncerShowing;
+ protected boolean mShowLockscreenNotifications;
protected NotificationOverflowContainer mKeyguardIconOverflowContainer;
@@ -192,11 +197,14 @@ public abstract class BaseStatusBar extends SystemUI implements
mContext.getContentResolver(), Settings.Global.DEVICE_PROVISIONED, 0);
if (provisioned != mDeviceProvisioned) {
mDeviceProvisioned = provisioned;
- updateNotificationIcons();
+ updateNotifications();
}
final int mode = Settings.Global.getInt(mContext.getContentResolver(),
Settings.Global.ZEN_MODE, Settings.Global.ZEN_MODE_OFF);
setZenMode(mode);
+ final boolean show = Settings.Global.getInt(mContext.getContentResolver(),
+ Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS, 1) != 0;
+ setShowLockscreenNotifications(show);
}
};
@@ -207,39 +215,53 @@ public abstract class BaseStatusBar extends SystemUI implements
// so we just dump our cache ...
mUsersAllowingPrivateNotifications.clear();
// ... and refresh all the notifications
- updateNotificationIcons();
+ updateNotifications();
}
};
private RemoteViews.OnClickHandler mOnClickHandler = new RemoteViews.OnClickHandler() {
@Override
- public boolean onClickHandler(View view, PendingIntent pendingIntent, Intent fillInIntent) {
+ public boolean onClickHandler(
+ final View view, final PendingIntent pendingIntent, final Intent fillInIntent) {
if (DEBUG) {
Log.v(TAG, "Notification click handler invoked for intent: " + pendingIntent);
}
final boolean isActivity = pendingIntent.isActivity();
if (isActivity) {
- 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();
- // Also, notifications can be launched from the lock screen,
- // so dismiss the lock screen when the activity starts.
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
- } catch (RemoteException e) {
- }
- }
+ startNotificationActivity(new OnDismissAction() {
+ @Override
+ public boolean onDismiss() {
+ 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();
+ // Also, notifications can be launched from the lock screen,
+ // so dismiss the lock screen when the activity starts.
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } catch (RemoteException e) {
+ }
- boolean handled = super.onClickHandler(view, pendingIntent, fillInIntent);
+ boolean handled = superOnClickHandler(view, pendingIntent, fillInIntent);
- if (isActivity && handled) {
- // close the shade if it was open
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
- visibilityChanged(false);
+ // close the shade if it was open
+ if (handled) {
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
+ visibilityChanged(false);
+ }
+ return handled; // Wait for activity start.
+ }
+ });
+ return true;
+ } else {
+ return super.onClickHandler(view, pendingIntent, fillInIntent);
}
- return handled;
+ }
+
+ private boolean superOnClickHandler(View view, PendingIntent pendingIntent,
+ Intent fillInIntent) {
+ return super.onClickHandler(view, pendingIntent, fillInIntent);
}
};
@@ -264,11 +286,12 @@ public abstract class BaseStatusBar extends SystemUI implements
public void onListenerConnected() {
if (DEBUG) Log.d(TAG, "onListenerConnected");
final StatusBarNotification[] notifications = getActiveNotifications();
+ final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
for (StatusBarNotification sbn : notifications) {
- addNotificationInternal(sbn);
+ addNotificationInternal(sbn, currentRanking);
}
}
});
@@ -277,13 +300,14 @@ public abstract class BaseStatusBar extends SystemUI implements
@Override
public void onNotificationPosted(final StatusBarNotification sbn) {
if (DEBUG) Log.d(TAG, "onNotificationPosted: " + sbn);
+ final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
if (mNotificationData.findByKey(sbn.getKey()) != null) {
- updateNotificationInternal(sbn);
+ updateNotificationInternal(sbn, currentRanking);
} else {
- addNotificationInternal(sbn);
+ addNotificationInternal(sbn, currentRanking);
}
}
});
@@ -292,10 +316,24 @@ public abstract class BaseStatusBar extends SystemUI implements
@Override
public void onNotificationRemoved(final StatusBarNotification sbn) {
if (DEBUG) Log.d(TAG, "onNotificationRemoved: " + sbn);
+ final Ranking currentRanking = getCurrentRanking();
mHandler.post(new Runnable() {
@Override
public void run() {
- removeNotificationInternal(sbn.getKey());
+ removeNotificationInternal(sbn.getKey(), currentRanking);
+ }
+ });
+ }
+
+ @Override
+ public void onNotificationRankingUpdate() {
+ if (DEBUG) Log.d(TAG, "onRankingUpdate");
+ final Ranking currentRanking = getCurrentRanking();
+ mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ mNotificationData.updateRanking(currentRanking);
+ updateNotifications();
}
});
}
@@ -328,6 +366,9 @@ public abstract class BaseStatusBar extends SystemUI implements
mContext.getContentResolver().registerContentObserver(
Settings.Global.getUriFor(Settings.Global.ZEN_MODE), false,
mSettingsObserver);
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.LOCK_SCREEN_SHOW_NOTIFICATIONS), false,
+ mSettingsObserver);
mContext.getContentResolver().registerContentObserver(
Settings.Secure.getUriFor(Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS),
@@ -434,6 +475,14 @@ public abstract class BaseStatusBar extends SystemUI implements
}
}
+ /**
+ * Takes the necessary steps to prepare the status bar for starting an activity, then starts it.
+ * @param action A dismiss action that is called if it's safe to start the activity.
+ */
+ protected void startNotificationActivity(OnDismissAction action) {
+ action.onDismiss();
+ }
+
@Override
protected void onConfigurationChanged(Configuration newConfig) {
final Locale locale = mContext.getResources().getConfiguration().locale;
@@ -999,47 +1048,55 @@ public abstract class BaseStatusBar extends SystemUI implements
mIsHeadsUp = forHun;
}
- 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();
- // Also, notifications can be launched from the lock screen,
- // so dismiss the lock screen when the activity starts.
- ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
- } catch (RemoteException e) {
- }
+ public void onClick(final View v) {
+ startNotificationActivity(new OnDismissAction() {
+ public boolean onDismiss() {
+ 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();
+ // Also, notifications can be launched from the lock screen,
+ // so dismiss the lock screen when the activity starts.
+ ActivityManagerNative.getDefault().dismissKeyguardOnNextActivity();
+ } 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(mContext, 0, overlay);
- } catch (PendingIntent.CanceledException e) {
- // the stack trace isn't very helpful here. Just log the exception message.
- Log.w(TAG, "Sending contentIntent failed: " + e);
- }
+ boolean sent = false;
+ 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(mContext, 0, overlay);
+ sent = true;
+ } catch (PendingIntent.CanceledException e) {
+ // the stack trace isn't very helpful here.
+ // Just log the exception message.
+ Log.w(TAG, "Sending contentIntent failed: " + e);
+ }
+ }
- KeyguardTouchDelegate.getInstance(mContext).dismiss();
- }
+ try {
+ if (mIsHeadsUp) {
+ mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
+ }
+ mBarService.onNotificationClick(mNotificationKey);
+ } catch (RemoteException ex) {
+ // system process is dead if we're here.
+ }
- try {
- if (mIsHeadsUp) {
- mHandler.sendEmptyMessage(MSG_HIDE_HEADS_UP);
- }
- mBarService.onNotificationClick(mNotificationKey);
- } catch (RemoteException ex) {
- // system process is dead if we're here.
- }
+ // close the shade if it was open
+ animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
+ visibilityChanged(false);
- // close the shade if it was open
- animateCollapsePanels(CommandQueue.FLAG_EXCLUDE_NONE);
- visibilityChanged(false);
+ boolean waitForActivityLaunch = sent && mIntent.isActivity();
+ return waitForActivityLaunch;
+ }
+ });
}
}
@@ -1081,19 +1138,13 @@ public abstract class BaseStatusBar extends SystemUI implements
}
}
- protected StatusBarNotification removeNotificationViews(String key) {
- NotificationData.Entry entry = mNotificationData.remove(key);
+ protected StatusBarNotification removeNotificationViews(String key, Ranking ranking) {
+ NotificationData.Entry entry = mNotificationData.remove(key, ranking);
if (entry == null) {
Log.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);
- updateRowStates();
- updateNotificationIcons();
- updateSpeedBump();
-
+ updateNotifications();
return entry.notification;
}
@@ -1127,35 +1178,17 @@ public abstract class BaseStatusBar extends SystemUI implements
return entry;
}
- protected void addNotificationViews(NotificationData.Entry entry) {
+ protected void addNotificationViews(Entry entry, Ranking ranking) {
if (entry == null) {
return;
}
// Add the expanded view and icon.
- int pos = mNotificationData.add(entry);
- if (DEBUG) {
- Log.d(TAG, "addNotificationViews: added at " + pos);
- }
- updateRowStates();
- updateNotificationIcons();
- updateSpeedBump();
+ mNotificationData.add(entry, ranking);
+ updateNotifications();
}
- protected void updateSpeedBump() {
- int n = mNotificationData.size();
- int speedBumpIndex = -1;
- for (int i = n-1; i >= 0; i--) {
- NotificationData.Entry entry = mNotificationData.get(i);
- if (entry.row.getVisibility() != View.GONE && speedBumpIndex == -1
- && entry.row.isBelowSpeedBump() ) {
- speedBumpIndex = n - 1 - i;
- }
- }
- mStackScroller.updateSpeedBumpIndex(speedBumpIndex);
- }
-
- private void addNotificationViews(StatusBarNotification notification) {
- addNotificationViews(createNotificationViews(notification));
+ private void addNotificationViews(StatusBarNotification notification, Ranking ranking) {
+ addNotificationViews(createNotificationViews(notification), ranking);
}
/**
@@ -1169,17 +1202,17 @@ public abstract class BaseStatusBar extends SystemUI implements
protected void updateRowStates() {
int maxKeyguardNotifications = getMaxKeyguardNotifications();
mKeyguardIconOverflowContainer.getIconsView().removeAllViews();
- int n = mNotificationData.size();
+ final int N = mNotificationData.size();
int visibleNotifications = 0;
boolean onKeyguard = mState == StatusBarState.KEYGUARD;
- for (int i = n-1; i >= 0; i--) {
+ for (int i = 0; i < N; i++) {
NotificationData.Entry entry = mNotificationData.get(i);
if (onKeyguard) {
entry.row.setExpansionDisabled(true);
} else {
entry.row.setExpansionDisabled(false);
if (!entry.row.isUserLocked()) {
- boolean top = (i == n-1);
+ boolean top = (i == 0);
entry.row.setSystemExpanded(top);
}
}
@@ -1206,6 +1239,9 @@ public abstract class BaseStatusBar extends SystemUI implements
} else {
mKeyguardIconOverflowContainer.setVisibility(View.GONE);
}
+ // Move overflow container to last position.
+ mStackScroller.changeViewPosition(mKeyguardIconOverflowContainer,
+ mStackScroller.getChildCount() - 1);
}
private boolean shouldShowOnKeyguard(StatusBarNotification sbn) {
@@ -1215,46 +1251,46 @@ public abstract class BaseStatusBar extends SystemUI implements
protected void setZenMode(int mode) {
if (!isDeviceProvisioned()) return;
mZenMode = mode;
- updateNotificationIcons();
+ updateNotifications();
+ }
+
+ protected void setShowLockscreenNotifications(boolean show) {
+ mShowLockscreenNotifications = show;
}
protected abstract void haltTicker();
protected abstract void setAreThereNotifications();
- protected abstract void updateNotificationIcons();
+ protected abstract void updateNotifications();
protected abstract void tick(StatusBarNotification n, boolean firstTime);
protected abstract void updateExpandedViewPos(int expandedPosition);
protected abstract boolean shouldDisableNavbarGestures();
- protected boolean isTopNotification(ViewGroup parent, NotificationData.Entry entry) {
- return parent != null && parent.indexOfChild(entry.row) == 0;
- }
-
-
@Override
public void addNotification(StatusBarNotification notification) {
if (!USE_NOTIFICATION_LISTENER) {
- addNotificationInternal(notification);
+ addNotificationInternal(notification, null);
}
}
- public abstract void addNotificationInternal(StatusBarNotification notification);
+ public abstract void addNotificationInternal(StatusBarNotification notification,
+ Ranking ranking);
@Override
public void removeNotification(String key) {
if (!USE_NOTIFICATION_LISTENER) {
- removeNotificationInternal(key);
+ removeNotificationInternal(key, null);
}
}
- protected abstract void removeNotificationInternal(String key);
+ protected abstract void removeNotificationInternal(String key, Ranking ranking);
public void updateNotification(StatusBarNotification notification) {
if (!USE_NOTIFICATION_LISTENER) {
- updateNotificationInternal(notification);
+ updateNotificationInternal(notification, null);
}
}
- public void updateNotificationInternal(StatusBarNotification notification) {
+ public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
if (DEBUG) Log.d(TAG, "updateNotification(" + notification + ")");
final NotificationData.Entry oldEntry = mNotificationData.findByKey(notification.getKey());
@@ -1326,18 +1362,12 @@ public abstract class BaseStatusBar extends SystemUI implements
&& oldPublicContentView.getPackage().equals(publicContentView.getPackage())
&& oldPublicContentView.getLayoutId() == publicContentView.getLayoutId());
- ViewGroup rowParent = (ViewGroup) oldEntry.row.getParent();
- boolean orderUnchanged =
- notification.getNotification().when == oldNotification.getNotification().when
- && notification.getScore() == oldNotification.getScore();
- // score now encompasses/supersedes isOngoing()
boolean updateTicker = notification.getNotification().tickerText != null
&& !TextUtils.equals(notification.getNotification().tickerText,
oldEntry.notification.getNotification().tickerText);
- boolean isTopAnyway = isTopNotification(rowParent, oldEntry);
- if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged && publicUnchanged
- && (orderUnchanged || isTopAnyway)) {
+ if (contentsUnchanged && bigContentsUnchanged && headsUpContentsUnchanged
+ && publicUnchanged) {
if (DEBUG) Log.d(TAG, "reusing notification for key: " + notification.getKey());
oldEntry.notification = notification;
try {
@@ -1365,22 +1395,20 @@ public abstract class BaseStatusBar extends SystemUI implements
handleNotificationError(notification, "Couldn't update icon: " + ic);
return;
}
- updateRowStates();
- updateSpeedBump();
+ mNotificationData.updateRanking(ranking);
+ updateNotifications();
}
catch (RuntimeException e) {
// It failed to add cleanly. Log, and remove the view from the panel.
Log.w(TAG, "Couldn't reapply views for package " + contentView.getPackage(), e);
- removeNotificationViews(notification.getKey());
- addNotificationViews(notification);
+ removeNotificationViews(notification.getKey(), ranking);
+ addNotificationViews(notification, ranking);
}
} else {
if (DEBUG) Log.d(TAG, "not reusing notification for key: " + notification.getKey());
if (DEBUG) Log.d(TAG, "contents was " + (contentsUnchanged ? "unchanged" : "changed"));
- if (DEBUG) Log.d(TAG, "order was " + (orderUnchanged ? "unchanged" : "changed"));
- if (DEBUG) Log.d(TAG, "notification is " + (isTopAnyway ? "top" : "not top"));
- removeNotificationViews(notification.getKey());
- addNotificationViews(notification); // will also replace the heads up
+ removeNotificationViews(notification.getKey(), ranking);
+ addNotificationViews(notification, ranking); // will also replace the heads up
final NotificationData.Entry newEntry = mNotificationData.findByKey(
notification.getKey());
final boolean userChangedExpansion = oldEntry.row.hasUserChangedExpansion();
@@ -1527,5 +1555,12 @@ public abstract class BaseStatusBar extends SystemUI implements
mWindowManager.removeViewImmediate(mSearchPanelView);
}
mContext.unregisterReceiver(mBroadcastReceiver);
+ if (USE_NOTIFICATION_LISTENER) {
+ try {
+ mNotificationListener.unregisterAsSystemService();
+ } catch (RemoteException e) {
+ // Ignore.
+ }
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
index 7d576cb..5f1325b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/FlingAnimationUtils.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar;
import android.animation.ValueAnimator;
import android.content.Context;
+import android.view.ViewPropertyAnimator;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
@@ -46,6 +47,8 @@ public class FlingAnimationUtils {
private float mMaxLengthSeconds;
private float mHighVelocityPxPerSecond;
+ private AnimatorProperties mAnimatorProperties = new AnimatorProperties();
+
public FlingAnimationUtils(Context ctx, float maxLengthSeconds) {
mMaxLengthSeconds = maxLengthSeconds;
mLinearOutSlowIn = new PathInterpolator(0, 0, LINEAR_OUT_SLOW_IN_X2, 1);
@@ -80,18 +83,59 @@ public class FlingAnimationUtils {
* @param currValue the current value
* @param endValue the end value of the animator
* @param velocity the current velocity of the motion
+ */
+ public void apply(ViewPropertyAnimator animator, float currValue, float endValue,
+ float velocity) {
+ apply(animator, currValue, endValue, velocity, Math.abs(endValue - currValue));
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
* @param maxDistance the maximum distance for this interaction; the maximum animation length
* gets multiplied by the ratio between the actual distance and this value
*/
public void apply(ValueAnimator animator, float currValue, float endValue, float velocity,
float maxDistance) {
+ AnimatorProperties properties = getProperties(currValue, endValue, velocity,
+ maxDistance);
+ animator.setDuration(properties.duration);
+ animator.setInterpolator(properties.interpolator);
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
+ * @param maxDistance the maximum distance for this interaction; the maximum animation length
+ * gets multiplied by the ratio between the actual distance and this value
+ */
+ public void apply(ViewPropertyAnimator animator, float currValue, float endValue,
+ float velocity, float maxDistance) {
+ AnimatorProperties properties = getProperties(currValue, endValue, velocity,
+ maxDistance);
+ animator.setDuration(properties.duration);
+ animator.setInterpolator(properties.interpolator);
+ }
+
+ private AnimatorProperties getProperties(float currValue,
+ float endValue, float velocity, float maxDistance) {
float maxLengthSeconds = (float) (mMaxLengthSeconds
* Math.sqrt(Math.abs(endValue - currValue) / maxDistance));
float diff = Math.abs(endValue - currValue);
float velAbs = Math.abs(velocity);
float durationSeconds = LINEAR_OUT_SLOW_IN_START_GRADIENT * diff / velAbs;
if (durationSeconds <= maxLengthSeconds) {
- animator.setInterpolator(mLinearOutSlowIn);
+ mAnimatorProperties.interpolator = mLinearOutSlowIn;
} else if (velAbs >= mMinVelocityPxPerSecond) {
// Cross fade between fast-out-slow-in and linear interpolator with current velocity.
@@ -100,14 +144,15 @@ public class FlingAnimationUtils {
= new VelocityInterpolator(durationSeconds, velAbs, diff);
InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
velocityInterpolator, mLinearOutSlowIn, mLinearOutSlowIn);
- animator.setInterpolator(superInterpolator);
+ mAnimatorProperties.interpolator = superInterpolator;
} else {
// Just use a normal interpolator which doesn't take the velocity into account.
durationSeconds = maxLengthSeconds;
- animator.setInterpolator(mFastOutSlowIn);
+ mAnimatorProperties.interpolator = mFastOutSlowIn;
}
- animator.setDuration((long) (durationSeconds * 1000));
+ mAnimatorProperties.duration = (long) (durationSeconds * 1000);
+ return mAnimatorProperties;
}
/**
@@ -124,6 +169,34 @@ public class FlingAnimationUtils {
*/
public void applyDismissing(ValueAnimator animator, float currValue, float endValue,
float velocity, float maxDistance) {
+ AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity,
+ maxDistance);
+ animator.setDuration(properties.duration);
+ animator.setInterpolator(properties.interpolator);
+ }
+
+ /**
+ * Applies the interpolator and length to the animator, such that the fling animation is
+ * consistent with the finger motion for the case when the animation is making something
+ * disappear.
+ *
+ * @param animator the animator to apply
+ * @param currValue the current value
+ * @param endValue the end value of the animator
+ * @param velocity the current velocity of the motion
+ * @param maxDistance the maximum distance for this interaction; the maximum animation length
+ * gets multiplied by the ratio between the actual distance and this value
+ */
+ public void applyDismissing(ViewPropertyAnimator animator, float currValue, float endValue,
+ float velocity, float maxDistance) {
+ AnimatorProperties properties = getDismissingProperties(currValue, endValue, velocity,
+ maxDistance);
+ animator.setDuration(properties.duration);
+ animator.setInterpolator(properties.interpolator);
+ }
+
+ private AnimatorProperties getDismissingProperties(float currValue, float endValue,
+ float velocity, float maxDistance) {
float maxLengthSeconds = (float) (mMaxLengthSeconds
* Math.pow(Math.abs(endValue - currValue) / maxDistance, 0.5f));
float diff = Math.abs(endValue - currValue);
@@ -135,7 +208,7 @@ public class FlingAnimationUtils {
Interpolator mLinearOutFasterIn = new PathInterpolator(0, 0, 1, y2);
float durationSeconds = startGradient * diff / velAbs;
if (durationSeconds <= maxLengthSeconds) {
- animator.setInterpolator(mLinearOutFasterIn);
+ mAnimatorProperties.interpolator = mLinearOutFasterIn;
} else if (velAbs >= mMinVelocityPxPerSecond) {
// Cross fade between linear-out-faster-in and linear interpolator with current
@@ -145,14 +218,15 @@ public class FlingAnimationUtils {
= new VelocityInterpolator(durationSeconds, velAbs, diff);
InterpolatorInterpolator superInterpolator = new InterpolatorInterpolator(
velocityInterpolator, mLinearOutFasterIn, mLinearOutSlowIn);
- animator.setInterpolator(superInterpolator);
+ mAnimatorProperties.interpolator = superInterpolator;
} else {
// Just use a normal interpolator which doesn't take the velocity into account.
durationSeconds = maxLengthSeconds;
- animator.setInterpolator(mFastOutLinearIn);
+ mAnimatorProperties.interpolator = mFastOutLinearIn;
}
- animator.setDuration((long) (durationSeconds * 1000));
+ mAnimatorProperties.duration = (long) (durationSeconds * 1000);
+ return mAnimatorProperties;
}
/**
@@ -221,4 +295,10 @@ public class FlingAnimationUtils {
return time * mVelocity / mDiff;
}
}
+
+ private static class AnimatorProperties {
+ Interpolator interpolator;
+ long duration;
+ }
+
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
index 0555879..24da5c2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/InterceptedNotifications.java
@@ -31,7 +31,6 @@ import com.android.systemui.statusbar.phone.PhoneStatusBar;
public class InterceptedNotifications {
private static final String TAG = "InterceptedNotifications";
private static final String EXTRA_INTERCEPT = "android.intercept";
- private static final String SYNTHETIC_KEY = "InterceptedNotifications.SYNTHETIC_KEY";
private final Context mContext;
private final PhoneStatusBar mBar;
@@ -50,7 +49,7 @@ public class InterceptedNotifications {
for (int i = 0; i < n; i++) {
final StatusBarNotification sbn = mIntercepted.valueAt(i);
sbn.getNotification().extras.putBoolean(EXTRA_INTERCEPT, false);
- mBar.addNotificationInternal(sbn);
+ mBar.addNotificationInternal(sbn, null);
}
mIntercepted.clear();
updateSyntheticNotification();
@@ -71,7 +70,7 @@ public class InterceptedNotifications {
}
public boolean isSyntheticEntry(Entry ent) {
- return ent.key.equals(SYNTHETIC_KEY);
+ return ent.key.equals(mSynKey);
}
public void update(StatusBarNotification notification) {
@@ -88,7 +87,7 @@ public class InterceptedNotifications {
private void updateSyntheticNotification() {
if (mIntercepted.isEmpty()) {
if (mSynKey != null) {
- mBar.removeNotificationInternal(mSynKey);
+ mBar.removeNotificationInternal(mSynKey, null);
mSynKey = null;
}
return;
@@ -107,9 +106,9 @@ public class InterceptedNotifications {
mBar.getCurrentUserHandle());
if (mSynKey == null) {
mSynKey = sbn.getKey();
- mBar.addNotificationInternal(sbn);
+ mBar.addNotificationInternal(sbn, null);
} else {
- mBar.updateNotificationInternal(sbn);
+ mBar.updateNotificationInternal(sbn, null);
}
final NotificationData.Entry entry = mBar.mNotificationData.findByKey(mSynKey);
entry.row.setOnClickListener(mSynClickListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
index 5696246..d829ac0 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationData.java
@@ -16,15 +16,19 @@
package com.android.systemui.statusbar;
+import android.app.Notification;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.view.View;
-import android.widget.ImageView;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
/**
* The list of currently displaying notifications.
+ *
+ * TODO: Rename to NotificationList.
*/
public class NotificationData {
public static final class Entry {
@@ -34,7 +38,6 @@ public class NotificationData {
public ExpandableNotificationRow row; // the outer expanded view
public View expanded; // the inflated RemoteViews
public View expandedPublic; // for insecure lockscreens
- public ImageView largeIcon;
public View expandedBig;
private boolean interruption;
public Entry() {}
@@ -64,18 +67,23 @@ public class NotificationData {
}
private final ArrayList<Entry> mEntries = new ArrayList<Entry>();
- private final Comparator<Entry> mEntryCmp = new Comparator<Entry>() {
- // sort first by score, then by when
+ private Ranking mRanking;
+ private final Comparator<Entry> mRankingComparator = new Comparator<Entry>() {
+ @Override
public int compare(Entry a, Entry b) {
+ if (mRanking != null) {
+ return mRanking.getRank(a.key) - mRanking.getRank(b.key);
+ }
+
final StatusBarNotification na = a.notification;
final StatusBarNotification nb = b.notification;
- int d = na.getScore() - nb.getScore();
+ int d = nb.getScore() - na.getScore();
if (a.interruption != b.interruption) {
- return a.interruption ? 1 : -1;
+ return a.interruption ? -1 : 1;
} else if (d != 0) {
return d;
} else {
- return (int) (na.getNotification().when - nb.getNotification().when);
+ return (int) (nb.getNotification().when - na.getNotification().when);
}
}
};
@@ -97,26 +105,47 @@ public class NotificationData {
return null;
}
- 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;
- }
- }
- mEntries.add(i, entry);
- return i;
+ public void add(Entry entry, Ranking ranking) {
+ mEntries.add(entry);
+ updateRankingAndSort(ranking);
}
- public Entry remove(String key) {
+ public Entry remove(String key, Ranking ranking) {
Entry e = findByKey(key);
- if (e != null) {
- mEntries.remove(e);
+ if (e == null) {
+ return null;
}
+ mEntries.remove(e);
+ updateRankingAndSort(ranking);
return e;
}
+ public void updateRanking(Ranking ranking) {
+ updateRankingAndSort(ranking);
+ }
+
+ public boolean isAmbient(String key) {
+ // TODO: Remove when switching to NotificationListener.
+ if (mRanking == null) {
+ for (Entry entry : mEntries) {
+ if (key.equals(entry.key)) {
+ return entry.notification.getNotification().priority ==
+ Notification.PRIORITY_MIN;
+ }
+ }
+ } else {
+ return mRanking.isAmbient(key);
+ }
+ return false;
+ }
+
+ private void updateRankingAndSort(Ranking ranking) {
+ if (ranking != null) {
+ mRanking = ranking;
+ }
+ Collections.sort(mEntries, mRankingComparator);
+ }
+
/**
* Return whether there are any visible items (i.e. items without an error).
*/
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
index a2f8991..a84daef 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/SpeedBumpView.java
@@ -103,7 +103,11 @@ public class SpeedBumpView extends ExpandableView implements View.OnClickListene
@Override
public int getIntrinsicHeight() {
- return getActualHeight();
+ if (mCurrentAnimator != null) {
+ // expand animation is running
+ return getActualHeight();
+ }
+ return mIsExpanded ? getHeight() : mCollapsedHeight;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 5e9ce21..994b329 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -23,46 +23,34 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.os.PowerManager;
import android.os.RemoteException;
import android.os.UserHandle;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
-import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityManager;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
import android.widget.ImageView;
-
-import com.android.internal.widget.LockPatternUtils;
-import com.android.keyguard.KeyguardUpdateMonitor;
-import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.systemui.R;
/**
* Implementation for the bottom area of the Keyguard, including camera/phone affordance and status
* text.
*/
-public class KeyguardBottomAreaView extends FrameLayout
- implements SwipeAffordanceView.AffordanceListener {
+public class KeyguardBottomAreaView extends FrameLayout implements View.OnClickListener,
+ UnlockMethodCache.OnUnlockMethodChangedListener {
final static String TAG = "PhoneStatusBar/KeyguardBottomAreaView";
private static final Intent PHONE_INTENT = new Intent(Intent.ACTION_DIAL);
- private SwipeAffordanceView mCameraButton;
- private SwipeAffordanceView mPhoneButton;
+ private ImageView mCameraImageView;
+ private ImageView mPhoneImageView;
private ImageView mLockIcon;
- private PowerManager mPowerManager;
private ActivityStarter mActivityStarter;
-
- private LockPatternUtils mLockPatternUtils;
- private KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private UnlockMethodCache mUnlockMethodCache;
public KeyguardBottomAreaView(Context context) {
super(context);
@@ -84,20 +72,16 @@ public class KeyguardBottomAreaView extends FrameLayout
@Override
protected void onFinishInflate() {
super.onFinishInflate();
- mCameraButton = (SwipeAffordanceView) findViewById(R.id.camera_button);
- mPhoneButton = (SwipeAffordanceView) findViewById(R.id.phone_button);
+ mCameraImageView = (ImageView) findViewById(R.id.camera_button);
+ mPhoneImageView = (ImageView) findViewById(R.id.phone_button);
mLockIcon = (ImageView) findViewById(R.id.lock_icon);
- mCameraButton.setAffordanceListener(this);
- mPhoneButton.setAffordanceListener(this);
- mLockPatternUtils = new LockPatternUtils(getContext());
- mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(getContext());
- KeyguardUpdateMonitor.getInstance(getContext()).registerCallback(mCallback);
watchForDevicePolicyChanges();
watchForAccessibilityChanges();
updateCameraVisibility();
updatePhoneVisibility();
+ mUnlockMethodCache = UnlockMethodCache.getInstance(getContext());
+ mUnlockMethodCache.addListener(this);
updateTrust();
- mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
}
public void setActivityStarter(ActivityStarter activityStarter) {
@@ -106,12 +90,12 @@ public class KeyguardBottomAreaView extends FrameLayout
private void updateCameraVisibility() {
boolean visible = !isCameraDisabledByDpm();
- mCameraButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+ mCameraImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private void updatePhoneVisibility() {
boolean visible = isPhoneVisible();
- mPhoneButton.setVisibility(visible ? View.VISIBLE : View.GONE);
+ mPhoneImageView.setVisibility(visible ? View.VISIBLE : View.GONE);
}
private boolean isPhoneVisible() {
@@ -171,33 +155,31 @@ public class KeyguardBottomAreaView extends FrameLayout
}
private void enableAccessibility(boolean touchExplorationEnabled) {
- mCameraButton.enableAccessibility(touchExplorationEnabled);
- mPhoneButton.enableAccessibility(touchExplorationEnabled);
+ mCameraImageView.setOnClickListener(touchExplorationEnabled ? this : null);
+ mCameraImageView.setClickable(touchExplorationEnabled);
+ mPhoneImageView.setOnClickListener(touchExplorationEnabled ? this : null);
+ mPhoneImageView.setClickable(touchExplorationEnabled);
+ }
+
+ @Override
+ public void onClick(View v) {
+ if (v == mCameraImageView) {
+ launchCamera();
+ } else if (v == mPhoneImageView) {
+ launchPhone();
+ }
}
- private void launchCamera() {
+ public void launchCamera() {
mContext.startActivityAsUser(
new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE),
UserHandle.CURRENT);
}
- private void launchPhone() {
+ public void launchPhone() {
mActivityStarter.startActivity(PHONE_INTENT);
}
- @Override
- public void onUserActivity(long when) {
- mPowerManager.userActivity(when, false);
- }
-
- @Override
- public void onActionPerformed(SwipeAffordanceView view) {
- if (view == mCameraButton) {
- launchCamera();
- } else if (view == mPhoneButton) {
- launchPhone();
- }
- }
@Override
protected void onVisibilityChanged(View changedView, int visibility) {
@@ -211,28 +193,26 @@ public class KeyguardBottomAreaView extends FrameLayout
if (getVisibility() != VISIBLE) {
return;
}
- int user = mLockPatternUtils.getCurrentUser();
- boolean trust = !mLockPatternUtils.isSecure() ||
- mKeyguardUpdateMonitor.getUserHasTrust(user);
-
- int iconRes = trust ? R.drawable.ic_lock_open_24dp : R.drawable.ic_lock_24dp;
+ int iconRes = mUnlockMethodCache.isMethodInsecure()
+ ? R.drawable.ic_lock_open_24dp
+ : R.drawable.ic_lock_24dp;
mLockIcon.setImageResource(iconRes);
}
- final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
- @Override
- public void onScreenTurnedOn() {
- updateTrust();
- }
+ public ImageView getPhoneImageView() {
+ return mPhoneImageView;
+ }
- @Override
- public void onUserSwitchComplete(int userId) {
- updateTrust();
- }
+ public ImageView getCameraImageView() {
+ return mCameraImageView;
+ }
- @Override
- public void onTrustChanged(int userId) {
- updateTrust();
- }
- };
+ public ImageView getLockIcon() {
+ return mLockIcon;
+ }
+
+ @Override
+ public void onMethodSecureChanged(boolean methodSecure) {
+ updateTrust();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
index d8e1766..b7a7b0a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBouncer.java
@@ -28,6 +28,7 @@ import com.android.keyguard.R;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.keyguard.KeyguardViewMediator;
+import static com.android.keyguard.KeyguardHostView.OnDismissAction;
import static com.android.keyguard.KeyguardSecurityModel.*;
/**
@@ -53,27 +54,36 @@ public class KeyguardBouncer {
mWindowManager = windowManager;
}
- public void prepare() {
- ensureView();
- }
-
public void show() {
ensureView();
+ if (mRoot.getVisibility() == View.VISIBLE) {
+ return;
+ }
// Try to dismiss the Keyguard. If no security pattern is set, this will dismiss the whole
// Keyguard. If we need to authenticate, show the bouncer.
if (!mKeyguardView.dismiss()) {
mRoot.setVisibility(View.VISIBLE);
- mKeyguardView.requestFocus();
mKeyguardView.onResume();
+ mKeyguardView.startAppearAnimation();
}
}
- public void hide() {
+ public void showWithDismissAction(OnDismissAction r) {
+ ensureView();
+ mKeyguardView.setOnDismissAction(r);
+ show();
+ }
+
+ public void hide(boolean destroyView) {
if (mKeyguardView != null) {
mKeyguardView.cleanUp();
}
- removeView();
+ if (destroyView) {
+ removeView();
+ } else if (mRoot != null) {
+ mRoot.setVisibility(View.INVISIBLE);
+ }
}
/**
@@ -103,6 +113,10 @@ public class KeyguardBouncer {
return mRoot != null && mRoot.getVisibility() == View.VISIBLE;
}
+ public void prepare() {
+ ensureView();
+ }
+
private void ensureView() {
if (mRoot == null) {
inflateView();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
index 769b1b1..c5c3fff 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardIndicationTextView.java
@@ -17,7 +17,9 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.text.TextUtils;
import android.util.AttributeSet;
+import android.view.View;
import android.widget.TextView;
/**
@@ -50,7 +52,12 @@ public class KeyguardIndicationTextView extends TextView {
public void switchIndication(CharSequence text) {
// TODO: Animation, make sure that we will show one indication long enough.
- setText(text);
+ if (TextUtils.isEmpty(text)) {
+ setVisibility(View.INVISIBLE);
+ } else {
+ setVisibility(View.VISIBLE);
+ setText(text);
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
new file mode 100644
index 0000000..b4f4865
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardPageSwipeHelper.java
@@ -0,0 +1,398 @@
+/*
+ * Copyright (C) 2014 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.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.Context;
+import android.os.PowerManager;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewPropertyAnimator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.Interpolator;
+import com.android.systemui.R;
+import com.android.systemui.statusbar.FlingAnimationUtils;
+
+import java.util.ArrayList;
+
+/**
+ * A touch handler of the Keyguard which is responsible for swiping the content left or right.
+ */
+public class KeyguardPageSwipeHelper {
+
+ private static final float SWIPE_MAX_ICON_SCALE_AMOUNT = 2.0f;
+ private static final float SWIPE_RESTING_ALPHA_AMOUNT = 0.7f;
+ private final Context mContext;
+
+ private FlingAnimationUtils mFlingAnimationUtils;
+ private Callback mCallback;
+ private int mTrackingPointer;
+ private VelocityTracker mVelocityTracker;
+ private boolean mSwipingInProgress;
+ private float mInitialTouchX;
+ private float mInitialTouchY;
+ private float mTranslation;
+ private float mTranslationOnDown;
+ private int mTouchSlop;
+ private int mMinTranslationAmount;
+ private int mMinFlingVelocity;
+ private PowerManager mPowerManager;
+ private final View mLeftIcon;
+ private final View mCenterIcon;
+ private final View mRightIcon;
+ private Interpolator mFastOutSlowIn;
+ private Animator mSwipeAnimator;
+ private boolean mCallbackCalled;
+
+ KeyguardPageSwipeHelper(Callback callback, Context context) {
+ mContext = context;
+ mCallback = callback;
+ mLeftIcon = mCallback.getLeftIcon();
+ mCenterIcon = mCallback.getCenterIcon();
+ mRightIcon = mCallback.getRightIcon();
+ updateIcon(mLeftIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ updateIcon(mCenterIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ updateIcon(mRightIcon, 1.0f, SWIPE_RESTING_ALPHA_AMOUNT, false);
+ mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ initDimens();
+ }
+
+ private void initDimens() {
+ final ViewConfiguration configuration = ViewConfiguration.get(mContext);
+ mTouchSlop = configuration.getScaledTouchSlop();
+ mMinFlingVelocity = configuration.getScaledMinimumFlingVelocity();
+ mMinTranslationAmount = mContext.getResources().getDimensionPixelSize(
+ R.dimen.keyguard_min_swipe_amount);
+ mFlingAnimationUtils = new FlingAnimationUtils(mContext, 0.4f);
+ mFastOutSlowIn = AnimationUtils.loadInterpolator(mContext,
+ android.R.interpolator.fast_out_slow_in);
+ }
+
+ public boolean onTouchEvent(MotionEvent event) {
+ int pointerIndex = event.findPointerIndex(mTrackingPointer);
+ if (pointerIndex < 0) {
+ pointerIndex = 0;
+ mTrackingPointer = event.getPointerId(pointerIndex);
+ }
+ final float y = event.getY(pointerIndex);
+ final float x = event.getX(pointerIndex);
+
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ if (mSwipingInProgress) {
+ cancelAnimations();
+ }
+ mInitialTouchY = y;
+ mInitialTouchX = x;
+ mTranslationOnDown = mTranslation;
+ initVelocityTracker();
+ trackMovement(event);
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ final int upPointer = event.getPointerId(event.getActionIndex());
+ if (mTrackingPointer == upPointer) {
+ // gesture is ongoing, find a new pointer to track
+ final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
+ final float newY = event.getY(newIndex);
+ final float newX = event.getX(newIndex);
+ mTrackingPointer = event.getPointerId(newIndex);
+ mInitialTouchY = newY;
+ mInitialTouchX = newX;
+ mTranslationOnDown = mTranslation;
+ }
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ final float w = x - mInitialTouchX;
+ trackMovement(event);
+ if (((leftSwipePossible() && w > mTouchSlop)
+ || (rightSwipePossible() && w < -mTouchSlop))
+ && Math.abs(w) > Math.abs(y - mInitialTouchY)
+ && !mSwipingInProgress) {
+ cancelAnimations();
+ mInitialTouchY = y;
+ mInitialTouchX = x;
+ mTranslationOnDown = mTranslation;
+ mSwipingInProgress = true;
+ }
+ if (mSwipingInProgress) {
+ setTranslation(mTranslationOnDown + x - mInitialTouchX, false);
+ onUserActivity(event.getEventTime());
+ }
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mTrackingPointer = -1;
+ trackMovement(event);
+ if (mSwipingInProgress) {
+ flingWithCurrentVelocity();
+ }
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ break;
+ }
+ return true;
+ }
+
+ private boolean rightSwipePossible() {
+ return mRightIcon.getVisibility() == View.VISIBLE;
+ }
+
+ private boolean leftSwipePossible() {
+ return mLeftIcon.getVisibility() == View.VISIBLE;
+ }
+
+ public boolean onInterceptTouchEvent(MotionEvent ev) {
+ return false;
+ }
+
+ private void onUserActivity(long when) {
+ mPowerManager.userActivity(when, false);
+ }
+
+ private void cancelAnimations() {
+ ArrayList<View> targetViews = mCallback.getTranslationViews();
+ for (View target : targetViews) {
+ target.animate().cancel();
+ }
+ View targetView = mTranslation > 0 ? mLeftIcon : mRightIcon;
+ targetView.animate().cancel();
+ if (mSwipeAnimator != null) {
+ mSwipeAnimator.removeAllListeners();
+ mSwipeAnimator.cancel();
+ hideInactiveIcons(true);
+ }
+ }
+
+ private void flingWithCurrentVelocity() {
+ float vel = getCurrentVelocity();
+
+ // We snap back if the current translation is not far enough
+ boolean snapBack = Math.abs(mTranslation) < mMinTranslationAmount;
+
+ // or if the velocity is in the opposite direction.
+ boolean velIsInWrongDirection = vel * mTranslation < 0;
+ snapBack |= Math.abs(vel) > mMinFlingVelocity && velIsInWrongDirection;
+ vel = snapBack ^ velIsInWrongDirection ? 0 : vel;
+ fling(vel, snapBack);
+ }
+
+ private void fling(float vel, final boolean snapBack) {
+ float target = mTranslation < 0 ? -mCallback.getPageWidth() : mCallback.getPageWidth();
+ target = snapBack ? 0 : target;
+
+ // translation Animation
+ startTranslationAnimations(vel, target);
+
+ // animate left / right icon
+ startIconAnimation(vel, snapBack, target);
+
+ ValueAnimator animator = ValueAnimator.ofFloat(mTranslation, target);
+ mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ mTranslation = (float) animation.getAnimatedValue();
+ }
+ });
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mSwipeAnimator = null;
+ mSwipingInProgress = false;
+ if (!snapBack && !mCallbackCalled) {
+
+ // ensure that the callback is called eventually
+ mCallback.onAnimationToSideStarted(mTranslation < 0);
+ mCallbackCalled = true;
+ }
+ }
+ });
+ if (!snapBack) {
+ mCallbackCalled = false;
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ int frameNumber;
+
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ if (frameNumber == 2 && !mCallbackCalled) {
+
+ // we have to wait for the second frame for this call,
+ // until the render thread has definitely kicked in, to avoid a lag.
+ mCallback.onAnimationToSideStarted(mTranslation < 0);
+ mCallbackCalled = true;
+ }
+ frameNumber++;
+ }
+ });
+ } else {
+ showAllIcons(true);
+ }
+ animator.start();
+ mSwipeAnimator = animator;
+ }
+
+ private void startTranslationAnimations(float vel, float target) {
+ ArrayList<View> targetViews = mCallback.getTranslationViews();
+ for (View targetView : targetViews) {
+ ViewPropertyAnimator animator = targetView.animate();
+ mFlingAnimationUtils.apply(animator, mTranslation, target, vel);
+ animator.translationX(target);
+ }
+ }
+
+ private void startIconAnimation(float vel, boolean snapBack, float target) {
+ float scale = snapBack ? 1.0f : SWIPE_MAX_ICON_SCALE_AMOUNT;
+ float alpha = snapBack ? SWIPE_RESTING_ALPHA_AMOUNT : 1.0f;
+ View targetView = mTranslation > 0
+ ? mLeftIcon
+ : mRightIcon;
+ if (targetView.getVisibility() == View.VISIBLE) {
+ ViewPropertyAnimator iconAnimator = targetView.animate();
+ mFlingAnimationUtils.apply(iconAnimator, mTranslation, target, vel);
+ iconAnimator.scaleX(scale);
+ iconAnimator.scaleY(scale);
+ iconAnimator.alpha(alpha);
+ }
+ }
+
+ private void setTranslation(float translation, boolean isReset) {
+ translation = rightSwipePossible() ? translation : Math.max(0, translation);
+ translation = leftSwipePossible() ? translation : Math.min(0, translation);
+ if (translation != mTranslation) {
+ ArrayList<View> translatedViews = mCallback.getTranslationViews();
+ for (View view : translatedViews) {
+ view.setTranslationX(translation);
+ }
+ if (translation == 0.0f) {
+ boolean animate = !isReset;
+ showAllIcons(animate);
+ } else {
+ View targetView = translation > 0 ? mLeftIcon : mRightIcon;
+ float progress = Math.abs(translation) / mCallback.getPageWidth();
+ progress = Math.min(progress, 1.0f);
+ float alpha = SWIPE_RESTING_ALPHA_AMOUNT * (1.0f - progress) + progress;
+ float scale = (1.0f - progress) + progress * SWIPE_MAX_ICON_SCALE_AMOUNT;
+ updateIcon(targetView, scale, alpha, false);
+ View otherView = translation < 0 ? mLeftIcon : mRightIcon;
+ if (mTranslation * translation <= 0) {
+ // The sign of the translation has changed so we need to hide the other icons
+ updateIcon(otherView, 0, 0, true);
+ updateIcon(mCenterIcon, 0, 0, true);
+ }
+ }
+ mTranslation = translation;
+ }
+ }
+
+ private void showAllIcons(boolean animate) {
+ float scale = 1.0f;
+ float alpha = SWIPE_RESTING_ALPHA_AMOUNT;
+ updateIcon(mRightIcon, scale, alpha, animate);
+ updateIcon(mCenterIcon, scale, alpha, animate);
+ updateIcon(mLeftIcon, scale, alpha, animate);
+ }
+
+ private void hideInactiveIcons(boolean animate){
+ View otherView = mTranslation < 0 ? mLeftIcon : mRightIcon;
+ updateIcon(otherView, 0, 0, animate);
+ updateIcon(mCenterIcon, 0, 0, animate);
+ }
+
+ private void updateIcon(View view, float scale, float alpha, boolean animate) {
+ if (view.getVisibility() != View.VISIBLE) {
+ return;
+ }
+ if (!animate) {
+ view.setAlpha(alpha);
+ view.setScaleX(scale);
+ view.setScaleY(scale);
+ // TODO: remove this invalidate once the property setters invalidate it properly
+ view.invalidate();
+ } else {
+ if (view.getAlpha() != alpha || view.getScaleX() != scale) {
+ view.animate()
+ .setInterpolator(mFastOutSlowIn)
+ .alpha(alpha)
+ .scaleX(scale)
+ .scaleY(scale);
+ }
+ }
+ }
+
+ private void trackMovement(MotionEvent event) {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.addMovement(event);
+ }
+ }
+
+ private void initVelocityTracker() {
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ }
+ mVelocityTracker = VelocityTracker.obtain();
+ }
+
+ private float getCurrentVelocity() {
+ if (mVelocityTracker == null) {
+ return 0;
+ }
+ mVelocityTracker.computeCurrentVelocity(1000);
+ return mVelocityTracker.getXVelocity();
+ }
+
+ public void onConfigurationChanged() {
+ initDimens();
+ }
+
+ public void reset() {
+ setTranslation(0.0f, true);
+ mSwipingInProgress = false;
+ }
+
+ public boolean isSwipingInProgress() {
+ return mSwipingInProgress;
+ }
+
+ public interface Callback {
+
+ /**
+ * Notifies the callback when an animation to a side page was started.
+ *
+ * @param rightPage Is the page animated to the right page?
+ */
+ void onAnimationToSideStarted(boolean rightPage);
+
+ float getPageWidth();
+
+ ArrayList<View> getTranslationViews();
+
+ View getLeftIcon();
+
+ View getCenterIcon();
+
+ View getRightIcon();
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
index c83b479..3753a72 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarTransitions.java
@@ -30,7 +30,6 @@ import com.android.systemui.statusbar.policy.KeyButtonView;
public final class NavigationBarTransitions extends BarTransitions {
- private static final float KEYGUARD_QUIESCENT_ALPHA = 0.5f;
private static final int CONTENT_FADE_DURATION = 200;
private final NavigationBarView mView;
@@ -81,8 +80,6 @@ public final class NavigationBarTransitions extends BarTransitions {
setKeyButtonViewQuiescentAlpha(mView.getRecentsButton(), alpha, animate);
setKeyButtonViewQuiescentAlpha(mView.getMenuButton(), alpha, animate);
- setKeyButtonViewQuiescentAlpha(mView.getSearchLight(), KEYGUARD_QUIESCENT_ALPHA, animate);
-
applyBackButtonQuiescentAlpha(mode, animate);
// apply to lights out
@@ -96,7 +93,6 @@ public final class NavigationBarTransitions extends BarTransitions {
public void applyBackButtonQuiescentAlpha(int mode, boolean animate) {
float backAlpha = 0;
- backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getSearchLight());
backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getHomeButton());
backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getRecentsButton());
backAlpha = maxVisibleQuiescentAlpha(backAlpha, mView.getMenuButton());
@@ -116,7 +112,6 @@ public final class NavigationBarTransitions extends BarTransitions {
public void setContentVisible(boolean visible) {
final float alpha = visible ? 1 : 0;
fadeContent(mView.getBackButton(), alpha);
- fadeContent(mView.getSearchLight(), alpha);
}
private void fadeContent(View v, float alpha) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
index 089757a..21842bf 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarView.java
@@ -133,16 +133,6 @@ public class NavigationBarView extends LinearLayout {
}
}
- // simplified click handler to be used when device is in accessibility mode
- private final OnClickListener mAccessibilityClickListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- if (v.getId() == R.id.search_light) {
- KeyguardTouchDelegate.getInstance(getContext()).showAssistant();
- }
- }
- };
-
private final OnClickListener mImeSwitcherClickListener = new OnClickListener() {
@Override
public void onClick(View view) {
@@ -246,11 +236,6 @@ public class NavigationBarView extends LinearLayout {
return mCurrentView.findViewById(R.id.ime_switcher);
}
- // for when home is disabled, but search isn't
- public View getSearchLight() {
- return mCurrentView.findViewById(R.id.search_light);
- }
-
private void getIcons(Resources res) {
mBackIcon = res.getDrawable(R.drawable.ic_sysbar_back);
mBackLandIcon = res.getDrawable(R.drawable.ic_sysbar_back_land);
@@ -345,9 +330,6 @@ public class NavigationBarView extends LinearLayout {
getHomeButton() .setVisibility(disableHome ? View.INVISIBLE : View.VISIBLE);
getRecentsButton().setVisibility(disableRecent ? View.INVISIBLE : View.VISIBLE);
- final boolean showSearch = disableHome && !disableSearch;
- setVisibleOrGone(getSearchLight(), showSearch);
-
mBarTransitions.applyBackButtonQuiescentAlpha(mBarTransitions.getMode(), true /*animate*/);
}
@@ -402,38 +384,6 @@ public class NavigationBarView extends LinearLayout {
mCurrentView = mRotatedViews[Surface.ROTATION_0];
getImeSwitchButton().setOnClickListener(mImeSwitcherClickListener);
-
- watchForAccessibilityChanges();
- }
-
- private void watchForAccessibilityChanges() {
- final AccessibilityManager am =
- (AccessibilityManager) getContext().getSystemService(Context.ACCESSIBILITY_SERVICE);
-
- // Set the initial state
- enableAccessibility(am.isTouchExplorationEnabled());
-
- // Watch for changes
- am.addTouchExplorationStateChangeListener(new TouchExplorationStateChangeListener() {
- @Override
- public void onTouchExplorationStateChanged(boolean enabled) {
- enableAccessibility(enabled);
- }
- });
- }
-
- private void enableAccessibility(boolean touchEnabled) {
- Log.v(TAG, "touchEnabled:" + touchEnabled);
-
- // Add a touch handler or accessibility click listener for camera and search buttons
- // for all view orientations.
- final OnClickListener onClickListener = touchEnabled ? mAccessibilityClickListener : null;
- for (int i = 0; i < mRotatedViews.length; i++) {
- final View searchLight = mRotatedViews[i].findViewById(R.id.search_light);
- if (searchLight != null) {
- searchLight.setOnClickListener(onClickListener);
- }
- }
}
public boolean isVertical() {
@@ -571,7 +521,6 @@ public class NavigationBarView extends LinearLayout {
dumpButton(pw, "home", getHomeButton());
dumpButton(pw, "rcnt", getRecentsButton());
dumpButton(pw, "menu", getMenuButton());
- dumpButton(pw, "srch", getSearchLight());
pw.println(" }");
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 0a44904..802e5e5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -21,9 +21,8 @@ import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator;
import android.content.Context;
-import android.graphics.Path;
+import android.content.res.Configuration;
import android.util.AttributeSet;
-import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -32,7 +31,6 @@ import android.view.ViewTreeObserver;
import android.view.accessibility.AccessibilityEvent;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
-import android.view.animation.PathInterpolator;
import android.widget.LinearLayout;
import com.android.systemui.R;
@@ -43,13 +41,17 @@ import com.android.systemui.statusbar.StatusBarState;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.StackStateAnimator;
+import java.util.ArrayList;
+
public class NotificationPanelView extends PanelView implements
ExpandableView.OnHeightChangedListener, ObservableScrollView.Listener,
- View.OnClickListener {
+ View.OnClickListener, KeyguardPageSwipeHelper.Callback {
+ private KeyguardPageSwipeHelper mPageSwiper;
PhoneStatusBar mStatusBar;
private StatusBarHeaderView mHeader;
private View mQsContainer;
+ private View mQsPanel;
private View mKeyguardStatusView;
private ObservableScrollView mScrollView;
private View mStackScrollerContainer;
@@ -60,7 +62,7 @@ public class NotificationPanelView extends PanelView implements
private int mTrackingPointer;
private VelocityTracker mVelocityTracker;
- private boolean mTracking;
+ private boolean mQsTracking;
/**
* Whether we are currently handling a motion gesture in #onInterceptTouchEvent, but haven't
@@ -68,6 +70,7 @@ public class NotificationPanelView extends PanelView implements
*/
private boolean mIntercepting;
private boolean mQsExpanded;
+ private boolean mKeyguardShowing;
private float mInitialHeightOnTouch;
private float mInitialTouchX;
private float mInitialTouchY;
@@ -77,6 +80,7 @@ public class NotificationPanelView extends PanelView implements
private int mQsMinExpansionHeight;
private int mQsMaxExpansionHeight;
private int mMinStackHeight;
+ private int mQsPeekHeight;
private float mNotificationTranslation;
private int mStackScrollerIntrinsicPadding;
private boolean mQsExpansionEnabled = true;
@@ -92,6 +96,11 @@ public class NotificationPanelView extends PanelView implements
new KeyguardClockPositionAlgorithm();
private KeyguardClockPositionAlgorithm.Result mClockPositionResult =
new KeyguardClockPositionAlgorithm.Result();
+ private boolean mIsSwipedHorizontally;
+ private boolean mIsExpanding;
+ private KeyguardBottomAreaView mKeyguardBottomArea;
+ private boolean mBlockTouches;
+ private ArrayList<View> mSwipeTranslationViews = new ArrayList<>();
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -121,6 +130,7 @@ public class NotificationPanelView extends PanelView implements
mKeyguardStatusView = findViewById(R.id.keyguard_status_view);
mStackScrollerContainer = findViewById(R.id.notification_container_parent);
mQsContainer = findViewById(R.id.quick_settings_container);
+ mQsPanel = findViewById(R.id.quick_settings_panel);
mScrollView = (ObservableScrollView) findViewById(R.id.scroll_view);
mScrollView.setListener(this);
mNotificationStackScroller = (NotificationStackScrollLayout)
@@ -128,6 +138,10 @@ public class NotificationPanelView extends PanelView implements
mNotificationStackScroller.setOnHeightChangedListener(this);
mFastOutSlowInInterpolator = AnimationUtils.loadInterpolator(getContext(),
android.R.interpolator.fast_out_slow_in);
+ mKeyguardBottomArea = (KeyguardBottomAreaView) findViewById(R.id.keyguard_bottom_area);
+ mSwipeTranslationViews.add(mNotificationStackScroller);
+ mSwipeTranslationViews.add(mKeyguardStatusView);
+ mPageSwiper = new KeyguardPageSwipeHelper(this, getContext());
}
@Override
@@ -139,22 +153,23 @@ public class NotificationPanelView extends PanelView implements
mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.4f);
mStatusBarMinHeight = getResources().getDimensionPixelSize(
com.android.internal.R.dimen.status_bar_height);
+ mQsPeekHeight = getResources().getDimensionPixelSize(R.dimen.qs_peek_height);
mClockPositionAlgorithm.loadDimens(getResources());
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
- if (!mQsExpanded) {
- positionClockAndNotifications();
- mNotificationStackScroller.setStackHeight(getExpandedHeight());
- }
// Calculate quick setting heights.
- mQsMinExpansionHeight = mHeader.getCollapsedHeight();
+ mQsMinExpansionHeight = mHeader.getCollapsedHeight() + mQsPeekHeight;
mQsMaxExpansionHeight = mHeader.getExpandedHeight() + mQsContainer.getHeight();
- if (mQsExpansionHeight == 0) {
- mQsExpansionHeight = mQsMinExpansionHeight;
+ if (mQsExpanded) {
+ setQsStackScrollerPadding(mQsMaxExpansionHeight);
+ } else {
+ setQsExpansion(mQsMinExpansionHeight);
+ positionClockAndNotifications();
+ mNotificationStackScroller.setStackHeight(getExpandedHeight());
}
}
@@ -165,7 +180,8 @@ public class NotificationPanelView extends PanelView implements
private void positionClockAndNotifications() {
boolean animateClock = mNotificationStackScroller.isAddOrRemoveAnimationPending();
if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
- mStackScrollerIntrinsicPadding = mHeader.getBottom() + mNotificationTopPadding;
+ mStackScrollerIntrinsicPadding = mHeader.getBottom() + mQsPeekHeight
+ + mNotificationTopPadding;
mTopPaddingAdjustment = 0;
} else {
mClockPositionAlgorithm.setup(
@@ -246,6 +262,13 @@ public class NotificationPanelView extends PanelView implements
mQsExpansionEnabled = qsExpansionEnabled;
}
+ @Override
+ public void resetViews() {
+ mBlockTouches = false;
+ mPageSwiper.reset();
+ closeQs();
+ }
+
public void closeQs() {
cancelAnimation();
setQsExpansion(mQsMinExpansionHeight);
@@ -262,9 +285,7 @@ public class NotificationPanelView extends PanelView implements
public void fling(float vel, boolean always) {
GestureRecorder gr = ((PhoneStatusBarView) mBar).mBar.getGestureRecorder();
if (gr != null) {
- gr.tag(
- "fling " + ((vel > 0) ? "open" : "closed"),
- "notifications,v=" + vel);
+ gr.tag("fling " + ((vel > 0) ? "open" : "closed"), "notifications,v=" + vel);
}
super.fling(vel, always);
}
@@ -282,6 +303,9 @@ public class NotificationPanelView extends PanelView implements
@Override
public boolean onInterceptTouchEvent(MotionEvent event) {
+ if (mBlockTouches) {
+ return false;
+ }
int pointerIndex = event.findPointerIndex(mTrackingPointer);
if (pointerIndex < 0) {
pointerIndex = 0;
@@ -297,7 +321,7 @@ public class NotificationPanelView extends PanelView implements
mInitialTouchX = x;
initVelocityTracker();
trackMovement(event);
- if (shouldIntercept(mInitialTouchX, mInitialTouchY, 0)) {
+ if (shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, 0)) {
getParent().requestDisallowInterceptTouchEvent(true);
}
break;
@@ -315,7 +339,7 @@ public class NotificationPanelView extends PanelView implements
case MotionEvent.ACTION_MOVE:
final float h = y - mInitialTouchY;
trackMovement(event);
- if (mTracking) {
+ if (mQsTracking) {
// Already tracking because onOverscrolled was called. We need to update here
// so we don't stop for a frame until the next touch event gets handled in
@@ -326,12 +350,12 @@ public class NotificationPanelView extends PanelView implements
return true;
}
if (Math.abs(h) > mTouchSlop && Math.abs(h) > Math.abs(x - mInitialTouchX)
- && shouldIntercept(mInitialTouchX, mInitialTouchY, h)) {
+ && shouldQuickSettingsIntercept(mInitialTouchX, mInitialTouchY, h)) {
onQsExpansionStarted();
mInitialHeightOnTouch = mQsExpansionHeight;
mInitialTouchY = y;
mInitialTouchX = x;
- mTracking = true;
+ mQsTracking = true;
mIntercepting = false;
return true;
}
@@ -340,9 +364,9 @@ public class NotificationPanelView extends PanelView implements
case MotionEvent.ACTION_CANCEL:
case MotionEvent.ACTION_UP:
trackMovement(event);
- if (mTracking) {
- flingWithCurrentVelocity();
- mTracking = false;
+ if (mQsTracking) {
+ flingQsWithCurrentVelocity();
+ mQsTracking = false;
}
mIntercepting = false;
break;
@@ -353,13 +377,15 @@ public class NotificationPanelView extends PanelView implements
@Override
public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
- // Block request so we can still intercept the scrolling when QS is expanded.
- if (!mQsExpanded) {
- super.requestDisallowInterceptTouchEvent(disallowIntercept);
+ // Block request when interacting with the scroll view so we can still intercept the
+ // scrolling when QS is expanded.
+ if (mScrollView.isDispatchingTouchEvent()) {
+ return;
}
+ super.requestDisallowInterceptTouchEvent(disallowIntercept);
}
- private void flingWithCurrentVelocity() {
+ private void flingQsWithCurrentVelocity() {
float vel = getCurrentVelocity();
// TODO: Better logic whether we should expand or not.
@@ -368,65 +394,83 @@ public class NotificationPanelView extends PanelView implements
@Override
public boolean onTouchEvent(MotionEvent event) {
+ if (mBlockTouches) {
+ return false;
+ }
// TODO: Handle doublefinger swipe to notifications again. Look at history for a reference
// implementation.
- if (mTracking) {
- int pointerIndex = event.findPointerIndex(mTrackingPointer);
- if (pointerIndex < 0) {
- pointerIndex = 0;
- mTrackingPointer = event.getPointerId(pointerIndex);
+ if (!mIsExpanding && !mQsExpanded && mStatusBar.getBarState() != StatusBarState.SHADE) {
+ mPageSwiper.onTouchEvent(event);
+ if (mPageSwiper.isSwipingInProgress()) {
+ return true;
}
- final float y = event.getY(pointerIndex);
- final float x = event.getX(pointerIndex);
+ }
+ if (mQsTracking || mQsExpanded) {
+ return onQsTouch(event);
+ }
- switch (event.getActionMasked()) {
- case MotionEvent.ACTION_DOWN:
- mTracking = true;
- mInitialTouchY = y;
- mInitialTouchX = x;
- onQsExpansionStarted();
- mInitialHeightOnTouch = mQsExpansionHeight;
- initVelocityTracker();
- trackMovement(event);
- break;
-
- case MotionEvent.ACTION_POINTER_UP:
- final int upPointer = event.getPointerId(event.getActionIndex());
- if (mTrackingPointer == upPointer) {
- // gesture is ongoing, find a new pointer to track
- final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
- final float newY = event.getY(newIndex);
- final float newX = event.getX(newIndex);
- mTrackingPointer = event.getPointerId(newIndex);
- mInitialHeightOnTouch = mQsExpansionHeight;
- mInitialTouchY = newY;
- mInitialTouchX = newX;
- }
- break;
+ super.onTouchEvent(event);
+ return true;
+ }
- case MotionEvent.ACTION_MOVE:
- final float h = y - mInitialTouchY;
- setQsExpansion(h + mInitialHeightOnTouch);
- trackMovement(event);
- break;
+ @Override
+ protected boolean hasConflictingGestures() {
+ return mStatusBar.getBarState() != StatusBarState.SHADE;
+ }
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- mTracking = false;
- mTrackingPointer = -1;
- trackMovement(event);
- flingWithCurrentVelocity();
- if (mVelocityTracker != null) {
- mVelocityTracker.recycle();
- mVelocityTracker = null;
- }
- break;
- }
- return true;
+ private boolean onQsTouch(MotionEvent event) {
+ int pointerIndex = event.findPointerIndex(mTrackingPointer);
+ if (pointerIndex < 0) {
+ pointerIndex = 0;
+ mTrackingPointer = event.getPointerId(pointerIndex);
}
+ final float y = event.getY(pointerIndex);
+ final float x = event.getX(pointerIndex);
- // Consume touch events when QS are expanded.
- return mQsExpanded || super.onTouchEvent(event);
+ switch (event.getActionMasked()) {
+ case MotionEvent.ACTION_DOWN:
+ mQsTracking = true;
+ mInitialTouchY = y;
+ mInitialTouchX = x;
+ onQsExpansionStarted();
+ mInitialHeightOnTouch = mQsExpansionHeight;
+ initVelocityTracker();
+ trackMovement(event);
+ break;
+
+ case MotionEvent.ACTION_POINTER_UP:
+ final int upPointer = event.getPointerId(event.getActionIndex());
+ if (mTrackingPointer == upPointer) {
+ // gesture is ongoing, find a new pointer to track
+ final int newIndex = event.getPointerId(0) != upPointer ? 0 : 1;
+ final float newY = event.getY(newIndex);
+ final float newX = event.getX(newIndex);
+ mTrackingPointer = event.getPointerId(newIndex);
+ mInitialHeightOnTouch = mQsExpansionHeight;
+ mInitialTouchY = newY;
+ mInitialTouchX = newX;
+ }
+ break;
+
+ case MotionEvent.ACTION_MOVE:
+ final float h = y - mInitialTouchY;
+ setQsExpansion(h + mInitialHeightOnTouch);
+ trackMovement(event);
+ break;
+
+ case MotionEvent.ACTION_UP:
+ case MotionEvent.ACTION_CANCEL:
+ mQsTracking = false;
+ mTrackingPointer = -1;
+ trackMovement(event);
+ flingQsWithCurrentVelocity();
+ if (mVelocityTracker != null) {
+ mVelocityTracker.recycle();
+ mVelocityTracker = null;
+ }
+ break;
+ }
+ return true;
}
@Override
@@ -436,7 +480,7 @@ public class NotificationPanelView extends PanelView implements
mInitialHeightOnTouch = mQsExpansionHeight;
mInitialTouchY = mLastTouchY;
mInitialTouchX = mLastTouchX;
- mTracking = true;
+ mQsTracking = true;
}
}
@@ -453,29 +497,38 @@ public class NotificationPanelView extends PanelView implements
setQsExpansion(height);
}
- private void expandQs() {
- mHeader.setExpanded(true);
- mNotificationStackScroller.setEnabled(false);
- mScrollView.setVisibility(View.VISIBLE);
- mQsExpanded = true;
+ private void setQsExpanded(boolean expanded) {
+ boolean changed = mQsExpanded != expanded;
+ if (changed) {
+ mQsExpanded = expanded;
+ updateQsState();
+ }
}
- private void collapseQs() {
- mHeader.setExpanded(false);
- mNotificationStackScroller.setEnabled(true);
- mScrollView.setVisibility(View.INVISIBLE);
- mQsExpanded = false;
+ public void setKeyguardShowing(boolean keyguardShowing) {
+ mKeyguardShowing = keyguardShowing;
+ updateQsState();
+ }
+
+ private void updateQsState() {
+ mHeader.setExpanded(mQsExpanded);
+ mNotificationStackScroller.setEnabled(!mQsExpanded);
+ mQsPanel.setVisibility(mQsExpanded ? View.VISIBLE : View.INVISIBLE);
+ mQsContainer.setVisibility(mKeyguardShowing && !mQsExpanded
+ ? View.INVISIBLE
+ : View.VISIBLE);
+ mScrollView.setTouchEnabled(mQsExpanded);
}
private void setQsExpansion(float height) {
height = Math.min(Math.max(height, mQsMinExpansionHeight), mQsMaxExpansionHeight);
if (height > mQsMinExpansionHeight && !mQsExpanded) {
- expandQs();
+ setQsExpanded(true);
} else if (height <= mQsMinExpansionHeight && mQsExpanded) {
- collapseQs();
+ setQsExpanded(false);
}
mQsExpansionHeight = height;
- mHeader.setExpansion(height);
+ mHeader.setExpansion(height - mQsPeekHeight);
setQsTranslation(height);
setQsStackScrollerPadding(height);
mStatusBar.userActivity();
@@ -557,7 +610,7 @@ public class NotificationPanelView extends PanelView implements
/**
* @return Whether we should intercept a gesture to open Quick Settings.
*/
- private boolean shouldIntercept(float x, float y, float yDiff) {
+ private boolean shouldQuickSettingsIntercept(float x, float y, float yDiff) {
if (!mQsExpansionEnabled) {
return false;
}
@@ -635,14 +688,33 @@ public class NotificationPanelView extends PanelView implements
protected void onExpandingStarted() {
super.onExpandingStarted();
mNotificationStackScroller.onExpansionStarted();
+ mIsExpanding = true;
}
@Override
protected void onExpandingFinished() {
super.onExpandingFinished();
mNotificationStackScroller.onExpansionStopped();
+ mIsExpanding = false;
+ }
+
+ @Override
+ protected void onOverExpansionChanged(float overExpansion) {
+ float currentOverScroll = mNotificationStackScroller.getCurrentOverScrolledPixels(true);
+ mNotificationStackScroller.setOverScrolledPixels(currentOverScroll + overExpansion
+ - mOverExpansion, true /* onTop */, false /* animate */);
+ super.onOverExpansionChanged(overExpansion);
+ }
+
+ @Override
+ protected void onTrackingStopped(boolean expand) {
+ super.onTrackingStopped(expand);
+ mOverExpansion = 0.0f;
+ mNotificationStackScroller.setOverScrolledPixels(0.0f, true /* onTop */,
+ true /* animate */);
}
+
@Override
public void onHeightChanged(ExpandableView view) {
requestPanelHeightUpdate();
@@ -657,6 +729,12 @@ public class NotificationPanelView extends PanelView implements
}
@Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ mPageSwiper.onConfigurationChanged();
+ }
+
+ @Override
public void onClick(View v) {
if (v == mHeader.getBackgroundView()) {
onQsExpansionStarted();
@@ -667,4 +745,40 @@ public class NotificationPanelView extends PanelView implements
}
}
}
+
+ @Override
+ public void onAnimationToSideStarted(boolean rightPage) {
+ if (rightPage) {
+ mKeyguardBottomArea.launchCamera();
+ } else {
+ mKeyguardBottomArea.launchPhone();
+ }
+ mBlockTouches = true;
+ }
+
+
+ @Override
+ public float getPageWidth() {
+ return getWidth();
+ }
+
+ @Override
+ public ArrayList<View> getTranslationViews() {
+ return mSwipeTranslationViews;
+ }
+
+ @Override
+ public View getLeftIcon() {
+ return mKeyguardBottomArea.getPhoneImageView();
+ }
+
+ @Override
+ public View getCenterIcon() {
+ return mKeyguardBottomArea.getLockIcon();
+ }
+
+ @Override
+ public View getRightIcon() {
+ return mKeyguardBottomArea.getCameraImageView();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
index ba0b66e..ea5b309 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ObservableScrollView.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.phone;
import android.content.Context;
import android.util.AttributeSet;
+import android.view.MotionEvent;
import android.view.View;
import android.widget.ScrollView;
@@ -28,6 +29,8 @@ public class ObservableScrollView extends ScrollView {
private Listener mListener;
private int mLastOverscrollAmount;
+ private boolean mDispatchingTouchEvent;
+ private boolean mTouchEnabled = true;
public ObservableScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -37,10 +40,18 @@ public class ObservableScrollView extends ScrollView {
mListener = listener;
}
+ public void setTouchEnabled(boolean touchEnabled) {
+ mTouchEnabled = touchEnabled;
+ }
+
public boolean isScrolledToBottom() {
return getScrollY() == getMaxScrollY();
}
+ public boolean isDispatchingTouchEvent() {
+ return mDispatchingTouchEvent;
+ }
+
private int getMaxScrollY() {
int scrollRange = 0;
if (getChildCount() > 0) {
@@ -52,6 +63,17 @@ public class ObservableScrollView extends ScrollView {
}
@Override
+ public boolean dispatchTouchEvent(MotionEvent ev) {
+ if (!mTouchEnabled) {
+ return false;
+ }
+ mDispatchingTouchEvent = true;
+ boolean result = super.dispatchTouchEvent(ev);
+ mDispatchingTouchEvent = false;
+ return result;
+ }
+
+ @Override
protected void onScrollChanged(int l, int t, int oldl, int oldt) {
super.onScrollChanged(l, t, oldl, oldt);
if (mListener != null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
index 8800625..b94f6f3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelBar.java
@@ -191,6 +191,7 @@ public class PanelBar extends FrameLayout {
pv.setExpandedFraction(0); // just in case
pv.setVisibility(View.GONE);
pv.cancelPeek();
+ pv.resetViews();
}
}
if (DEBUG) LOG("collapseAllPanels: animate=%s waiting=%s", animate, waiting);
@@ -222,7 +223,11 @@ public class PanelBar extends FrameLayout {
}
}
- public void onTrackingStopped(PanelView panel) {
+ public void onTrackingStopped(PanelView panel, boolean expand) {
mTracking = false;
}
+
+ public void onExpandingFinished() {
+
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
index 8631e3a..c5a9b85 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PanelView.java
@@ -35,9 +35,10 @@ import com.android.systemui.statusbar.FlingAnimationUtils;
import java.io.FileDescriptor;
import java.io.PrintWriter;
-public class PanelView extends FrameLayout {
+public abstract class PanelView extends FrameLayout {
public static final boolean DEBUG = PanelBar.DEBUG;
public static final String TAG = PanelView.class.getSimpleName();
+ protected float mOverExpansion;
private final void logf(String fmt, Object... args) {
Log.v(TAG, (mViewName != null ? (mViewName + ": ") : "") + String.format(fmt, args));
@@ -66,6 +67,7 @@ public class PanelView extends FrameLayout {
private float mInitialTouchX;
protected void onExpandingFinished() {
+ mBar.onExpandingFinished();
}
protected void onExpandingStarted() {
@@ -128,21 +130,24 @@ public class PanelView extends FrameLayout {
final float y = event.getY(pointerIndex);
final float x = event.getX(pointerIndex);
+ boolean waitForTouchSlop = hasConflictingGestures();
+
switch (event.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
- mTracking = true;
mInitialTouchY = y;
mInitialTouchX = x;
+ mInitialOffsetOnTouch = mExpandedHeight;
if (mVelocityTracker == null) {
initVelocityTracker();
}
trackMovement(event);
- if (mHeightAnimator != null) {
- mHeightAnimator.cancel(); // end any outstanding animations
+ if (!waitForTouchSlop || mHeightAnimator != null) {
+ if (mHeightAnimator != null) {
+ mHeightAnimator.cancel(); // end any outstanding animations
+ }
+ onTrackingStarted();
}
- onTrackingStarted();
- mInitialOffsetOnTouch = mExpandedHeight;
if (mExpandedHeight == 0) {
mJustPeeked = true;
runPeekAnimation();
@@ -164,15 +169,27 @@ public class PanelView extends FrameLayout {
break;
case MotionEvent.ACTION_MOVE:
- final float h = y - mInitialTouchY + mInitialOffsetOnTouch;
- if (h > mPeekHeight) {
+ float h = y - mInitialTouchY;
+ if (waitForTouchSlop && !mTracking && Math.abs(h) > mTouchSlop
+ && Math.abs(h) > Math.abs(x - mInitialTouchX)) {
+ mInitialOffsetOnTouch = mExpandedHeight;
+ mInitialTouchX = x;
+ mInitialTouchY = y;
+ if (mHeightAnimator != null) {
+ mHeightAnimator.cancel(); // end any outstanding animations
+ }
+ onTrackingStarted();
+ h = 0;
+ }
+ final float newHeight = h + mInitialOffsetOnTouch;
+ if (newHeight > mPeekHeight) {
if (mPeekAnimator != null && mPeekAnimator.isStarted()) {
mPeekAnimator.cancel();
}
mJustPeeked = false;
}
- if (!mJustPeeked) {
- setExpandedHeightInternal(h);
+ if (!mJustPeeked && (!waitForTouchSlop || mTracking)) {
+ setExpandedHeightInternal(newHeight);
mBar.panelExpansionChanged(PanelView.this, mExpandedFraction);
}
@@ -181,25 +198,28 @@ public class PanelView extends FrameLayout {
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_CANCEL:
- mTracking = false;
mTrackingPointer = -1;
- onTrackingStopped();
trackMovement(event);
- flingWithCurrentVelocity();
+ boolean expand = flingWithCurrentVelocity();
+ onTrackingStopped(expand);
if (mVelocityTracker != null) {
mVelocityTracker.recycle();
mVelocityTracker = null;
}
break;
}
- return true;
+ return !waitForTouchSlop || mTracking;
}
- protected void onTrackingStopped() {
- mBar.onTrackingStopped(PanelView.this);
+ protected abstract boolean hasConflictingGestures();
+
+ protected void onTrackingStopped(boolean expand) {
+ mTracking = false;
+ mBar.onTrackingStopped(PanelView.this, expand);
}
protected void onTrackingStarted() {
+ mTracking = true;
mBar.onTrackingStarted(PanelView.this);
onExpandingStarted();
}
@@ -302,7 +322,10 @@ public class PanelView extends FrameLayout {
mMaxPanelHeight = -1;
}
- private void flingWithCurrentVelocity() {
+ /**
+ * @return whether the panel will be expanded after the animation
+ */
+ private boolean flingWithCurrentVelocity() {
float vel = getCurrentVelocity();
boolean expand;
if (Math.abs(vel) < mFlingAnimationUtils.getMinVelocityPxPerSecond()) {
@@ -311,11 +334,16 @@ public class PanelView extends FrameLayout {
expand = vel > 0;
}
fling(vel, expand);
+ return expand;
}
protected void fling(float vel, boolean expand) {
cancelPeek();
float target = expand ? getMaxPanelHeight() : 0.0f;
+ if (target == mExpandedHeight) {
+ onExpandingFinished();
+ return;
+ }
ValueAnimator animator = ValueAnimator.ofFloat(mExpandedHeight, target);
if (expand) {
mFlingAnimationUtils.apply(animator, mExpandedHeight, target, vel, getHeight());
@@ -403,6 +431,11 @@ public class PanelView extends FrameLayout {
public void setExpandedHeightInternal(float h) {
float fh = getMaxPanelHeight();
mExpandedHeight = Math.min(fh, h);
+ float overExpansion = h - fh;
+ overExpansion = Math.max(0, overExpansion);
+ if (overExpansion != mOverExpansion) {
+ onOverExpansionChanged(overExpansion);
+ }
if (DEBUG) {
logf("setExpansion: height=%.1f fh=%.1f tracking=%s", h, fh, mTracking ? "T" : "f");
@@ -412,6 +445,10 @@ public class PanelView extends FrameLayout {
mExpandedFraction = Math.min(1f, (fh == 0) ? 0 : h / fh);
}
+ protected void onOverExpansionChanged(float overExpansion) {
+ mOverExpansion = overExpansion;
+ }
+
protected void onHeightUpdated(float expandedHeight) {
requestLayout();
}
@@ -503,4 +540,6 @@ public class PanelView extends FrameLayout {
mHeightAnimator, ((mHeightAnimator !=null && mHeightAnimator.isStarted())?" (started)":"")
));
}
+
+ public abstract void resetViews();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 152ca3f..0e5b7e1 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -22,6 +22,7 @@ import static android.app.StatusBarManager.NAVIGATION_HINT_IME_SHOWN;
import static android.app.StatusBarManager.WINDOW_STATE_HIDDEN;
import static android.app.StatusBarManager.WINDOW_STATE_SHOWING;
import static android.app.StatusBarManager.windowStateToString;
+import static com.android.keyguard.KeyguardHostView.OnDismissAction;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_LIGHTS_OUT;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_OPAQUE;
import static com.android.systemui.statusbar.phone.BarTransitions.MODE_SEMI_TRANSPARENT;
@@ -63,6 +64,7 @@ import android.os.SystemClock;
import android.os.UserHandle;
import android.provider.Settings;
import android.provider.Settings.Global;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.util.ArraySet;
import android.util.DisplayMetrics;
@@ -85,7 +87,6 @@ import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.DecelerateInterpolator;
import android.widget.FrameLayout;
-import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
@@ -120,10 +121,12 @@ import com.android.systemui.statusbar.policy.UserInfoController;
import com.android.systemui.statusbar.policy.LocationControllerImpl;
import com.android.systemui.statusbar.policy.NetworkControllerImpl;
import com.android.systemui.statusbar.policy.RotationLockControllerImpl;
+import com.android.systemui.statusbar.policy.ZenModeController;
import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout;
import com.android.systemui.statusbar.stack.NotificationStackScrollLayout.OnChildLocationsChangedListener;
import com.android.systemui.statusbar.stack.StackScrollState.ViewState;
+import com.android.systemui.volume.VolumeComponent;
import java.io.FileDescriptor;
import java.io.PrintWriter;
@@ -195,8 +198,9 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
NetworkControllerImpl mNetworkController;
RotationLockControllerImpl mRotationLockController;
UserInfoController mUserInfoController;
- ZenModeControllerImpl mZenModeController;
+ ZenModeController mZenModeController;
CastControllerImpl mCastController;
+ VolumeComponent mVolumeComponent;
int mNaturalBarHeight = -1;
int mIconSize = -1;
@@ -208,6 +212,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
PhoneStatusBarView mStatusBarView;
private int mStatusBarWindowState = WINDOW_STATE_SHOWING;
private StatusBarWindowManager mStatusBarWindowManager;
+ private UnlockMethodCache mUnlockMethodCache;
int mPixelFormat;
Object mQueueLock = new Object();
@@ -371,6 +376,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private ViewMediatorCallback mKeyguardViewMediatorCallback;
+ private ScrimController mScrimController;
private final Runnable mAutohide = new Runnable() {
@Override
@@ -499,6 +505,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
+ protected void setShowLockscreenNotifications(boolean show) {
+ super.setShowLockscreenNotifications(show);
+ updateStackScrollerState();
+ }
+
+ @Override
public void start() {
mDisplay = ((WindowManager)mContext.getSystemService(Context.WINDOW_SERVICE))
.getDefaultDisplay();
@@ -521,6 +533,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
Settings.Global.getUriFor(SETTING_HEADS_UP_TICKER), true,
mHeadsUpObserver);
}
+ mUnlockMethodCache = UnlockMethodCache.getInstance(mContext);
startKeyguard();
}
@@ -637,9 +650,12 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
SpeedBumpView speedBump = (SpeedBumpView) LayoutInflater.from(mContext).inflate(
R.layout.status_bar_notification_speed_bump, mStackScroller, false);
mStackScroller.setSpeedBumpView(speedBump);
-
mExpandedContents = mStackScroller;
+ mScrimController = new ScrimController(mStatusBarWindow.findViewById(R.id.scrim_behind),
+ mStatusBarWindow.findViewById(R.id.scrim_in_front));
+ mStatusBarView.setScrimController(mScrimController);
+
mHeader = (StatusBarHeaderView) mStatusBarWindow.findViewById(R.id.header);
mHeader.setActivityStarter(this);
mKeyguardStatusView = mStatusBarWindow.findViewById(R.id.keyguard_status_view);
@@ -679,7 +695,8 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mRotationLockController = new RotationLockControllerImpl(mContext);
}
mUserInfoController = new UserInfoController(mContext);
- mZenModeController = new ZenModeControllerImpl(mContext, mHandler);
+ mVolumeComponent = getComponent(VolumeComponent.class);
+ mZenModeController = mVolumeComponent.getZenController();
mCastController = new CastControllerImpl(mContext);
final SignalClusterView signalCluster =
(SignalClusterView)mStatusBarView.findViewById(R.id.signal_cluster);
@@ -742,7 +759,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
final QSTileHost qsh = new QSTileHost(mContext, this,
mBluetoothController, mLocationController, mRotationLockController,
mNetworkController, mZenModeController, null /*tethering*/,
- mCastController);
+ mCastController, mVolumeComponent);
for (QSTile<?> tile : qsh.getTiles()) {
mQSPanel.addTile(tile);
}
@@ -774,7 +791,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void startKeyguard() {
KeyguardViewMediator keyguardViewMediator = getComponent(KeyguardViewMediator.class);
mStatusBarKeyguardViewManager = keyguardViewMediator.registerStatusBar(this,
- mStatusBarWindow, mStatusBarWindowManager);
+ mStatusBarWindow, mStatusBarWindowManager, mScrimController);
mKeyguardViewMediatorCallback = keyguardViewMediator.getViewMediatorCallback();
}
@@ -879,7 +896,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
};
- View.OnTouchListener mHomeSearchActionListener = new View.OnTouchListener() {
+ View.OnTouchListener mHomeActionListener = new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
switch(event.getAction()) {
case MotionEvent.ACTION_DOWN:
@@ -914,8 +931,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mNavigationBarView.getRecentsButton().setOnClickListener(mRecentsClickListener);
mNavigationBarView.getRecentsButton().setOnTouchListener(mRecentsPreloadOnTouchListener);
- mNavigationBarView.getHomeButton().setOnTouchListener(mHomeSearchActionListener);
- mNavigationBarView.getSearchLight().setOnTouchListener(mHomeSearchActionListener);
+ mNavigationBarView.getHomeButton().setOnTouchListener(mHomeActionListener);
updateSearchPanel();
}
@@ -965,7 +981,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
private void addHeadsUpView() {
WindowManager.LayoutParams lp = new WindowManager.LayoutParams(
- LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT,
+ LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT,
WindowManager.LayoutParams.TYPE_STATUS_BAR_PANEL, // above the status bar!
WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN
| WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS
@@ -1028,13 +1044,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
- public void addNotificationInternal(StatusBarNotification notification) {
+ public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
if (DEBUG) Log.d(TAG, "addNotification score=" + notification.getScore());
Entry shadeEntry = createNotificationViews(notification);
if (shadeEntry == null) {
return;
}
if (mZenMode != Global.ZEN_MODE_OFF && mIntercepted.tryIntercept(notification)) {
+ // Forward the ranking so we can sort the new notification.
+ mNotificationData.updateRanking(ranking);
return;
}
if (mUseHeadsUp && shouldInterrupt(notification)) {
@@ -1074,7 +1092,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
tick(notification, true);
}
}
- addNotificationViews(shadeEntry);
+ addNotificationViews(shadeEntry, ranking);
// Recalculate the position of the sliding windows and the titles.
setAreThereNotifications();
updateExpandedViewPos(EXPANDED_LEAVE_ALONE);
@@ -1090,14 +1108,14 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
@Override
- public void updateNotification(StatusBarNotification notification) {
- super.updateNotification(notification);
+ public void updateNotificationInternal(StatusBarNotification notification, Ranking ranking) {
+ super.updateNotificationInternal(notification, ranking);
mIntercepted.update(notification);
}
@Override
- public void removeNotificationInternal(String key) {
- StatusBarNotification old = removeNotificationViews(key);
+ public void removeNotificationInternal(String key, Ranking ranking) {
+ StatusBarNotification old = removeNotificationViews(key, ranking);
if (SPEW) Log.d(TAG, "removeNotification key=" + key + " old=" + old);
if (old != null) {
@@ -1134,7 +1152,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
R.integer.config_show_search_delay);
}
- private void loadNotificationShade() {
+ private void updateNotificationShade() {
if (mStackScroller == null) return;
int N = mNotificationData.size();
@@ -1144,7 +1162,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
final boolean provisioned = isDeviceProvisioned();
// If the device hasn't been through Setup, we only show system notifications
for (int i=0; i<N; i++) {
- Entry ent = mNotificationData.get(N-i-1);
+ Entry ent = mNotificationData.get(i);
if (!(provisioned || showNotificationEvenIfUnprovisioned(ent.notification))) continue;
// TODO How do we want to badge notifcations from profiles.
@@ -1175,26 +1193,75 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
for (int i=0; i<toShow.size(); i++) {
View v = toShow.get(i);
if (v.getParent() == null) {
- mStackScroller.addView(v, i);
+ mStackScroller.addView(v);
}
}
+ // So after all this work notifications still aren't sorted correctly.
+ // Let's do that now by advancing through toShow and mStackScroller in
+ // lock-step, making sure mStackScroller matches what we see in toShow.
+ int j = 0;
+ for (int i = 0; i < mStackScroller.getChildCount(); i++) {
+ View child = mStackScroller.getChildAt(i);
+ if (!(child instanceof ExpandableNotificationRow)) {
+ // We don't care about non-notification views.
+ continue;
+ }
+
+ if (child == toShow.get(j)) {
+ // Everything is well, advance both lists.
+ j++;
+ continue;
+ }
+
+ // Oops, wrong notification at this position. Put the right one
+ // here and advance both lists.
+ mStackScroller.changeViewPosition(toShow.get(j), i);
+ j++;
+ }
+ updateRowStates();
+ updateSpeedbump();
mNotificationPanel.setQsExpansionEnabled(provisioned && mUserSetup);
}
+ private void updateSpeedbump() {
+ int speedbumpIndex = -1;
+ int currentIndex = 0;
+ for (int i = 0; i < mNotificationData.size(); i++) {
+ Entry entry = mNotificationData.get(i);
+ if (entry.row.getParent() == null) {
+ // This view isn't even added, so the stack scroller doesn't
+ // know about it. Ignore completely.
+ continue;
+ }
+ if (entry.row.getVisibility() != View.GONE &&
+ mNotificationData.isAmbient(entry.key)) {
+ speedbumpIndex = currentIndex;
+ break;
+ }
+ currentIndex++;
+ }
+ mStackScroller.updateSpeedBumpIndex(speedbumpIndex);
+ }
+
@Override
- protected void updateNotificationIcons() {
+ protected void updateNotifications() {
+ // TODO: Move this into updateNotificationIcons()?
if (mNotificationIcons == null) return;
- loadNotificationShade();
+ updateNotificationShade();
+ updateNotificationIcons();
+ }
+ private void updateNotificationIcons() {
final LinearLayout.LayoutParams params
= new LinearLayout.LayoutParams(mIconSize + 2*mIconHPadding, mNaturalBarHeight);
int N = mNotificationData.size();
if (DEBUG) {
- Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" + mNotificationIcons);
+ Log.d(TAG, "refreshing icons: " + N + " notifications, mNotificationIcons=" +
+ mNotificationIcons);
}
ArrayList<View> toShow = new ArrayList<View>();
@@ -1202,7 +1269,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
final boolean provisioned = isDeviceProvisioned();
// If the device hasn't been through Setup, we only show system notifications
for (int i=0; i<N; i++) {
- Entry ent = mNotificationData.get(N-i-1);
+ Entry ent = mNotificationData.get(i);
if (!((provisioned && ent.notification.getScore() >= HIDE_ICONS_BELOW_SCORE)
|| showNotificationEvenIfUnprovisioned(ent.notification))) continue;
if (!notificationIsForCurrentProfiles(ent.notification)) continue;
@@ -1445,6 +1512,10 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
startActivityDismissingKeyguard(intent, false);
}
+ public ScrimController getScrimController() {
+ return mScrimController;
+ }
+
/**
* All changes to the status bar and notifications funnel through here and are batched.
*/
@@ -2346,6 +2417,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
};
+ @Override
+ protected void startNotificationActivity(OnDismissAction action) {
+ if (mStatusBarKeyguardViewManager.isShowing()) {
+ mStatusBarKeyguardViewManager.dismissWithAction(action);
+ } else {
+ action.onDismiss();
+ }
+ }
+
// SystemUIService notifies SystemBars of configuration changes, which then calls down here
@Override
protected void onConfigurationChanged(Configuration newConfig) {
@@ -2366,7 +2446,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
public void userSwitched(int newUserId) {
if (MULTIUSER_DEBUG) mNotificationPanelDebugText.setText("USER " + newUserId);
animateCollapsePanels();
- updateNotificationIcons();
+ updateNotifications();
resetUserSetupObserver();
}
@@ -2752,7 +2832,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
mKeyguardStatusView.setVisibility(View.VISIBLE);
mKeyguardIndicationTextView.setVisibility(View.VISIBLE);
mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
- mNotificationPanel.closeQs();
+ mNotificationPanel.resetViews();
} else {
mKeyguardStatusView.setVisibility(View.GONE);
mKeyguardIndicationTextView.setVisibility(View.GONE);
@@ -2760,22 +2840,27 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
mKeyguardBottomArea.setVisibility(View.VISIBLE);
mHeader.setKeyguardShowing(true);
+ mNotificationPanel.setKeyguardShowing(true);
+ mScrimController.setKeyguardShowing(true);
} else {
mKeyguardBottomArea.setVisibility(View.GONE);
mHeader.setKeyguardShowing(false);
+ mNotificationPanel.setKeyguardShowing(false);
+ mScrimController.setKeyguardShowing(false);
}
updateStackScrollerState();
updatePublicMode();
- updateRowStates();
- updateSpeedBump();
+ updateNotifications();
checkBarModes();
- updateNotificationIcons();
updateCarrierLabelVisibility(false);
}
public void updateStackScrollerState() {
+ if (mStackScroller == null) return;
mStackScroller.setDimmed(mState == StatusBarState.KEYGUARD, false /* animate */);
+ mStackScroller.setVisibility(!mShowLockscreenNotifications && mState == StatusBarState.KEYGUARD
+ ? View.INVISIBLE : View.VISIBLE);
}
public void userActivity() {
@@ -2860,10 +2945,15 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
}
}
- public void onTrackingStopped() {
+ public void onTrackingStopped(boolean expand) {
if (mState == StatusBarState.KEYGUARD) {
mKeyguardIndicationTextView.switchIndication(mKeyguardHotwordPhrase);
}
+ if (mState == StatusBarState.KEYGUARD || mState == StatusBarState.SHADE_LOCKED) {
+ if (!expand && !mUnlockMethodCache.isMethodInsecure()) {
+ showBouncer();
+ }
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
index 084bfcf..910d88c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarView.java
@@ -36,21 +36,16 @@ public class PhoneStatusBarView extends PanelBar {
private static final boolean DEBUG_GESTURES = true;
PhoneStatusBar mBar;
- int mScrimColor;
- int mScrimColorKeyguard;
- PanelView mFadingPanel = null;
PanelView mLastFullyOpenedPanel = null;
PanelView mNotificationPanel;
- private boolean mShouldFade;
private final PhoneStatusBarTransitions mBarTransitions;
+ private ScrimController mScrimController;
public PhoneStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
Resources res = getContext().getResources();
- mScrimColor = res.getColor(R.color.notification_panel_scrim_color);
- mScrimColorKeyguard = res.getColor(R.color.notification_panel_scrim_color_keyguard);
mBarTransitions = new PhoneStatusBarTransitions(this);
}
@@ -62,6 +57,10 @@ public class PhoneStatusBarView extends PanelBar {
mBar = bar;
}
+ public void setScrimController(ScrimController scrimController) {
+ mScrimController = scrimController;
+ }
+
@Override
public void onFinishInflate() {
mBarTransitions.init();
@@ -110,27 +109,11 @@ public class PhoneStatusBarView extends PanelBar {
}
@Override
- public void startOpeningPanel(PanelView panel) {
- super.startOpeningPanel(panel);
- // we only want to start fading if this is the "first" or "last" panel,
- // which is kind of tricky to determine
- mShouldFade = (mFadingPanel == null || mFadingPanel.isFullyExpanded());
- if (DEBUG) {
- Log.v(TAG, "start opening: " + panel + " shouldfade=" + mShouldFade);
- }
- mFadingPanel = panel;
- }
-
- @Override
public void onAllPanelsCollapsed() {
super.onAllPanelsCollapsed();
// give animations time to settle
mBar.makeExpandedInvisibleSoon();
- mFadingPanel = null;
mLastFullyOpenedPanel = null;
- if (mScrimColor != 0 && ActivityManager.isHighEndGfx() && mBar.mStatusBarWindow != null) {
- mBar.mStatusBarWindow.setBackgroundColor(0);
- }
}
@Override
@@ -139,9 +122,7 @@ public class PhoneStatusBarView extends PanelBar {
if (openPanel != mLastFullyOpenedPanel) {
openPanel.sendAccessibilityEvent(AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
- mFadingPanel = openPanel;
mLastFullyOpenedPanel = openPanel;
- mShouldFade = true; // now you own the fade, mister
}
@Override
@@ -163,12 +144,19 @@ public class PhoneStatusBarView extends PanelBar {
public void onTrackingStarted(PanelView panel) {
super.onTrackingStarted(panel);
mBar.onTrackingStarted();
+ mScrimController.onTrackingStarted();
+ }
+
+ @Override
+ public void onTrackingStopped(PanelView panel, boolean expand) {
+ super.onTrackingStopped(panel, expand);
+ mBar.onTrackingStopped(expand);
}
@Override
- public void onTrackingStopped(PanelView panel) {
- super.onTrackingStopped(panel);
- mBar.onTrackingStopped();
+ public void onExpandingFinished() {
+ super.onExpandingFinished();
+ mScrimController.onExpandingFinished();
}
@Override
@@ -184,27 +172,7 @@ public class PhoneStatusBarView extends PanelBar {
Log.v(TAG, "panelExpansionChanged: f=" + frac);
}
- if (panel == mFadingPanel && mScrimColor != 0 && ActivityManager.isHighEndGfx()
- && mBar.mStatusBarWindow != null) {
- if (mShouldFade) {
- int scrimColor = (mBar.getBarState() == StatusBarState.KEYGUARD
- || mBar.getBarState() == StatusBarState.SHADE_LOCKED)
- ? mScrimColorKeyguard
- : mScrimColor;
- frac = mPanelExpandedFractionSum; // don't judge me
- // let's start this 20% of the way down the screen
- frac = frac * 1.2f - 0.2f;
- if (frac <= 0) {
- mBar.mStatusBarWindow.setBackgroundColor(0);
- } else {
- // woo, special effects
- final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
- // attenuate background color alpha by k
- final int color = (int) ((scrimColor >>> 24) * k) << 24 | (scrimColor & 0xFFFFFF);
- mBar.mStatusBarWindow.setBackgroundColor(color);
- }
- }
- }
+ mScrimController.setPanelExpansion(frac);
// fade out the panel as it gets buried into the status bar to avoid overdrawing the
// status bar on the last frame of a close animation
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 7029898..1344703 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -21,6 +21,7 @@ import android.content.Intent;
import android.os.HandlerThread;
import android.os.Looper;
+import com.android.systemui.R;
import com.android.systemui.qs.QSTile;
import com.android.systemui.qs.tiles.AirplaneModeTile;
import com.android.systemui.qs.tiles.BluetoothTile;
@@ -29,11 +30,10 @@ import com.android.systemui.qs.tiles.CastTile;
import com.android.systemui.qs.tiles.CellularTile;
import com.android.systemui.qs.tiles.ColorInversionTile;
import com.android.systemui.qs.tiles.LocationTile;
-import com.android.systemui.qs.tiles.RingerModeTile;
+import com.android.systemui.qs.tiles.NotificationsTile;
import com.android.systemui.qs.tiles.RotationLockTile;
import com.android.systemui.qs.tiles.HotspotTile;
import com.android.systemui.qs.tiles.WifiTile;
-import com.android.systemui.qs.tiles.ZenModeTile;
import com.android.systemui.settings.CurrentUserTracker;
import com.android.systemui.statusbar.policy.BluetoothController;
import com.android.systemui.statusbar.policy.CastController;
@@ -42,6 +42,7 @@ import com.android.systemui.statusbar.policy.NetworkController;
import com.android.systemui.statusbar.policy.RotationLockController;
import com.android.systemui.statusbar.policy.TetheringController;
import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.volume.VolumeComponent;
import java.util.ArrayList;
import java.util.List;
@@ -60,13 +61,15 @@ public class QSTileHost implements QSTile.Host {
private final CastController mCast;
private final Looper mLooper;
private final CurrentUserTracker mUserTracker;
+ private final VolumeComponent mVolume;
private final ArrayList<QSTile<?>> mTiles = new ArrayList<QSTile<?>>();
+ private final int mFeedbackStartDelay;
public QSTileHost(Context context, PhoneStatusBar statusBar,
BluetoothController bluetooth, LocationController location,
RotationLockController rotation, NetworkController network,
ZenModeController zen, TetheringController tethering,
- CastController cast) {
+ CastController cast, VolumeComponent volume) {
mContext = context;
mStatusBar = statusBar;
mBluetooth = bluetooth;
@@ -76,6 +79,7 @@ public class QSTileHost implements QSTile.Host {
mZen = zen;
mTethering = tethering;
mCast = cast;
+ mVolume = volume;
final HandlerThread ht = new HandlerThread(QSTileHost.class.getSimpleName());
ht.start();
@@ -86,8 +90,7 @@ public class QSTileHost implements QSTile.Host {
mTiles.add(new ColorInversionTile(this));
mTiles.add(new CellularTile(this));
mTiles.add(new AirplaneModeTile(this));
- mTiles.add(new ZenModeTile(this));
- mTiles.add(new RingerModeTile(this));
+ mTiles.add(new NotificationsTile(this));
mTiles.add(new RotationLockTile(this));
mTiles.add(new LocationTile(this));
mTiles.add(new CastTile(this));
@@ -103,6 +106,7 @@ public class QSTileHost implements QSTile.Host {
}
};
mUserTracker.startTracking();
+ mFeedbackStartDelay = mContext.getResources().getInteger(R.integer.feedback_start_delay);
}
@Override
@@ -112,7 +116,7 @@ public class QSTileHost implements QSTile.Host {
@Override
public void startSettingsActivity(final Intent intent) {
- mStatusBar.postStartSettingsActivity(intent, QSTile.FEEDBACK_START_DELAY);
+ mStatusBar.postStartSettingsActivity(intent, mFeedbackStartDelay);
}
@Override
@@ -169,4 +173,9 @@ public class QSTileHost implements QSTile.Host {
public CastController getCastController() {
return mCast;
}
+
+ @Override
+ public VolumeComponent getVolumeComponent() {
+ return mVolume;
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
new file mode 100644
index 0000000..6156fc3
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -0,0 +1,193 @@
+/*
+ * Copyright (C) 2014 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.phone;
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.ValueAnimator;
+import android.content.res.Resources;
+import android.graphics.Color;
+import android.graphics.drawable.ColorDrawable;
+import android.view.View;
+import android.view.ViewTreeObserver;
+import android.view.animation.AccelerateInterpolator;
+import android.view.animation.AnimationUtils;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.Interpolator;
+import android.view.animation.LinearInterpolator;
+
+/**
+ * Controls both the scrim behind the notifications and in front of the notifications (when a
+ * security method gets shown).
+ */
+public class ScrimController implements ViewTreeObserver.OnPreDrawListener {
+
+ private static final float SCRIM_BEHIND_ALPHA = 0.62f;
+ private static final float SCRIM_BEHIND_ALPHA_KEYGUARD = 0.5f;
+ private static final float SCRIM_IN_FRONT_ALPHA = 0.75f;
+ private static final long ANIMATION_DURATION = 220;
+
+ private final View mScrimBehind;
+ private final View mScrimInFront;
+ private final UnlockMethodCache mUnlockMethodCache;
+
+ private boolean mKeyguardShowing;
+ private float mFraction;
+
+ private boolean mDarkenWhileDragging;
+ private boolean mBouncerShowing;
+ private boolean mAnimateChange;
+ private boolean mUpdatePending;
+ private boolean mExpanding;
+
+ private final Interpolator mInterpolator = new DecelerateInterpolator();
+
+ public ScrimController(View scrimBehind, View scrimInFront) {
+ mScrimBehind = scrimBehind;
+ mScrimInFront = scrimInFront;
+ mUnlockMethodCache = UnlockMethodCache.getInstance(scrimBehind.getContext());
+ }
+
+ public void setKeyguardShowing(boolean showing) {
+ mKeyguardShowing = showing;
+ scheduleUpdate();
+ }
+
+ public void onTrackingStarted() {
+ mExpanding = true;
+ mDarkenWhileDragging = !mUnlockMethodCache.isMethodInsecure();
+ }
+
+ public void onExpandingFinished() {
+ mExpanding = false;
+ }
+
+ public void setPanelExpansion(float fraction) {
+ mFraction = fraction;
+ scheduleUpdate();
+ }
+
+ public void setBouncerShowing(boolean showing) {
+ mBouncerShowing = showing;
+ mAnimateChange = !mExpanding;
+ scheduleUpdate();
+ }
+
+ private void scheduleUpdate() {
+ if (mUpdatePending) return;
+ mScrimBehind.getViewTreeObserver().addOnPreDrawListener(this);
+ mUpdatePending = true;
+ }
+
+ private void updateScrims() {
+ if (!mKeyguardShowing) {
+ updateScrimNormal();
+ setScrimInFrontColor(0);
+ } else {
+ updateScrimKeyguard();
+ }
+ mAnimateChange = false;
+ }
+
+ private void updateScrimKeyguard() {
+ if (mExpanding && mDarkenWhileDragging) {
+ float behindFraction = Math.max(0, Math.min(mFraction, 1));
+ float fraction = 1 - behindFraction;
+ setScrimInFrontColor(fraction * SCRIM_IN_FRONT_ALPHA);
+ setScrimBehindColor(behindFraction * SCRIM_BEHIND_ALPHA_KEYGUARD);
+ } else if (mBouncerShowing) {
+ setScrimInFrontColor(SCRIM_IN_FRONT_ALPHA);
+ setScrimBehindColor(0f);
+ } else {
+ setScrimInFrontColor(0f);
+ setScrimBehindColor(SCRIM_BEHIND_ALPHA_KEYGUARD);
+ }
+ }
+
+ private void updateScrimNormal() {
+ float frac = mFraction;
+ // let's start this 20% of the way down the screen
+ frac = frac * 1.2f - 0.2f;
+ if (frac <= 0) {
+ setScrimBehindColor(0);
+ } else {
+ // woo, special effects
+ final float k = (float)(1f-0.5f*(1f-Math.cos(3.14159f * Math.pow(1f-frac, 2f))));
+ setScrimBehindColor(k * SCRIM_BEHIND_ALPHA);
+ }
+ }
+
+ private void setScrimBehindColor(float alpha) {
+ setScrimColor(mScrimBehind, alpha);
+ }
+
+ private void setScrimInFrontColor(float alpha) {
+ setScrimColor(mScrimInFront, alpha);
+ if (alpha == 0f) {
+ mScrimInFront.setClickable(false);
+ } else {
+
+ // Eat touch events.
+ mScrimInFront.setClickable(true);
+ }
+ }
+
+ private void setScrimColor(View scrim, float alpha) {
+ int color = Color.argb((int) (alpha * 255), 0, 0, 0);
+ if (mAnimateChange) {
+ startScrimAnimation(scrim, color);
+ } else {
+ scrim.setBackgroundColor(color);
+ }
+ }
+
+ private void startScrimAnimation(final View scrim, int targetColor) {
+ int current = getBackgroundAlpha(scrim);
+ int target = Color.alpha(targetColor);
+ if (current == targetColor) {
+ return;
+ }
+ ValueAnimator anim = ValueAnimator.ofInt(current, target);
+ anim.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ int value = (int) animation.getAnimatedValue();
+ scrim.setBackgroundColor(Color.argb(value, 0, 0, 0));
+ }
+ });
+ anim.setInterpolator(mInterpolator);
+ anim.setDuration(ANIMATION_DURATION);
+ anim.start();
+ }
+
+ private int getBackgroundAlpha(View scrim) {
+ if (scrim.getBackground() instanceof ColorDrawable) {
+ ColorDrawable drawable = (ColorDrawable) scrim.getBackground();
+ return Color.alpha(drawable.getColor());
+ } else {
+ return 0;
+ }
+ }
+
+ @Override
+ public boolean onPreDraw() {
+ mScrimBehind.getViewTreeObserver().removeOnPreDrawListener(this);
+ mUpdatePending = false;
+ updateScrims();
+ return true;
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
index 389e725..3245f1a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHeaderView.java
@@ -38,6 +38,11 @@ import com.android.systemui.statusbar.policy.UserInfoController;
*/
public class StatusBarHeaderView extends RelativeLayout implements View.OnClickListener {
+ /**
+ * How much the header expansion gets rubberbanded while expanding the panel.
+ */
+ private static final float EXPANSION_RUBBERBAND_FACTOR = 0.35f;
+
private boolean mExpanded;
private boolean mKeyguardShowing;
@@ -128,6 +133,8 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
updateVisibilities();
updateSystemIconsLayoutParams();
updateBrightnessControllerState();
+ updateZTranslation();
+ updateClickTargets();
if (mQSPanel != null) {
mQSPanel.setExpanded(expanded);
}
@@ -202,18 +209,30 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
}
}
+ private void updateClickTargets() {
+ mDateTime.setClickable(mExpanded);
+ mMultiUserSwitch.setClickable(mExpanded);
+ }
+
+ private void updateZTranslation() {
+
+ // If we are on the Keyguard, we need to set our z position to zero, so we don't get
+ // shadows.
+ if (mKeyguardShowing && !mExpanded) {
+ setZ(0);
+ } else {
+ setTranslationZ(0);
+ }
+ }
+
public void setExpansion(float height) {
+ height = (height - mCollapsedHeight) * EXPANSION_RUBBERBAND_FACTOR + mCollapsedHeight;
if (height < mCollapsedHeight) {
height = mCollapsedHeight;
}
if (height > mExpandedHeight) {
height = mExpandedHeight;
}
- if (mExpanded) {
- mBackground.setTranslationY(-(mExpandedHeight - height));
- } else {
- mBackground.setTranslationY(0);
- }
setClipping(height);
}
@@ -247,14 +266,10 @@ public class StatusBarHeaderView extends RelativeLayout implements View.OnClickL
public void setKeyguardShowing(boolean keyguardShowing) {
mKeyguardShowing = keyguardShowing;
- if (keyguardShowing) {
- setZ(0);
- } else {
- setTranslationZ(0);
- }
updateHeights();
updateWidth();
updateVisibilities();
+ updateZTranslation();
}
public void setUserInfoController(UserInfoController userInfoController) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 1040c15..d5551b8 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -29,6 +29,8 @@ import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
+import static com.android.keyguard.KeyguardHostView.OnDismissAction;
+
/**
* Manages creating, showing, hiding and resetting the keyguard within the status bar. Calls back
* via {@link ViewMediatorCallback} to poke the wake lock and report that the keyguard is done,
@@ -43,6 +45,7 @@ public class StatusBarKeyguardViewManager {
private LockPatternUtils mLockPatternUtils;
private ViewMediatorCallback mViewMediatorCallback;
private PhoneStatusBar mPhoneStatusBar;
+ private ScrimController mScrimController;
private ViewGroup mContainer;
private StatusBarWindowManager mStatusBarWindowManager;
@@ -66,10 +69,12 @@ public class StatusBarKeyguardViewManager {
}
public void registerStatusBar(PhoneStatusBar phoneStatusBar,
- ViewGroup container, StatusBarWindowManager statusBarWindowManager) {
+ ViewGroup container, StatusBarWindowManager statusBarWindowManager,
+ ScrimController scrimController) {
mPhoneStatusBar = phoneStatusBar;
mContainer = container;
mStatusBarWindowManager = statusBarWindowManager;
+ mScrimController = scrimController;
mBouncer = new KeyguardBouncer(mContext, mViewMediatorCallback, mLockPatternUtils,
mStatusBarWindowManager, container);
}
@@ -96,7 +101,7 @@ public class StatusBarKeyguardViewManager {
mBouncer.show();
} else {
mPhoneStatusBar.showKeyguard();
- mBouncer.hide();
+ mBouncer.hide(false /* destroyView */);
mBouncer.prepare();
}
}
@@ -108,6 +113,13 @@ public class StatusBarKeyguardViewManager {
updateStates();
}
+ public void dismissWithAction(OnDismissAction r) {
+ if (!mOccluded) {
+ mBouncer.showWithDismissAction(r);
+ }
+ updateStates();
+ }
+
/**
* Reset the state of the view.
*/
@@ -115,7 +127,7 @@ public class StatusBarKeyguardViewManager {
if (mShowing) {
if (mOccluded) {
mPhoneStatusBar.hideKeyguard();
- mBouncer.hide();
+ mBouncer.hide(false /* destroyView */);
} else {
showBouncerOrKeyguard();
}
@@ -175,7 +187,7 @@ public class StatusBarKeyguardViewManager {
mShowing = false;
mPhoneStatusBar.hideKeyguard();
mStatusBarWindowManager.setKeyguardShowing(false);
- mBouncer.hide();
+ mBouncer.hide(true /* destroyView */);
mViewMediatorCallback.keyguardGone();
updateStates();
}
@@ -207,7 +219,7 @@ public class StatusBarKeyguardViewManager {
*/
public boolean onBackPressed() {
if (mBouncer.isShowing()) {
- mBouncer.hide();
+ mBouncer.hide(false /* destroyView */);
mPhoneStatusBar.showKeyguard();
updateStates();
return true;
@@ -244,6 +256,7 @@ public class StatusBarKeyguardViewManager {
if (bouncerShowing != mLastBouncerShowing || mFirstUpdate) {
mStatusBarWindowManager.setBouncerShowing(bouncerShowing);
mPhoneStatusBar.setBouncerShowing(bouncerShowing);
+ mScrimController.setBouncerShowing(bouncerShowing);
}
KeyguardUpdateMonitor updateMonitor = KeyguardUpdateMonitor.getInstance(mContext);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java
deleted file mode 100644
index 049c5fc..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/SwipeAffordanceView.java
+++ /dev/null
@@ -1,222 +0,0 @@
-/*
- * Copyright (C) 2014 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.phone;
-
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.os.SystemClock;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.widget.Button;
-
-import com.android.systemui.R;
-import com.android.systemui.statusbar.policy.KeyButtonView;
-
-/**
- * A swipeable button for affordances on the lockscreen. This is used for the camera and phone
- * affordance.
- */
-public class SwipeAffordanceView extends KeyButtonView {
-
- private static final int SWIPE_DIRECTION_START = 0;
- private static final int SWIPE_DIRECTION_END = 1;
-
- private static final int SWIPE_DIRECTION_LEFT = 0;
- private static final int SWIPE_DIRECTION_RIGHT = 1;
-
- private AffordanceListener mListener;
- private int mScaledTouchSlop;
- private float mDragDistance;
- private int mResolvedSwipeDirection;
- private int mSwipeDirection;
-
- public SwipeAffordanceView(Context context, AttributeSet attrs) {
- this(context, attrs, 0);
- }
-
- public SwipeAffordanceView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- TypedArray a = context.getTheme().obtainStyledAttributes(
- attrs,
- R.styleable.SwipeAffordanceView,
- 0, 0);
- try {
- mSwipeDirection = a.getInt(R.styleable.SwipeAffordanceView_swipeDirection, 0);
- } finally {
- a.recycle();
- }
- }
-
- @Override
- public void onRtlPropertiesChanged(int layoutDirection) {
- super.onRtlPropertiesChanged(layoutDirection);
- if (!isLayoutRtl()) {
- mResolvedSwipeDirection = mSwipeDirection;
- } else {
- mResolvedSwipeDirection = mSwipeDirection == SWIPE_DIRECTION_START
- ? SWIPE_DIRECTION_RIGHT
- : SWIPE_DIRECTION_LEFT;
- }
- }
-
- @Override
- protected void onFinishInflate() {
- super.onFinishInflate();
- mDragDistance = getResources().getDimension(R.dimen.affordance_drag_distance);
- mScaledTouchSlop = ViewConfiguration.get(mContext).getScaledTouchSlop();
- }
-
- public void enableAccessibility(boolean touchExplorationEnabled) {
-
- // Add a touch handler or accessibility click listener for camera button.
- if (touchExplorationEnabled) {
- setOnTouchListener(null);
- setOnClickListener(mClickListener);
- } else {
- setOnTouchListener(mTouchListener);
- setOnClickListener(null);
- }
- }
-
- public void setAffordanceListener(AffordanceListener listener) {
- mListener = listener;
- }
-
- private void onActionPerformed() {
- if (mListener != null) {
- mListener.onActionPerformed(this);
- }
- }
-
- private void onUserActivity(long when) {
- if (mListener != null) {
- mListener.onUserActivity(when);
- }
- }
-
- private final OnClickListener mClickListener = new OnClickListener() {
- @Override
- public void onClick(View v) {
- onActionPerformed();
- }
- };
-
- private final OnTouchListener mTouchListener = new OnTouchListener() {
- private float mStartX;
- private boolean mTouchSlopReached;
- private boolean mSkipCancelAnimation;
-
- @Override
- public boolean onTouch(final View view, MotionEvent event) {
- float realX = event.getRawX();
- switch (event.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mStartX = realX;
- mTouchSlopReached = false;
- mSkipCancelAnimation = false;
- break;
- case MotionEvent.ACTION_MOVE:
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX > mStartX
- : realX < mStartX) {
- realX = mStartX;
- }
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX < mStartX - mDragDistance
- : realX > mStartX + mDragDistance) {
- view.setPressed(true);
- onUserActivity(event.getEventTime());
- } else {
- view.setPressed(false);
- }
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX < mStartX - mScaledTouchSlop
- : realX > mStartX + mScaledTouchSlop) {
- mTouchSlopReached = true;
- }
- view.setTranslationX(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? Math.max(realX - mStartX, -mDragDistance)
- : Math.min(realX - mStartX, mDragDistance));
- break;
- case MotionEvent.ACTION_UP:
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX < mStartX - mDragDistance
- : realX > mStartX + mDragDistance) {
- onActionPerformed();
- view.animate().x(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? -view.getWidth()
- : ((View) view.getParent()).getWidth() + view.getWidth())
- .setInterpolator(new AccelerateInterpolator(2f)).withEndAction(
- new Runnable() {
- @Override
- public void run() {
- view.setTranslationX(0);
- }
- });
- mSkipCancelAnimation = true;
- }
- if (mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? realX < mStartX - mScaledTouchSlop
- : realX > mStartX + mScaledTouchSlop) {
- mTouchSlopReached = true;
- }
- if (!mTouchSlopReached) {
- mSkipCancelAnimation = true;
- view.animate().translationX(mResolvedSwipeDirection == SWIPE_DIRECTION_LEFT
- ? -mDragDistance / 2
- : mDragDistance / 2).
- setInterpolator(new DecelerateInterpolator()).withEndAction(
- new Runnable() {
- @Override
- public void run() {
- view.animate().translationX(0).
- setInterpolator(new AccelerateInterpolator());
- }
- });
- }
- case MotionEvent.ACTION_CANCEL:
- view.setPressed(false);
- if (!mSkipCancelAnimation) {
- view.animate().translationX(0)
- .setInterpolator(new AccelerateInterpolator(2f));
- }
- break;
- }
- return true;
- }
- };
-
- public interface AffordanceListener {
-
- /**
- * Called when the view would like to report user activity.
- *
- * @param when The timestamp of the user activity in {@link SystemClock#uptimeMillis} time
- * base.
- */
- void onUserActivity(long when);
-
- /**
- * Called when the action of the affordance has been performed.
- */
- void onActionPerformed(SwipeAffordanceView view);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
new file mode 100644
index 0000000..bfd657b
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockMethodCache.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2014 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.phone;
+
+import android.content.Context;
+
+import com.android.internal.widget.LockPatternUtils;
+import com.android.keyguard.KeyguardUpdateMonitor;
+import com.android.keyguard.KeyguardUpdateMonitorCallback;
+
+import java.util.ArrayList;
+
+/**
+ * Caches whether the current unlock method is insecure, taking trust into account. This information
+ * might be a little bit out of date and should not be used for actual security decisions; it should
+ * be only used for visual indications.
+ */
+public class UnlockMethodCache {
+
+ private static UnlockMethodCache sInstance;
+
+ private final LockPatternUtils mLockPatternUtils;
+ private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
+ private final ArrayList<OnUnlockMethodChangedListener> mListeners = new ArrayList<>();
+ private boolean mMethodInsecure;
+
+ private UnlockMethodCache(Context ctx) {
+ mLockPatternUtils = new LockPatternUtils(ctx);
+ mKeyguardUpdateMonitor = KeyguardUpdateMonitor.getInstance(ctx);
+ KeyguardUpdateMonitor.getInstance(ctx).registerCallback(mCallback);
+ updateMethodSecure(true /* updateAlways */);
+ }
+
+ public static UnlockMethodCache getInstance(Context context) {
+ if (sInstance == null) {
+ sInstance = new UnlockMethodCache(context);
+ }
+ return sInstance;
+ }
+
+ /**
+ * @return whether the current security method is secure, i. e. the bouncer will be shown
+ */
+ public boolean isMethodInsecure() {
+ return mMethodInsecure;
+ }
+
+ public void addListener(OnUnlockMethodChangedListener listener) {
+ mListeners.add(listener);
+ }
+
+ public void removeListener(OnUnlockMethodChangedListener listener) {
+ mListeners.remove(listener);
+ }
+
+ private void updateMethodSecure(boolean updateAlways) {
+ int user = mLockPatternUtils.getCurrentUser();
+ boolean methodInsecure = !mLockPatternUtils.isSecure() ||
+ mKeyguardUpdateMonitor.getUserHasTrust(user);
+ boolean changed = methodInsecure != mMethodInsecure;
+ if (changed || updateAlways) {
+ mMethodInsecure = methodInsecure;
+ notifyListeners(mMethodInsecure);
+ }
+ }
+
+ private void notifyListeners(boolean secure) {
+ for (OnUnlockMethodChangedListener listener : mListeners) {
+ listener.onMethodSecureChanged(secure);
+ }
+ }
+
+ private final KeyguardUpdateMonitorCallback mCallback = new KeyguardUpdateMonitorCallback() {
+ @Override
+ public void onUserSwitchComplete(int userId) {
+ updateMethodSecure(false /* updateAlways */);
+ }
+
+ @Override
+ public void onTrustChanged(int userId) {
+ updateMethodSecure(false /* updateAlways */);
+ }
+
+ @Override
+ public void onScreenTurnedOn() {
+ updateMethodSecure(false /* updateAlways */);
+ }
+ };
+
+ public static interface OnUnlockMethodChangedListener {
+ void onMethodSecureChanged(boolean methodSecure);
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
index 81e2cb3..9271e71 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpNotificationView.java
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.policy;
import android.content.Context;
import android.content.res.Configuration;
+import android.graphics.Outline;
import android.graphics.Rect;
import android.util.AttributeSet;
import android.util.Log;
@@ -25,6 +26,7 @@ import android.view.MotionEvent;
import android.view.View;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
+import android.view.ViewTreeObserver;
import android.widget.FrameLayout;
import com.android.systemui.ExpandHelper;
@@ -35,14 +37,17 @@ import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.ExpandableView;
import com.android.systemui.statusbar.NotificationData;
-public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback {
+public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.Callback, ExpandHelper.Callback,
+ ViewTreeObserver.OnComputeInternalInsetsListener {
private static final String TAG = "HeadsUpNotificationView";
private static final boolean DEBUG = false;
private static final boolean SPEW = DEBUG;
Rect mTmpRect = new Rect();
+ int[] mTmpTwoArray = new int[2];
private final int mTouchSensitivityDelay;
+ private final float mMaxAlpha = 0.95f;
private SwipeHelper mSwipeHelper;
private EdgeSwipeHelper mEdgeSwipeHelper;
@@ -87,8 +92,9 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
}
mContentHolder.setX(0);
mContentHolder.setVisibility(View.VISIBLE);
- mContentHolder.setAlpha(1f);
+ mContentHolder.setAlpha(mMaxAlpha);
mContentHolder.addView(mHeadsUp.row);
+
mSwipeHelper.snapChild(mContentHolder, 1f);
mStartTouchTime = System.currentTimeMillis() + mTouchSensitivityDelay;
}
@@ -99,32 +105,6 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
return mHeadsUp == null || mHeadsUp.notification.isClearable();
}
- public void setMargin(int notificationPanelMarginPx) {
- if (SPEW) Log.v(TAG, "setMargin() " + notificationPanelMarginPx);
- if (mContentHolder != null &&
- mContentHolder.getLayoutParams() instanceof FrameLayout.LayoutParams) {
- FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mContentHolder.getLayoutParams();
- lp.setMarginStart(notificationPanelMarginPx);
- mContentHolder.setLayoutParams(lp);
- }
- }
-
- // LinearLayout methods
-
- @Override
- public void onDraw(android.graphics.Canvas c) {
- super.onDraw(c);
- if (DEBUG) {
- //Log.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
- // + getMeasuredHeight() + "px");
- c.save();
- c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
- android.graphics.Region.Op.DIFFERENCE);
- c.drawColor(0xFFcc00cc);
- c.restore();
- }
- }
-
// ViewGroup methods
@Override
@@ -134,6 +114,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
float pagingTouchSlop = viewConfiguration.getScaledPagingTouchSlop();
float touchSlop = viewConfiguration.getScaledTouchSlop();
mSwipeHelper = new SwipeHelper(SwipeHelper.X, this, densityScale, pagingTouchSlop);
+ mSwipeHelper.setMaxAlpha(mMaxAlpha);
mEdgeSwipeHelper = new EdgeSwipeHelper(touchSlop);
int minHeight = getResources().getDimensionPixelSize(R.dimen.notification_min_height);
@@ -146,6 +127,8 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
// whoops, we're on already!
setNotification(mHeadsUp);
}
+
+ getViewTreeObserver().addOnComputeInternalInsetsListener(this);
}
@Override
@@ -163,6 +146,20 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
// View methods
@Override
+ public void onDraw(android.graphics.Canvas c) {
+ super.onDraw(c);
+ if (DEBUG) {
+ //Log.d(TAG, "onDraw: canvas height: " + c.getHeight() + "px; measured height: "
+ // + getMeasuredHeight() + "px");
+ c.save();
+ c.clipRect(6, 6, c.getWidth() - 6, getMeasuredHeight() - 6,
+ android.graphics.Region.Op.DIFFERENCE);
+ c.drawColor(0xFFcc00cc);
+ c.restore();
+ }
+ }
+
+ @Override
public boolean onTouchEvent(MotionEvent ev) {
if (System.currentTimeMillis() < mStartTouchTime) {
return false;
@@ -183,6 +180,14 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
mSwipeHelper.setPagingTouchSlop(pagingTouchSlop);
}
+ @Override
+ protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+ super.onLayout(changed, left, top, right, bottom);
+ Outline o = new Outline();
+ o.setRect(0, 0, mContentHolder.getWidth(), mContentHolder.getHeight());
+ mContentHolder.setOutline(o);
+ }
+
// ExpandHelper.Callback methods
@Override
@@ -233,7 +238,7 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
@Override
public void onDragCancelled(View v) {
- mContentHolder.setAlpha(1f); // sometimes this isn't quite reset
+ mContentHolder.setAlpha(mMaxAlpha); // sometimes this isn't quite reset
}
@Override
@@ -250,6 +255,16 @@ public class HeadsUpNotificationView extends FrameLayout implements SwipeHelper.
return mContentHolder;
}
+ @Override
+ public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo info) {
+ mContentHolder.getLocationOnScreen(mTmpTwoArray);
+
+ info.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);
+ info.touchableRegion.set(mTmpTwoArray[0], mTmpTwoArray[1],
+ mTmpTwoArray[0] + mContentHolder.getWidth(),
+ mTmpTwoArray[1] + mContentHolder.getHeight());
+ }
+
private class EdgeSwipeHelper implements Gefingerpoken {
private static final boolean DEBUG_EDGE_SWIPE = false;
private final float mTouchSlop;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index 718acc3..330b599 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -17,12 +17,9 @@
package com.android.systemui.statusbar.policy;
import android.animation.Animator;
-import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.RectF;
import android.graphics.drawable.Drawable;
import android.hardware.input.InputManager;
import android.os.SystemClock;
@@ -34,9 +31,7 @@ import android.view.KeyCharacterMap;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SoundEffectConstants;
-import android.view.View;
import android.view.ViewConfiguration;
-import android.view.ViewDebug;
import android.view.accessibility.AccessibilityEvent;
import android.widget.ImageView;
@@ -46,25 +41,18 @@ public class KeyButtonView extends ImageView {
private static final String TAG = "StatusBar.KeyButtonView";
private static final boolean DEBUG = false;
- final float GLOW_MAX_SCALE_FACTOR = 1.8f;
public static final float DEFAULT_QUIESCENT_ALPHA = 0.70f;
- long mDownTime;
- int mCode;
- int mTouchSlop;
- Drawable mGlowBG;
- int mGlowWidth, mGlowHeight;
- float mGlowAlpha = 0f, mGlowScale = 1f;
- @ViewDebug.ExportedProperty(category = "drawing")
- float mDrawingAlpha = 1f;
- @ViewDebug.ExportedProperty(category = "drawing")
- float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA;
- boolean mSupportsLongpress = true;
- RectF mRect = new RectF();
- AnimatorSet mPressedAnim;
- Animator mAnimateToQuiescent = new ObjectAnimator();
+ private long mDownTime;
+ private int mCode;
+ private int mTouchSlop;
+ private float mDrawingAlpha = 1f;
+ private float mQuiescentAlpha = DEFAULT_QUIESCENT_ALPHA;
+ private boolean mSupportsLongpress = true;
+ private Animator mAnimateToQuiescent = new ObjectAnimator();
+ private Drawable mBackground;
- Runnable mCheckLongPress = new Runnable() {
+ private final Runnable mCheckLongPress = new Runnable() {
public void run() {
if (isPressed()) {
// Log.d("KeyButtonView", "longpressed: " + this);
@@ -93,47 +81,27 @@ public class KeyButtonView extends ImageView {
mSupportsLongpress = a.getBoolean(R.styleable.KeyButtonView_keyRepeat, true);
- mGlowBG = a.getDrawable(R.styleable.KeyButtonView_glowBackground);
- setDrawingAlpha(mQuiescentAlpha);
- if (mGlowBG != null) {
- mGlowWidth = mGlowBG.getIntrinsicWidth();
- mGlowHeight = mGlowBG.getIntrinsicHeight();
+ Drawable d = getBackground();
+ if (d != null) {
+ mBackground = d.mutate();
+ setBackground(mBackground);
}
+ setDrawingAlpha(mQuiescentAlpha);
+
a.recycle();
setClickable(true);
mTouchSlop = ViewConfiguration.get(context).getScaledTouchSlop();
}
- @Override
- protected void onDraw(Canvas canvas) {
- if (mGlowBG != null) {
- canvas.save();
- final int w = getWidth();
- final int h = getHeight();
- final float aspect = (float)mGlowWidth / mGlowHeight;
- final int drawW = (int)(h*aspect);
- final int drawH = h;
- final int margin = (drawW-w)/2;
- canvas.scale(mGlowScale, mGlowScale, w*0.5f, h*0.5f);
- mGlowBG.setBounds(-margin, 0, drawW-margin, drawH);
- mGlowBG.setAlpha((int)(mDrawingAlpha * mGlowAlpha * 255));
- mGlowBG.draw(canvas);
- canvas.restore();
- mRect.right = w;
- mRect.bottom = h;
- }
- super.onDraw(canvas);
- }
-
public void setQuiescentAlpha(float alpha, boolean animate) {
mAnimateToQuiescent.cancel();
alpha = Math.min(Math.max(alpha, 0), 1);
if (alpha == mQuiescentAlpha && alpha == mDrawingAlpha) return;
mQuiescentAlpha = alpha;
if (DEBUG) Log.d(TAG, "New quiescent alpha = " + mQuiescentAlpha);
- if (mGlowBG != null && animate) {
+ if (mBackground != null && animate) {
mAnimateToQuiescent = animateToQuiescent();
mAnimateToQuiescent.start();
} else {
@@ -154,87 +122,35 @@ public class KeyButtonView extends ImageView {
}
public void setDrawingAlpha(float x) {
- // Calling setAlpha(int), which is an ImageView-specific
- // method that's different from setAlpha(float). This sets
- // the alpha on this ImageView's drawable directly
- setAlpha((int) (x * 255));
- mDrawingAlpha = x;
- }
-
- public float getGlowAlpha() {
- if (mGlowBG == null) return 0;
- return mGlowAlpha;
- }
-
- public void setGlowAlpha(float x) {
- if (mGlowBG == null) return;
- mGlowAlpha = x;
- invalidate();
- }
-
- public float getGlowScale() {
- if (mGlowBG == null) return 0;
- return mGlowScale;
- }
-
- public void setGlowScale(float x) {
- if (mGlowBG == null) return;
- mGlowScale = x;
- final float w = getWidth();
- final float h = getHeight();
- if (GLOW_MAX_SCALE_FACTOR <= 1.0f) {
- // this only works if we know the glow will never leave our bounds
- invalidate();
- } else {
- final float rx = (w * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
- final float ry = (h * (GLOW_MAX_SCALE_FACTOR - 1.0f)) / 2.0f + 1.0f;
- com.android.systemui.SwipeHelper.invalidateGlobalRegion(
- this,
- new RectF(getLeft() - rx,
- getTop() - ry,
- getRight() + rx,
- getBottom() + ry));
-
- // also invalidate our immediate parent to help avoid situations where nearby glows
- // interfere
- ((View)getParent()).invalidate();
+ setImageAlpha((int) (x * 255));
+ if (mBackground != null) {
+ mBackground.setAlpha((int)(x * 255));
}
+ mDrawingAlpha = x;
}
public void setPressed(boolean pressed) {
- if (mGlowBG != null) {
+ if (mBackground != null) {
if (pressed != isPressed()) {
- if (mPressedAnim != null && mPressedAnim.isRunning()) {
- mPressedAnim.cancel();
- }
- final AnimatorSet as = mPressedAnim = new AnimatorSet();
if (pressed) {
- if (mGlowScale < GLOW_MAX_SCALE_FACTOR)
- mGlowScale = GLOW_MAX_SCALE_FACTOR;
- if (mGlowAlpha < mQuiescentAlpha)
- mGlowAlpha = mQuiescentAlpha;
setDrawingAlpha(1f);
- as.playTogether(
- ObjectAnimator.ofFloat(this, "glowAlpha", 1f),
- ObjectAnimator.ofFloat(this, "glowScale", GLOW_MAX_SCALE_FACTOR)
- );
- as.setDuration(50);
} else {
mAnimateToQuiescent.cancel();
mAnimateToQuiescent = animateToQuiescent();
- as.playTogether(
- ObjectAnimator.ofFloat(this, "glowAlpha", 0f),
- ObjectAnimator.ofFloat(this, "glowScale", 1f),
- mAnimateToQuiescent
- );
- as.setDuration(500);
+ mAnimateToQuiescent.setDuration(500);
+ mAnimateToQuiescent.start();
}
- as.start();
}
}
super.setPressed(pressed);
}
+ private void setHotspot(float x, float y) {
+ if (mBackground != null) {
+ mBackground.setHotspot(x, y);
+ }
+ }
+
public boolean onTouchEvent(MotionEvent ev) {
final int action = ev.getAction();
int x, y;
@@ -254,6 +170,7 @@ public class KeyButtonView extends ImageView {
removeCallbacks(mCheckLongPress);
postDelayed(mCheckLongPress, ViewConfiguration.getLongPressTimeout());
}
+ setHotspot(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_MOVE:
x = (int)ev.getX();
@@ -262,6 +179,7 @@ public class KeyButtonView extends ImageView {
&& x < getWidth() + mTouchSlop
&& y >= -mTouchSlop
&& y < getHeight() + mTouchSlop);
+ setHotspot(ev.getX(), ev.getY());
break;
case MotionEvent.ACTION_CANCEL:
setPressed(false);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
index 966c0b0..56402a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkControllerImpl.java
@@ -339,7 +339,7 @@ public class NetworkControllerImpl extends BroadcastReceiver
boolean wifiOut = wifiEnabled && mWifiSsid != null
&& (mWifiActivity == WifiManager.DATA_ACTIVITY_INOUT
|| mWifiActivity == WifiManager.DATA_ACTIVITY_OUT);
- cb.onWifiSignalChanged(wifiEnabled, mQSWifiIconId, wifiIn, wifiOut,
+ cb.onWifiSignalChanged(mWifiEnabled, mQSWifiIconId, wifiIn, wifiOut,
mContentDescriptionWifi, wifiDesc);
boolean mobileIn = mDataConnected && (mDataActivity == TelephonyManager.DATA_ACTIVITY_INOUT
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
index 173af40..3ce6905 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/UserInfoController.java
@@ -166,7 +166,7 @@ public final class UserInfoController {
if (rawAvatar != null) {
avatar = new BitmapDrawable(mContext.getResources(), circularClip(rawAvatar));
} else {
- avatar = mContext.getResources().getDrawable(R.drawable.ic_qs_default_user);
+ avatar = mContext.getResources().getDrawable(R.drawable.ic_account_circle);
mUseDefaultAvatar = true;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
index 5e2d06b..cf56fa57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/AnimationFilter.java
@@ -27,6 +27,7 @@ public class AnimationFilter {
boolean animateZ;
boolean animateScale;
boolean animateHeight;
+ boolean animateTopInset;
boolean animateDimmed;
boolean hasDelays;
@@ -60,6 +61,11 @@ public class AnimationFilter {
return this;
}
+ public AnimationFilter animateTopInset() {
+ animateTopInset = true;
+ return this;
+ }
+
public AnimationFilter animateDimmed() {
animateDimmed = true;
return this;
@@ -84,6 +90,7 @@ public class AnimationFilter {
animateZ |= filter.animateZ;
animateScale |= filter.animateScale;
animateHeight |= filter.animateHeight;
+ animateTopInset |= filter.animateTopInset;
animateDimmed |= filter.animateDimmed;
hasDelays |= filter.hasDelays;
}
@@ -94,6 +101,7 @@ public class AnimationFilter {
animateZ = false;
animateScale = false;
animateHeight = false;
+ animateTopInset = false;
animateDimmed = false;
hasDelays = false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
index 079b184..58176b9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/NotificationStackScrollLayout.java
@@ -1599,6 +1599,7 @@ public class NotificationStackScrollLayout extends ViewGroup
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateZ()
.hasDelays(),
@@ -1607,6 +1608,7 @@ public class NotificationStackScrollLayout extends ViewGroup
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateZ()
.hasDelays(),
@@ -1615,6 +1617,7 @@ public class NotificationStackScrollLayout extends ViewGroup
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateZ()
.hasDelays(),
@@ -1623,6 +1626,7 @@ public class NotificationStackScrollLayout extends ViewGroup
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateDimmed()
.animateScale()
@@ -1651,6 +1655,7 @@ public class NotificationStackScrollLayout extends ViewGroup
new AnimationFilter()
.animateAlpha()
.animateHeight()
+ .animateTopInset()
.animateY()
.animateZ()
};
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
index bd2541a..2b52c7e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollAlgorithm.java
@@ -49,6 +49,7 @@ public class StackScrollAlgorithm {
private int mBottomStackPeekSize;
private int mZDistanceBetweenElements;
private int mZBasicHeight;
+ private int mRoundedRectCornerRadius;
private StackIndentationFunctor mTopStackIndentationFunctor;
private StackIndentationFunctor mBottomStackIndentationFunctor;
@@ -111,6 +112,8 @@ public class StackScrollAlgorithm {
mZBasicHeight = (MAX_ITEMS_IN_BOTTOM_STACK + 1) * mZDistanceBetweenElements;
mBottomStackSlowDownLength = context.getResources()
.getDimensionPixelSize(R.dimen.bottom_stack_slow_down_length);
+ mRoundedRectCornerRadius = context.getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.notification_quantum_rounded_rect_radius);
}
@@ -146,6 +149,67 @@ public class StackScrollAlgorithm {
handleDraggedViews(ambientState, resultState, algorithmState);
updateDimmedActivated(ambientState, resultState, algorithmState);
+ updateClipping(resultState, algorithmState);
+ }
+
+ private void updateClipping(StackScrollState resultState,
+ StackScrollAlgorithmState algorithmState) {
+ float previousNotificationEnd = 0;
+ float previousNotificationStart = 0;
+ boolean previousNotificationIsSwiped = false;
+ int childCount = algorithmState.visibleChildren.size();
+ for (int i = 0; i < childCount; i++) {
+ ExpandableView child = algorithmState.visibleChildren.get(i);
+ StackScrollState.ViewState state = resultState.getViewStateForView(child);
+ float newYTranslation = state.yTranslation;
+ int newHeight = state.height;
+ // apply clipping and shadow
+ float newNotificationEnd = newYTranslation + newHeight;
+
+ // In the unlocked shade we have to clip a little bit higher because of the rounded
+ // corners of the notifications.
+ float clippingCorrection = state.dimmed ? 0 : mRoundedRectCornerRadius;
+
+ // When the previous notification is swiped, we don't clip the content to the
+ // bottom of it.
+ float clipHeight = previousNotificationIsSwiped
+ ? newHeight
+ : newNotificationEnd - (previousNotificationEnd - clippingCorrection);
+
+ updateChildClippingAndBackground(state, newHeight, clipHeight,
+ (int) (newHeight - (previousNotificationStart - newYTranslation)));
+
+ if (!child.isTransparent()) {
+ // Only update the previous values if we are not transparent,
+ // otherwise we would clip to a transparent view.
+ previousNotificationStart = newYTranslation + child.getClipTopAmount();
+ previousNotificationEnd = newNotificationEnd;
+ previousNotificationIsSwiped = child.getTranslationX() != 0;
+ }
+ }
+ }
+
+ /**
+ * Updates the shadow outline and the clipping for a view.
+ *
+ * @param state the viewState to update
+ * @param realHeight the currently applied height of the view
+ * @param clipHeight the desired clip height, the rest of the view will be clipped from the top
+ * @param backgroundHeight the desired background height. The shadows of the view will be
+ * based on this height and the content will be clipped from the top
+ */
+ private void updateChildClippingAndBackground(StackScrollState.ViewState state, int realHeight,
+ float clipHeight, int backgroundHeight) {
+ if (realHeight > clipHeight) {
+ state.topOverLap = (int) (realHeight - clipHeight);
+ } else {
+ state.topOverLap = 0;
+ }
+ if (realHeight > backgroundHeight) {
+ state.clipTopAmount = (realHeight - backgroundHeight);
+ } else {
+ state.clipTopAmount = 0;
+ }
}
/**
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
index ae2acab..94cb16d 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackScrollState.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar.stack;
-import android.graphics.Outline;
import android.graphics.Rect;
import android.util.Log;
import android.view.View;
@@ -80,9 +79,6 @@ public class StackScrollState {
*/
public void apply() {
int numChildren = mHostView.getChildCount();
- float previousNotificationEnd = 0;
- float previousNotificationStart = 0;
- boolean previousNotificationIsSwiped = false;
for (int i = 0; i < numChildren; i++) {
ExpandableView child = (ExpandableView) mHostView.getChildAt(i);
ViewState state = mStateMap.get(child);
@@ -152,35 +148,41 @@ public class StackScrollState {
// apply dimming
child.setDimmed(state.dimmed, false /* animate */);
- // apply clipping and shadow
- float newNotificationEnd = newYTranslation + newHeight;
-
- // When the previous notification is swiped, we don't clip the content to the
- // bottom of it.
- float clipHeight = previousNotificationIsSwiped
- ? newHeight
- : newNotificationEnd - (previousNotificationEnd);
-
- updateChildClippingAndBackground(child, newHeight,
- clipHeight,
- (int) (newHeight - (previousNotificationStart - newYTranslation)));
-
- if (!child.isTransparent()) {
- // Only update the previous values if we are not transparent,
- // otherwise we would clip to a transparent view.
- previousNotificationStart = newYTranslation + child.getClipTopAmount();
- previousNotificationEnd = newNotificationEnd;
- previousNotificationIsSwiped = child.getTranslationX() != 0;
+ float oldClipTopAmount = child.getClipTopAmount();
+ if (oldClipTopAmount != state.clipTopAmount) {
+ child.setClipTopAmount(state.clipTopAmount);
+ }
+
+ if (state.topOverLap != 0) {
+ updateChildClip(child, newHeight, state.topOverLap);
+ } else {
+ child.setClipBounds(null);
}
if(child instanceof SpeedBumpView) {
- performSpeedBumpAnimation(i, (SpeedBumpView) child, newNotificationEnd,
+ float speedBumpEnd = newYTranslation + newHeight;
+ performSpeedBumpAnimation(i, (SpeedBumpView) child, speedBumpEnd,
newYTranslation);
}
}
}
}
+ /**
+ * Updates the clipping of a view
+ *
+ * @param child the view to update
+ * @param height the currently applied height of the view
+ * @param clipInset how much should this view be clipped from the top
+ */
+ private void updateChildClip(View child, int height, int clipInset) {
+ mClipRect.set(0,
+ clipInset,
+ child.getWidth(),
+ height);
+ child.setClipBounds(mClipRect);
+ }
+
private void performSpeedBumpAnimation(int i, SpeedBumpView speedBump, float speedBumpEnd,
float speedBumpStart) {
View nextChild = getNextChildNotGone(i);
@@ -209,45 +211,6 @@ public class StackScrollState {
return null;
}
- /**
- * Updates the shadow outline and the clipping for a view.
- *
- * @param child the view to update
- * @param realHeight the currently applied height of the view
- * @param clipHeight the desired clip height, the rest of the view will be clipped from the top
- * @param backgroundHeight the desired background height. The shadows of the view will be
- * based on this height and the content will be clipped from the top
- */
- private void updateChildClippingAndBackground(ExpandableView child, int realHeight,
- float clipHeight, int backgroundHeight) {
- if (realHeight > clipHeight) {
- updateChildClip(child, realHeight, clipHeight);
- } else {
- child.setClipBounds(null);
- }
- if (realHeight > backgroundHeight) {
- child.setClipTopAmount(realHeight - backgroundHeight);
- } else {
- child.setClipTopAmount(0);
- }
- }
-
- /**
- * Updates the clipping of a view
- *
- * @param child the view to update
- * @param height the currently applied height of the view
- * @param clipHeight the desired clip height, the rest of the view will be clipped from the top
- */
- private void updateChildClip(View child, int height, float clipHeight) {
- int clipInset = (int) (height - clipHeight);
- mClipRect.set(0,
- clipInset,
- child.getWidth(),
- height);
- child.setClipBounds(mClipRect);
- }
-
public static class ViewState {
// These are flags such that we can create masks for filtering.
@@ -269,6 +232,18 @@ public class StackScrollState {
boolean dimmed;
/**
+ * The amount which the view should be clipped from the top. This is calculated to
+ * perceive consistent shadows.
+ */
+ int clipTopAmount;
+
+ /**
+ * How much does the child overlap with the previous view on the top? Can be used for
+ * a clipping optimization
+ */
+ int topOverLap;
+
+ /**
* The index of the view, only accounting for views not equal to GONE
*/
int notGoneIndex;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
index f019e6c..f41ab3a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/stack/StackStateAnimator.java
@@ -133,10 +133,11 @@ public class StackStateAnimator {
boolean scaleChanging = child.getScaleX() != viewState.scale;
boolean alphaChanging = alpha != child.getAlpha();
boolean heightChanging = viewState.height != child.getActualHeight();
+ boolean topInsetChanging = viewState.clipTopAmount != child.getClipTopAmount();
boolean wasAdded = mNewAddChildren.contains(child);
boolean hasDelays = mAnimationFilter.hasDelays;
boolean isDelayRelevant = yTranslationChanging || zTranslationChanging || scaleChanging ||
- alphaChanging || heightChanging;
+ alphaChanging || heightChanging || topInsetChanging;
long delay = 0;
if (hasDelays && isDelayRelevant || wasAdded) {
delay = calculateChildAnimationDelay(viewState, finalState);
@@ -167,6 +168,11 @@ public class StackStateAnimator {
startHeightAnimation(child, viewState, delay);
}
+ // start top inset animation
+ if (topInsetChanging) {
+ startInsetAnimation(child, viewState, delay);
+ }
+
// start dimmed animation
child.setDimmed(viewState.dimmed, mAnimationFilter.animateDimmed);
@@ -280,6 +286,64 @@ public class StackStateAnimator {
child.setTag(TAG_END_HEIGHT, newEndValue);
}
+ private void startInsetAnimation(final ExpandableView child,
+ StackScrollState.ViewState viewState, long delay) {
+ Integer previousStartValue = getChildTag(child, TAG_START_TOP_INSET);
+ Integer previousEndValue = getChildTag(child, TAG_END_TOP_INSET);
+ int newEndValue = viewState.clipTopAmount;
+ if (previousEndValue != null && previousEndValue == newEndValue) {
+ return;
+ }
+ ValueAnimator previousAnimator = getChildTag(child, TAG_ANIMATOR_TOP_INSET);
+ if (!mAnimationFilter.animateTopInset) {
+ // just a local update was performed
+ if (previousAnimator != null) {
+ // we need to increase all animation keyframes of the previous animator by the
+ // relative change to the end value
+ PropertyValuesHolder[] values = previousAnimator.getValues();
+ int relativeDiff = newEndValue - previousEndValue;
+ int newStartValue = previousStartValue + relativeDiff;
+ values[0].setIntValues(newStartValue, newEndValue);
+ child.setTag(TAG_START_TOP_INSET, newStartValue);
+ child.setTag(TAG_END_TOP_INSET, newEndValue);
+ previousAnimator.setCurrentPlayTime(previousAnimator.getCurrentPlayTime());
+ return;
+ } else {
+ // no new animation needed, let's just apply the value
+ child.setClipTopAmount(newEndValue);
+ return;
+ }
+ }
+
+ ValueAnimator animator = ValueAnimator.ofInt(child.getClipTopAmount(), newEndValue);
+ animator.addUpdateListener(new ValueAnimator.AnimatorUpdateListener() {
+ @Override
+ public void onAnimationUpdate(ValueAnimator animation) {
+ child.setClipTopAmount((int) animation.getAnimatedValue());
+ }
+ });
+ animator.setInterpolator(mFastOutSlowInInterpolator);
+ long newDuration = cancelAnimatorAndGetNewDuration(previousAnimator);
+ animator.setDuration(newDuration);
+ if (delay > 0 && (previousAnimator == null || !previousAnimator.isRunning())) {
+ animator.setStartDelay(delay);
+ }
+ animator.addListener(getGlobalAnimationFinishedListener());
+ // remove the tag when the animation is finished
+ animator.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ child.setTag(TAG_ANIMATOR_TOP_INSET, null);
+ child.setTag(TAG_START_TOP_INSET, null);
+ child.setTag(TAG_END_TOP_INSET, null);
+ }
+ });
+ startAnimator(animator);
+ child.setTag(TAG_ANIMATOR_TOP_INSET, animator);
+ child.setTag(TAG_START_TOP_INSET, child.getClipTopAmount());
+ child.setTag(TAG_END_TOP_INSET, newEndValue);
+ }
+
private void startAlphaAnimation(final ExpandableView child,
final StackScrollState.ViewState viewState, long delay) {
Float previousStartValue = getChildTag(child,TAG_START_ALPHA);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
index 25147b4..c2bd1cb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java
@@ -17,12 +17,12 @@
package com.android.systemui.statusbar.tv;
import android.os.IBinder;
+import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.StatusBarNotification;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
-import com.android.internal.policy.IKeyguardShowCallback;
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.statusbar.BaseStatusBar;
@@ -50,7 +50,7 @@ public class TvStatusBar extends BaseStatusBar {
}
@Override
- public void addNotificationInternal(StatusBarNotification notification) {
+ public void addNotificationInternal(StatusBarNotification notification, Ranking ranking) {
}
@Override
@@ -58,7 +58,7 @@ public class TvStatusBar extends BaseStatusBar {
}
@Override
- protected void removeNotificationInternal(String key) {
+ protected void removeNotificationInternal(String key, Ranking ranking) {
}
@Override
@@ -117,7 +117,7 @@ public class TvStatusBar extends BaseStatusBar {
}
@Override
- protected void updateNotificationIcons() {
+ protected void updateNotifications() {
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
new file mode 100644
index 0000000..5ee8925
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeComponent.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2014 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.volume;
+
+import com.android.systemui.statusbar.policy.ZenModeController;
+
+public interface VolumeComponent {
+ ZenModeController getZenController();
+ void setVolumePanel(VolumePanel panel);
+}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
index 8657e07..67f3a3d 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumePanel.java
@@ -16,14 +16,12 @@
package com.android.systemui.volume;
-import com.android.internal.R;
-
import android.app.AlertDialog;
import android.app.Dialog;
-import android.content.DialogInterface.OnDismissListener;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
+import android.content.DialogInterface.OnDismissListener;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Resources;
@@ -42,6 +40,7 @@ import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
import android.view.Window;
import android.view.WindowManager;
import android.view.WindowManager.LayoutParams;
@@ -49,6 +48,9 @@ import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
+import com.android.internal.R;
+import com.android.systemui.statusbar.policy.ZenModeController;
+
import java.util.HashMap;
/**
@@ -57,7 +59,6 @@ import java.util.HashMap;
* @hide
*/
public class VolumePanel extends Handler {
- private static final String TAG = VolumePanel.class.getSimpleName();
private static boolean LOGD = false;
private static final int PLAY_SOUND_DELAY = AudioService.PLAY_SOUND_DELAY;
@@ -88,33 +89,48 @@ public class VolumePanel extends Handler {
private static final int MSG_REMOTE_VOLUME_UPDATE_IF_SHOWN = 9;
private static final int MSG_SLIDER_VISIBILITY_CHANGED = 10;
private static final int MSG_DISPLAY_SAFE_VOLUME_WARNING = 11;
+ private static final int MSG_LAYOUT_DIRECTION = 12;
+ private static final int MSG_ZEN_MODE_CHANGED = 13;
// Pseudo stream type for master volume
private static final int STREAM_MASTER = -100;
// Pseudo stream type for remote volume is defined in AudioService.STREAM_REMOTE_MUSIC
+ private final String mTag;
protected final Context mContext;
private final AudioManager mAudioManager;
+ private final ZenModeController mZenController;
private boolean mRingIsSilent;
- private boolean mShowCombinedVolumes;
private boolean mVoiceCapable;
+ private boolean mZenModeCapable;
// True if we want to play tones on the system stream when the master stream is specified.
private final boolean mPlayMasterStreamTones;
- /** Dialog containing all the sliders */
- private final Dialog mDialog;
- /** Dialog's content view */
+
+ /** Volume panel content view */
private final View mView;
+ /** Dialog hosting the panel, if not embedded */
+ private final Dialog mDialog;
+ /** Parent view hosting the panel, if embedded */
+ private final ViewGroup mParent;
/** The visible portion of the volume overlay */
private final ViewGroup mPanel;
- /** Contains the sliders and their touchable icons */
- private final ViewGroup mSliderGroup;
- /** The button that expands the dialog to show all sliders */
- private final View mMoreButton;
- /** Dummy divider icon that needs to vanish with the more button */
- private final View mDivider;
+ /** Contains the slider and its touchable icons */
+ private final ViewGroup mSliderPanel;
+ /** The button that expands the dialog to show the zen panel */
+ private final ImageView mExpandButton;
+ /** Dummy divider icon that needs to vanish with the expand button */
+ private final View mExpandDivider;
+ /** The zen mode configuration panel view stub */
+ private final ViewStub mZenPanelStub;
+ /** The zen mode configuration panel view, once inflated */
+ private ZenModePanel mZenPanel;
+ /** Dummy divider icon that needs to vanish with the zen panel */
+ private final View mZenPanelDivider;
+
+ private ZenModePanel.Callback mZenPanelCallback;
/** Currently active stream that shows up at the top of the list of sliders */
private int mActiveStreamType = -1;
@@ -129,8 +145,8 @@ public class VolumePanel extends Handler {
false),
RingerStream(AudioManager.STREAM_RING,
R.string.volume_icon_description_ringer,
- R.drawable.ic_audio_ring_notif,
- R.drawable.ic_audio_ring_notif_mute,
+ com.android.systemui.R.drawable.ic_ringer_audible,
+ com.android.systemui.R.drawable.ic_ringer_silent,
false),
VoiceStream(AudioManager.STREAM_VOICE_CALL,
R.string.volume_icon_description_incall,
@@ -149,8 +165,8 @@ public class VolumePanel extends Handler {
true),
NotificationStream(AudioManager.STREAM_NOTIFICATION,
R.string.volume_icon_description_notification,
- R.drawable.ic_audio_notification,
- R.drawable.ic_audio_notification_mute,
+ com.android.systemui.R.drawable.ic_ringer_audible,
+ com.android.systemui.R.drawable.ic_ringer_silent,
true),
// for now, use media resources for master volume
MasterStream(STREAM_MASTER,
@@ -245,8 +261,11 @@ public class VolumePanel extends Handler {
}
- public VolumePanel(Context context) {
+ public VolumePanel(Context context, ViewGroup parent, ZenModeController zenController) {
+ mTag = String.format("VolumePanel%s.%08x", parent == null ? "Dialog" : "", hashCode());
mContext = context;
+ mParent = parent;
+ mZenController = zenController;
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
// For now, only show master volume if master volume is supported
@@ -258,74 +277,81 @@ public class VolumePanel extends Handler {
streamRes.show = (streamRes.streamType == STREAM_MASTER);
}
}
-
- mDialog = new Dialog(context) {
- @Override
- public boolean onTouchEvent(MotionEvent event) {
- if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE &&
- sConfirmSafeVolumeDialog == null) {
- forceTimeout();
- return true;
+ if (LOGD) Log.d(mTag, String.format("new VolumePanel hasParent=%s", parent != null));
+ final int layoutId = com.android.systemui.R.layout.volume_panel;
+ if (parent == null) {
+ // dialog mode
+ mDialog = new Dialog(context) {
+ @Override
+ public boolean onTouchEvent(MotionEvent event) {
+ if (isShowing() && event.getAction() == MotionEvent.ACTION_OUTSIDE &&
+ sConfirmSafeVolumeDialog == null) {
+ forceTimeout();
+ return true;
+ }
+ return false;
}
- return false;
- }
- };
-
- // Change some window properties
- final Window window = mDialog.getWindow();
- final LayoutParams lp = window.getAttributes();
- lp.token = null;
- // Offset from the top
- lp.y = res.getDimensionPixelOffset(R.dimen.volume_panel_top);
- lp.type = LayoutParams.TYPE_VOLUME_OVERLAY;
- lp.windowAnimations = R.style.Animation_VolumePanel;
- window.setAttributes(lp);
- window.setGravity(Gravity.TOP);
- window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
- window.requestFeature(Window.FEATURE_NO_TITLE);
- window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE
- | LayoutParams.FLAG_NOT_TOUCH_MODAL
- | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
-
- mDialog.setCanceledOnTouchOutside(true);
- mDialog.setContentView(R.layout.volume_adjust);
- mDialog.setOnDismissListener(new OnDismissListener() {
- @Override
- public void onDismiss(DialogInterface dialog) {
- mActiveStreamType = -1;
- mAudioManager.forceVolumeControlStream(mActiveStreamType);
- }
- });
+ };
+
+ // Change some window properties
+ final Window window = mDialog.getWindow();
+ final LayoutParams lp = window.getAttributes();
+ lp.token = null;
+ // Offset from the top
+ lp.y = res.getDimensionPixelOffset(com.android.systemui.R.dimen.volume_panel_top);
+ lp.width = res.getDimensionPixelSize(com.android.systemui.R.dimen.volume_panel_width);
+ lp.type = LayoutParams.TYPE_VOLUME_OVERLAY;
+ lp.windowAnimations = R.style.Animation_VolumePanel;
+ window.setBackgroundDrawableResource(com.android.systemui.R.drawable.qs_panel_background);
+ window.setAttributes(lp);
+ window.setGravity(Gravity.TOP);
+ window.clearFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
+ window.requestFeature(Window.FEATURE_NO_TITLE);
+ window.addFlags(LayoutParams.FLAG_NOT_FOCUSABLE
+ | LayoutParams.FLAG_NOT_TOUCH_MODAL
+ | LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH);
+ mDialog.setCanceledOnTouchOutside(true);
+ mDialog.setContentView(layoutId);
+ mDialog.setOnDismissListener(new OnDismissListener() {
+ @Override
+ public void onDismiss(DialogInterface dialog) {
+ mActiveStreamType = -1;
+ mAudioManager.forceVolumeControlStream(mActiveStreamType);
+ }
+ });
- mDialog.create();
+ mDialog.create();
- mView = window.findViewById(R.id.content);
- mView.setOnTouchListener(new View.OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- resetTimeout();
- return false;
- }
- });
+ mView = window.findViewById(R.id.content);
+ mView.setOnTouchListener(new View.OnTouchListener() {
+ @Override
+ public boolean onTouch(View v, MotionEvent event) {
+ resetTimeout();
+ return false;
+ }
+ });
- mPanel = (ViewGroup) mView.findViewById(R.id.visible_panel);
- mSliderGroup = (ViewGroup) mView.findViewById(R.id.slider_group);
- mMoreButton = mView.findViewById(R.id.expand_button);
- mDivider = mView.findViewById(R.id.expand_button_divider);
+ } else {
+ // embedded mode
+ mDialog = null;
+ mView = LayoutInflater.from(mContext).inflate(layoutId, parent, true);
+ }
+ mPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.visible_panel);
+ mSliderPanel = (ViewGroup) mView.findViewById(com.android.systemui.R.id.slider_panel);
+ mExpandButton = (ImageView) mView.findViewById(com.android.systemui.R.id.expand_button);
+ mExpandDivider = mView.findViewById(com.android.systemui.R.id.expand_button_divider);
+ mZenPanelStub = (ViewStub)mView.findViewById(com.android.systemui.R.id.zen_panel_stub);
+ mZenPanelDivider = mView.findViewById(com.android.systemui.R.id.zen_panel_divider);
mToneGenerators = new ToneGenerator[AudioSystem.getNumStreamTypes()];
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mVoiceCapable = context.getResources().getBoolean(R.bool.config_voice_capable);
- // If we don't want to show multiple volumes, hide the settings button
- // and divider.
- mShowCombinedVolumes = !mVoiceCapable && !useMasterVolume;
- if (!mShowCombinedVolumes) {
- mMoreButton.setVisibility(View.GONE);
- mDivider.setVisibility(View.GONE);
- } else {
- mMoreButton.setOnClickListener(mClickListener);
- }
+ mZenModeCapable = !useMasterVolume && mZenController != null;
+ mZenPanelDivider.setVisibility(View.GONE);
+ mExpandButton.setOnClickListener(mClickListener);
+ updateZenMode(mZenController == null ? false : mZenController.isZen());
+ mZenController.addCallback(mZenCallback);
final boolean masterVolumeOnly = res.getBoolean(R.bool.config_useMasterVolume);
final boolean masterVolumeKeySounds = res.getBoolean(R.bool.config_useVolumeKeySounds);
@@ -334,7 +360,7 @@ public class VolumePanel extends Handler {
listenToRingerMode();
}
- public void setLayoutDirection(int layoutDirection) {
+ private void setLayoutDirection(int layoutDirection) {
mPanel.setLayoutDirection(layoutDirection);
updateStates();
}
@@ -406,21 +432,19 @@ public class VolumePanel extends Handler {
StreamResources streamRes = STREAMS[i];
final int streamType = streamRes.streamType;
- if (mVoiceCapable && streamRes == StreamResources.NotificationStream) {
- streamRes = StreamResources.RingerStream;
- }
final StreamControl sc = new StreamControl();
sc.streamType = streamType;
- sc.group = (ViewGroup) inflater.inflate(R.layout.volume_adjust_item, null);
+ sc.group = (ViewGroup) inflater.inflate(
+ com.android.systemui.R.layout.volume_panel_item, null);
sc.group.setTag(sc);
- sc.icon = (ImageView) sc.group.findViewById(R.id.stream_icon);
+ sc.icon = (ImageView) sc.group.findViewById(com.android.systemui.R.id.stream_icon);
sc.icon.setTag(sc);
sc.icon.setContentDescription(res.getString(streamRes.descRes));
sc.iconRes = streamRes.iconRes;
sc.iconMuteRes = streamRes.iconMuteRes;
sc.icon.setImageResource(sc.iconRes);
- sc.seekbarView = (SeekBar) sc.group.findViewById(R.id.seekbar);
+ sc.seekbarView = (SeekBar) sc.group.findViewById(com.android.systemui.R.id.seekbar);
final int plusOne = (streamType == AudioSystem.STREAM_BLUETOOTH_SCO ||
streamType == AudioSystem.STREAM_VOICE_CALL) ? 1 : 0;
sc.seekbarView.setMax(getStreamMaxVolume(streamType) + plusOne);
@@ -431,34 +455,18 @@ public class VolumePanel extends Handler {
}
private void reorderSliders(int activeStreamType) {
- mSliderGroup.removeAllViews();
+ mSliderPanel.removeAllViews();
final StreamControl active = mStreamControls.get(activeStreamType);
if (active == null) {
Log.e("VolumePanel", "Missing stream type! - " + activeStreamType);
mActiveStreamType = -1;
} else {
- mSliderGroup.addView(active.group);
+ mSliderPanel.addView(active.group);
mActiveStreamType = activeStreamType;
active.group.setVisibility(View.VISIBLE);
updateSlider(active);
- }
-
- addOtherVolumes();
- }
-
- private void addOtherVolumes() {
- if (!mShowCombinedVolumes) return;
-
- for (int i = 0; i < STREAMS.length; i++) {
- // Skip the phone specific ones and the active one
- final int streamType = STREAMS[i].streamType;
- if (!STREAMS[i].show || streamType == mActiveStreamType) {
- continue;
- }
- StreamControl sc = mStreamControls.get(streamType);
- mSliderGroup.addView(sc.group);
- updateSlider(sc);
+ updateZenMode(mZenController == null ? false : mZenController.isZen());
}
}
@@ -472,7 +480,7 @@ public class VolumePanel extends Handler {
if (((sc.streamType == AudioManager.STREAM_RING) ||
(sc.streamType == AudioManager.STREAM_NOTIFICATION)) &&
mAudioManager.getRingerMode() == AudioManager.RINGER_MODE_VIBRATE) {
- sc.icon.setImageResource(R.drawable.ic_audio_ring_notif_vibrate);
+ sc.icon.setImageResource(com.android.systemui.R.drawable.ic_ringer_vibrate);
}
if (sc.streamType == AudioService.STREAM_REMOTE_MUSIC) {
// never disable touch interactions for remote playback, the muting is not tied to
@@ -486,32 +494,70 @@ public class VolumePanel extends Handler {
}
}
+ public void setZenModePanelCallback(ZenModePanel.Callback callback) {
+ mZenPanelCallback = callback;
+ }
+
private void expand() {
- final int count = mSliderGroup.getChildCount();
- for (int i = 0; i < count; i++) {
- mSliderGroup.getChildAt(i).setVisibility(View.VISIBLE);
+ if (LOGD) Log.d(mTag, "expand mZenPanel=" + mZenPanel);
+ if (mZenPanel == null) {
+ mZenPanel = (ZenModePanel) mZenPanelStub.inflate();
+ mZenPanel.init(mZenController);
+ mZenPanel.setCallback(new ZenModePanel.Callback() {
+ @Override
+ public void onMoreSettings() {
+ if (mZenPanelCallback != null) {
+ mZenPanelCallback.onMoreSettings();
+ }
+ }
+
+ @Override
+ public void onInteraction() {
+ if (mZenPanelCallback != null) {
+ mZenPanelCallback.onInteraction();
+ }
+ }
+ });
}
- mMoreButton.setVisibility(View.INVISIBLE);
- mDivider.setVisibility(View.INVISIBLE);
+ mZenPanel.setVisibility(View.VISIBLE);
+ mZenPanelDivider.setVisibility(View.VISIBLE);
}
private void collapse() {
- mMoreButton.setVisibility(View.VISIBLE);
- mDivider.setVisibility(View.VISIBLE);
- final int count = mSliderGroup.getChildCount();
- for (int i = 1; i < count; i++) {
- mSliderGroup.getChildAt(i).setVisibility(View.GONE);
+ if (LOGD) Log.d(mTag, "collapse mZenPanel=" + mZenPanel);
+ if (mZenPanel != null) {
+ mZenPanel.setVisibility(View.GONE);
}
+ mZenPanelDivider.setVisibility(View.GONE);
}
public void updateStates() {
- final int count = mSliderGroup.getChildCount();
+ final int count = mSliderPanel.getChildCount();
for (int i = 0; i < count; i++) {
- StreamControl sc = (StreamControl) mSliderGroup.getChildAt(i).getTag();
+ StreamControl sc = (StreamControl) mSliderPanel.getChildAt(i).getTag();
updateSlider(sc);
}
}
+ private void updateZenMode(boolean zen) {
+ if (mZenModeCapable) {
+ final boolean show = mActiveStreamType == AudioManager.STREAM_NOTIFICATION
+ || mActiveStreamType == AudioManager.STREAM_RING;
+ mExpandButton.setVisibility(show ? View.VISIBLE : View.GONE);
+ mExpandDivider.setVisibility(show ? View.VISIBLE : View.GONE);
+ mExpandButton.setImageResource(zen ? com.android.systemui.R.drawable.ic_vol_zen_on
+ : com.android.systemui.R.drawable.ic_vol_zen_off);
+ } else {
+ mExpandButton.setVisibility(View.GONE);
+ mExpandDivider.setVisibility(View.GONE);
+ }
+ }
+
+ public void postZenModeChanged(boolean zen) {
+ removeMessages(MSG_ZEN_MODE_CHANGED);
+ obtainMessage(MSG_ZEN_MODE_CHANGED, zen ? 1 : 0).sendToTarget();
+ }
+
public void postVolumeChanged(int streamType, int flags) {
if (hasMessages(MSG_VOLUME_CHANGED)) return;
synchronized (this) {
@@ -582,8 +628,12 @@ public class VolumePanel extends Handler {
}
public void postDismiss() {
- removeMessages(MSG_TIMEOUT);
- sendEmptyMessage(MSG_TIMEOUT);
+ forceTimeout();
+ }
+
+ public void postLayoutDirection(int layoutDirection) {
+ removeMessages(MSG_LAYOUT_DIRECTION);
+ obtainMessage(MSG_LAYOUT_DIRECTION, layoutDirection).sendToTarget();
}
/**
@@ -593,7 +643,7 @@ public class VolumePanel extends Handler {
*/
protected void onVolumeChanged(int streamType, int flags) {
- if (LOGD) Log.d(TAG, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")");
+ if (LOGD) Log.d(mTag, "onVolumeChanged(streamType: " + streamType + ", flags: " + flags + ")");
if ((flags & AudioManager.FLAG_SHOW_UI) != 0) {
synchronized (this) {
@@ -622,7 +672,7 @@ public class VolumePanel extends Handler {
protected void onMuteChanged(int streamType, int flags) {
- if (LOGD) Log.d(TAG, "onMuteChanged(streamType: " + streamType + ", flags: " + flags + ")");
+ if (LOGD) Log.d(mTag, "onMuteChanged(streamType: " + streamType + ", flags: " + flags + ")");
StreamControl sc = mStreamControls.get(streamType);
if (sc != null) {
@@ -638,7 +688,7 @@ public class VolumePanel extends Handler {
mRingIsSilent = false;
if (LOGD) {
- Log.d(TAG, "onShowVolumeChanged(streamType: " + streamType
+ Log.d(mTag, "onShowVolumeChanged(streamType: " + streamType
+ ", flags: " + flags + "), index: " + index);
}
@@ -707,7 +757,7 @@ public class VolumePanel extends Handler {
}
case AudioService.STREAM_REMOTE_MUSIC: {
- if (LOGD) { Log.d(TAG, "showing remote volume "+index+" over "+ max); }
+ if (LOGD) { Log.d(mTag, "showing remote volume "+index+" over "+ max); }
break;
}
}
@@ -730,16 +780,18 @@ public class VolumePanel extends Handler {
}
}
- if (!mDialog.isShowing()) {
+ if (!isShowing()) {
int stream = (streamType == AudioService.STREAM_REMOTE_MUSIC) ? -1 : streamType;
// when the stream is for remote playback, use -1 to reset the stream type evaluation
mAudioManager.forceVolumeControlStream(stream);
// Showing dialog - use collapsed state
- if (mShowCombinedVolumes) {
+ if (mZenModeCapable) {
collapse();
}
- mDialog.show();
+ if (mDialog != null) {
+ mDialog.show();
+ }
}
// Do a little vibrate if applicable (only when going into vibrate mode)
@@ -751,6 +803,10 @@ public class VolumePanel extends Handler {
}
}
+ private boolean isShowing() {
+ return mDialog != null ? mDialog.isShowing() : mParent.isAttachedToWindow();
+ }
+
protected void onPlaySound(int streamType, int flags) {
if (hasMessages(MSG_STOP_SOUNDS)) {
@@ -795,9 +851,9 @@ public class VolumePanel extends Handler {
// streamType is the real stream type being affected, but for the UI sliders, we
// refer to AudioService.STREAM_REMOTE_MUSIC. We still play the beeps on the real
// stream type.
- if (LOGD) Log.d(TAG, "onRemoteVolumeChanged(stream:"+streamType+", flags: " + flags + ")");
+ if (LOGD) Log.d(mTag, "onRemoteVolumeChanged(stream:"+streamType+", flags: " + flags + ")");
- if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || mDialog.isShowing()) {
+ if (((flags & AudioManager.FLAG_SHOW_UI) != 0) || isShowing()) {
synchronized (this) {
if (mActiveStreamType != AudioService.STREAM_REMOTE_MUSIC) {
reorderSliders(AudioService.STREAM_REMOTE_MUSIC);
@@ -805,7 +861,7 @@ public class VolumePanel extends Handler {
onShowVolumeChanged(AudioService.STREAM_REMOTE_MUSIC, flags);
}
} else {
- if (LOGD) Log.d(TAG, "not calling onShowVolumeChanged(), no FLAG_SHOW_UI or no UI");
+ if (LOGD) Log.d(mTag, "not calling onShowVolumeChanged(), no FLAG_SHOW_UI or no UI");
}
if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 && ! mRingIsSilent) {
@@ -825,8 +881,8 @@ public class VolumePanel extends Handler {
}
protected void onRemoteVolumeUpdateIfShown() {
- if (LOGD) Log.d(TAG, "onRemoteVolumeUpdateIfShown()");
- if (mDialog.isShowing()
+ if (LOGD) Log.d(mTag, "onRemoteVolumeUpdateIfShown()");
+ if (isShowing()
&& (mActiveStreamType == AudioService.STREAM_REMOTE_MUSIC)
&& (mStreamControls != null)) {
onShowVolumeChanged(AudioService.STREAM_REMOTE_MUSIC, 0);
@@ -842,7 +898,7 @@ public class VolumePanel extends Handler {
* @param visible
*/
synchronized protected void onSliderVisibilityChanged(int streamType, int visible) {
- if (LOGD) Log.d(TAG, "onSliderVisibilityChanged(stream="+streamType+", visi="+visible+")");
+ if (LOGD) Log.d(mTag, "onSliderVisibilityChanged(stream="+streamType+", visi="+visible+")");
boolean isVisible = (visible == 1);
for (int i = STREAMS.length - 1 ; i >= 0 ; i--) {
StreamResources streamRes = STREAMS[i];
@@ -857,7 +913,7 @@ public class VolumePanel extends Handler {
}
protected void onDisplaySafeVolumeWarning(int flags) {
- if ((flags & AudioManager.FLAG_SHOW_UI) != 0 || mDialog.isShowing()) {
+ if ((flags & AudioManager.FLAG_SHOW_UI) != 0 || isShowing()) {
synchronized (sConfirmSafeVolumeLock) {
if (sConfirmSafeVolumeDialog != null) {
return;
@@ -907,7 +963,7 @@ public class VolumePanel extends Handler {
mToneGenerators[streamType] = new ToneGenerator(streamType, MAX_VOLUME);
} catch (RuntimeException e) {
if (LOGD) {
- Log.d(TAG, "ToneGenerator constructor failed with "
+ Log.d(mTag, "ToneGenerator constructor failed with "
+ "RuntimeException: " + e);
}
}
@@ -976,9 +1032,11 @@ public class VolumePanel extends Handler {
}
case MSG_TIMEOUT: {
- if (mDialog.isShowing()) {
- mDialog.dismiss();
- mActiveStreamType = -1;
+ if (isShowing()) {
+ if (mDialog != null) {
+ mDialog.dismiss();
+ mActiveStreamType = -1;
+ }
}
synchronized (sConfirmSafeVolumeLock) {
if (sConfirmSafeVolumeDialog != null) {
@@ -988,7 +1046,7 @@ public class VolumePanel extends Handler {
break;
}
case MSG_RINGER_MODE_CHANGED: {
- if (mDialog.isShowing()) {
+ if (isShowing()) {
updateStates();
}
break;
@@ -1010,17 +1068,30 @@ public class VolumePanel extends Handler {
case MSG_DISPLAY_SAFE_VOLUME_WARNING:
onDisplaySafeVolumeWarning(msg.arg1);
break;
+
+ case MSG_LAYOUT_DIRECTION:
+ setLayoutDirection(msg.arg1);
+ break;
+
+ case MSG_ZEN_MODE_CHANGED:
+ updateZenMode(msg.arg1 != 0);
+ break;
}
}
- private void resetTimeout() {
+ public void resetTimeout() {
+ if (LOGD) Log.d(mTag, "resetTimeout at " + System.currentTimeMillis());
removeMessages(MSG_TIMEOUT);
- sendMessageDelayed(obtainMessage(MSG_TIMEOUT), TIMEOUT_DELAY);
+ sendEmptyMessageDelayed(MSG_TIMEOUT, TIMEOUT_DELAY);
}
private void forceTimeout() {
removeMessages(MSG_TIMEOUT);
- sendMessage(obtainMessage(MSG_TIMEOUT));
+ sendEmptyMessage(MSG_TIMEOUT);
+ }
+
+ public ZenModeController getZenController() {
+ return mZenController;
}
private final OnSeekBarChangeListener mSeekListener = new OnSeekBarChangeListener() {
@@ -1061,10 +1132,22 @@ public class VolumePanel extends Handler {
private final View.OnClickListener mClickListener = new View.OnClickListener() {
@Override
public void onClick(View v) {
- if (v == mMoreButton) {
- expand();
+ if (v == mExpandButton && mZenController != null) {
+ final boolean newZen = !mZenController.isZen();
+ mZenController.setZen(newZen);
+ if (newZen) {
+ expand();
+ } else {
+ collapse();
+ }
}
resetTimeout();
}
};
+
+ private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
+ public void onZenChanged(boolean zen) {
+ updateZenMode(zen);
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
index 9bd75b7..7da90d8 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeUI.java
@@ -1,16 +1,22 @@
package com.android.systemui.volume;
import android.content.Context;
+import android.content.Intent;
+import android.content.res.Resources;
import android.database.ContentObserver;
import android.media.AudioManager;
import android.media.IVolumeController;
import android.net.Uri;
import android.os.Handler;
import android.os.RemoteException;
+import android.os.UserHandle;
import android.provider.Settings;
import android.util.Log;
+import com.android.systemui.R;
import com.android.systemui.SystemUI;
+import com.android.systemui.statusbar.policy.ZenModeController;
+import com.android.systemui.statusbar.policy.ZenModeControllerImpl;
/*
* Copyright (C) 2014 The Android Open Source Project
@@ -34,21 +40,21 @@ public class VolumeUI extends SystemUI {
private static final Uri SETTING_URI = Settings.Global.getUriFor(SETTING);
private static final int DEFAULT = 1; // enabled by default
+ private final Handler mHandler = new Handler();
private AudioManager mAudioManager;
private VolumeController mVolumeController;
@Override
public void start() {
mAudioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
+ mVolumeController = new VolumeController(mContext);
+ putComponent(VolumeComponent.class, mVolumeController);
updateController();
mContext.getContentResolver().registerContentObserver(SETTING_URI, false, mObserver);
}
private void updateController() {
if (Settings.Global.getInt(mContext.getContentResolver(), SETTING, DEFAULT) != 0) {
- if (mVolumeController == null) {
- mVolumeController = new VolumeController(mContext);
- }
Log.d(TAG, "Registering volume controller");
mAudioManager.setVolumeController(mVolumeController);
} else {
@@ -57,7 +63,7 @@ public class VolumeUI extends SystemUI {
}
}
- private final ContentObserver mObserver = new ContentObserver(new Handler()) {
+ private final ContentObserver mObserver = new ContentObserver(mHandler) {
public void onChange(boolean selfChange, Uri uri) {
if (SETTING_URI.equals(uri)) {
updateController();
@@ -66,13 +72,38 @@ public class VolumeUI extends SystemUI {
};
/** For now, simply host an unmodified base volume panel in this process. */
- private final class VolumeController extends IVolumeController.Stub {
- private final VolumePanel mPanel;
+ private final class VolumeController extends IVolumeController.Stub implements VolumeComponent {
+ private final VolumePanel mDialogPanel;
+ private VolumePanel mPanel;
public VolumeController(Context context) {
- mPanel = new VolumePanel(context);
+ mPanel = new VolumePanel(context, null, new ZenModeControllerImpl(mContext, mHandler));
+ final int delay = context.getResources().getInteger(R.integer.feedback_start_delay);
+ mPanel.setZenModePanelCallback(new ZenModePanel.Callback() {
+ @Override
+ public void onMoreSettings() {
+ mHandler.removeCallbacks(mStartZenSettings);
+ mHandler.postDelayed(mStartZenSettings, delay);
+ }
+
+ @Override
+ public void onInteraction() {
+ mDialogPanel.resetTimeout();
+ }
+ });
+ mDialogPanel = mPanel;
}
+ private final Runnable mStartZenSettings = new Runnable() {
+ @Override
+ public void run() {
+ mDialogPanel.postDismiss();
+ final Intent intent = ZenModePanel.ZEN_SETTINGS;
+ intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
+ mContext.startActivityAsUser(intent, new UserHandle(UserHandle.USER_CURRENT));
+ }
+ };
+
@Override
public void hasNewRemotePlaybackInfo() throws RemoteException {
mPanel.postHasNewRemotePlaybackInfo();
@@ -114,12 +145,22 @@ public class VolumeUI extends SystemUI {
@Override
public void setLayoutDirection(int layoutDirection)
throws RemoteException {
- mPanel.setLayoutDirection(layoutDirection);
+ mPanel.postLayoutDirection(layoutDirection);
}
@Override
public void dismiss() throws RemoteException {
mPanel.postDismiss();
}
+
+ @Override
+ public ZenModeController getZenController() {
+ return mDialogPanel.getZenController();
+ }
+
+ @Override
+ public void setVolumePanel(VolumePanel panel) {
+ mPanel = panel == null ? mDialogPanel : panel;
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
new file mode 100644
index 0000000..77d267e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -0,0 +1,248 @@
+/*
+ * Copyright (C) 2014 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.volume;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.provider.Settings;
+import android.service.notification.Condition;
+import android.util.AttributeSet;
+import android.view.ContextThemeWrapper;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.CompoundButton;
+import android.widget.CompoundButton.OnCheckedChangeListener;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.RadioButton;
+import android.widget.TextView;
+
+import com.android.systemui.R;
+import com.android.systemui.statusbar.policy.ZenModeController;
+
+import java.util.Arrays;
+import java.util.HashSet;
+
+public class ZenModePanel extends LinearLayout {
+ private static final int[] MINUTES = new int[] { 15, 30, 45, 60, 120, 180, 240, 480 };
+ public static final Intent ZEN_SETTINGS = new Intent(Settings.ACTION_ZEN_MODE_SETTINGS);
+
+ private final LayoutInflater mInflater;
+ private final HashSet<RadioButton> mRadioButtons = new HashSet<RadioButton>();
+ private final H mHandler = new H();
+ private LinearLayout mConditions;
+ private int mMinutesIndex = Arrays.binarySearch(MINUTES, 60); // default to one hour
+ private Callback mCallback;
+ private ZenModeController mController;
+ private boolean mRequestingConditions;
+
+ public ZenModePanel(Context context, AttributeSet attrs) {
+ super(context, attrs);
+ mInflater = LayoutInflater.from(new ContextThemeWrapper(context, R.style.QSWhiteTheme));
+ }
+
+ @Override
+ protected void onFinishInflate() {
+ super.onFinishInflate();
+ mConditions = (LinearLayout) findViewById(android.R.id.content);
+ findViewById(android.R.id.button2).setOnClickListener(new View.OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ fireMoreSettings();
+ }
+ });
+ }
+
+ @Override
+ public void setVisibility(int visibility) {
+ super.setVisibility(visibility);
+ setRequestingConditions(visibility == VISIBLE);
+ }
+
+ /** Start or stop requesting relevant zen mode exit conditions */
+ private void setRequestingConditions(boolean requesting) {
+ if (mRequestingConditions == requesting) return;
+ mRequestingConditions = requesting;
+ if (mRequestingConditions) {
+ mController.addCallback(mZenCallback);
+ } else {
+ mController.removeCallback(mZenCallback);
+ }
+ mController.requestConditions(mRequestingConditions);
+ }
+
+ public void init(ZenModeController controller) {
+ mController = controller;
+ mConditions.removeAllViews();
+ bind(updateTimeCondition(), mConditions.getChildAt(0));
+ handleUpdateConditions(new Condition[0]);
+ }
+
+ public void setCallback(Callback callback) {
+ mCallback = callback;
+ }
+
+ private Condition updateTimeCondition() {
+ final int minutes = MINUTES[mMinutesIndex];
+ final long millis = System.currentTimeMillis() + minutes * 60 * 1000;
+ final Uri id = new Uri.Builder().scheme(Condition.SCHEME).authority("android")
+ .appendPath("countdown").appendPath(Long.toString(millis)).build();
+ final int num = minutes < 60 ? minutes : minutes / 60;
+ final int resId = minutes < 60
+ ? R.plurals.zen_mode_duration_minutes
+ : R.plurals.zen_mode_duration_hours;
+ final String caption = mContext.getResources().getQuantityString(resId, num, num);
+ return new Condition(id, caption, "", "", 0, Condition.STATE_TRUE,
+ Condition.FLAG_RELEVANT_NOW);
+ }
+
+ private void handleUpdateConditions(Condition[] conditions) {
+ final int newCount = conditions == null ? 0 : conditions.length;
+ for (int i = mConditions.getChildCount() - 1; i > newCount; i--) {
+ mConditions.removeViewAt(i);
+ }
+ for (int i = 0; i < newCount; i++) {
+ bind(conditions[i], mConditions.getChildAt(i + 1));
+ }
+ bind(null, mConditions.getChildAt(newCount + 1));
+ }
+
+ private void editTimeCondition(int delta) {
+ final int i = mMinutesIndex + delta;
+ if (i < 0 || i >= MINUTES.length) return;
+ mMinutesIndex = i;
+ final Condition c = updateTimeCondition();
+ bind(c, mConditions.getChildAt(0));
+ }
+
+ private void bind(final Condition condition, View convertView) {
+ final boolean enabled = condition == null || condition.state == Condition.STATE_TRUE;
+ final View row;
+ if (convertView == null) {
+ row = mInflater.inflate(R.layout.zen_mode_condition, this, false);
+ mConditions.addView(row);
+ } else {
+ row = convertView;
+ }
+ final int position = mConditions.indexOfChild(row);
+ final RadioButton rb = (RadioButton) row.findViewById(android.R.id.checkbox);
+ mRadioButtons.add(rb);
+ rb.setEnabled(enabled);
+ rb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
+ @Override
+ public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+ if (isChecked) {
+ for (RadioButton otherButton : mRadioButtons) {
+ if (otherButton == rb) continue;
+ otherButton.setChecked(false);
+ }
+ mController.select(condition);
+ fireInteraction();
+ }
+ }
+ });
+ final TextView title = (TextView) row.findViewById(android.R.id.title);
+ if (condition == null) {
+ title.setText(R.string.zen_mode_forever);
+ } else {
+ title.setText(condition.summary);
+ }
+ title.setEnabled(enabled);
+ title.setAlpha(enabled ? 1 : .5f);
+ final ImageView button1 = (ImageView) row.findViewById(android.R.id.button1);
+ button1.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ rb.setChecked(true);
+ editTimeCondition(-1);
+ fireInteraction();
+ }
+ });
+
+ final ImageView button2 = (ImageView) row.findViewById(android.R.id.button2);
+ button2.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ rb.setChecked(true);
+ editTimeCondition(1);
+ fireInteraction();
+ }
+ });
+ title.setOnClickListener(new OnClickListener() {
+ @Override
+ public void onClick(View v) {
+ rb.setChecked(true);
+ fireInteraction();
+ }
+ });
+ if (position == 0) {
+ button1.setEnabled(mMinutesIndex > 0);
+ button2.setEnabled(mMinutesIndex < MINUTES.length - 1);
+ button1.setImageAlpha(button1.isEnabled() ? 0xff : 0x7f);
+ button2.setImageAlpha(button2.isEnabled() ? 0xff : 0x7f);
+ } else {
+ button1.setVisibility(View.GONE);
+ button2.setVisibility(View.GONE);
+ }
+ if (position == 0 && mConditions.getChildCount() == 1) {
+ rb.setChecked(true);
+ }
+ }
+
+ private void fireMoreSettings() {
+ if (mCallback != null) {
+ mCallback.onMoreSettings();
+ }
+ }
+
+ private void fireInteraction() {
+ if (mCallback != null) {
+ mCallback.onInteraction();
+ }
+ }
+
+ private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
+ @Override
+ public void onConditionsChanged(Condition[] conditions) {
+ mHandler.obtainMessage(H.UPDATE_CONDITIONS, conditions).sendToTarget();
+ }
+ };
+
+ private final class H extends Handler {
+ private static final int UPDATE_CONDITIONS = 1;
+
+ private H() {
+ super(Looper.getMainLooper());
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ if (msg.what == UPDATE_CONDITIONS) {
+ handleUpdateConditions((Condition[])msg.obj);
+ }
+ }
+ }
+
+ public interface Callback {
+ void onMoreSettings();
+ void onInteraction();
+ }
+}