diff options
| author | 2018-02-23 22:11:06 +0000 | |
|---|---|---|
| committer | 2018-02-23 22:11:06 +0000 | |
| commit | bf077b51b4065da8c8af0a3ff59f39c8eeda1690 (patch) | |
| tree | c2036f887cd2776758f69ce0e4c5105042958794 | |
| parent | e12dc74665326dc08f362c7288ccd917316c7ae4 (diff) | |
| parent | 41ff695104f5845565a09796e9a70aa5fdd5d342 (diff) | |
Merge "Alignment of clock and shade"
17 files changed, 190 insertions, 347 deletions
diff --git a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml index 713c5739de2d..fa14d1b55896 100644 --- a/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml +++ b/packages/SystemUI/res-keyguard/layout/keyguard_status_view.xml @@ -62,7 +62,7 @@ android:layout_gravity="center_horizontal" android:layout_centerHorizontal="true" android:layout_alignParentTop="true" - android:letterSpacing="0.04" + android:letterSpacing="0.03" android:textColor="?attr/wallpaperTextColor" android:singleLine="true" style="@style/widget_big_thin" diff --git a/packages/SystemUI/res-keyguard/values/dimens.xml b/packages/SystemUI/res-keyguard/values/dimens.xml index 4934e147e42b..1c1c7579b8ad 100644 --- a/packages/SystemUI/res-keyguard/values/dimens.xml +++ b/packages/SystemUI/res-keyguard/values/dimens.xml @@ -60,8 +60,8 @@ <dimen name="widget_horizontal_padding">8dp</dimen> <dimen name="widget_icon_size">16dp</dimen> <dimen name="widget_icon_padding">8dp</dimen> - <!-- Dash between notification shelf and date/alarm --> - <dimen name="widget_bottom_separator_padding">29dp</dimen> + <!-- Space between notification shelf and dash above it --> + <dimen name="widget_bottom_separator_padding">28dp</dimen> <!-- The y translation to apply at the start in appear animations. --> <dimen name="appear_y_translation_start">32dp</dimen> diff --git a/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml b/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml deleted file mode 100644 index f6dbc3de2738..000000000000 --- a/packages/SystemUI/res/values-h560dp-xhdpi/dimens.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?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 - --> - -<resources> - <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction> - <fraction name="keyguard_clock_y_fraction_min">24%</fraction> -</resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml b/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml deleted file mode 100644 index b2231a6160a9..000000000000 --- a/packages/SystemUI/res/values-h560dp-xxhdpi/config.xml +++ /dev/null @@ -1,22 +0,0 @@ -<?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 - --> -<resources> - <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow - card. --> - <integer name="keyguard_max_notification_count">4</integer> -</resources> - diff --git a/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml b/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml deleted file mode 100644 index 905e9e3adb62..000000000000 --- a/packages/SystemUI/res/values-h560dp-xxhdpi/dimens.xml +++ /dev/null @@ -1,21 +0,0 @@ -<?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 - --> - -<resources> - <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction> - <fraction name="keyguard_clock_y_fraction_min">19.8%</fraction> -</resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-h650dp/config.xml b/packages/SystemUI/res/values-h650dp/config.xml deleted file mode 100644 index ee641b4b6edd..000000000000 --- a/packages/SystemUI/res/values-h650dp/config.xml +++ /dev/null @@ -1,24 +0,0 @@ -<?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 - --> - -<resources> - <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow - card. --> - <integer name="keyguard_max_notification_count">5</integer> -</resources> - diff --git a/packages/SystemUI/res/values-h650dp/dimens.xml b/packages/SystemUI/res/values-h650dp/dimens.xml index 3811f678e330..8a0095304978 100644 --- a/packages/SystemUI/res/values-h650dp/dimens.xml +++ b/packages/SystemUI/res/values-h650dp/dimens.xml @@ -16,7 +16,4 @@ <resources> <dimen name="keyguard_clock_notifications_margin">32dp</dimen> - - <fraction name="keyguard_clock_y_fraction_max">32.5%</fraction> - <fraction name="keyguard_clock_y_fraction_min">18.5%</fraction> </resources>
\ No newline at end of file diff --git a/packages/SystemUI/res/values-sw600dp-land/config.xml b/packages/SystemUI/res/values-sw600dp-land/config.xml index 6594bd28c8b4..c4c467152281 100644 --- a/packages/SystemUI/res/values-sw600dp-land/config.xml +++ b/packages/SystemUI/res/values-sw600dp-land/config.xml @@ -15,10 +15,6 @@ ~ limitations under the License --> <resources> - <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow - card. --> - <integer name="keyguard_max_notification_count">3</integer> - <!-- Whether QuickSettings is in a phone landscape --> <bool name="quick_settings_wide">false</bool> diff --git a/packages/SystemUI/res/values-sw600dp-land/dimens.xml b/packages/SystemUI/res/values-sw600dp-land/dimens.xml index 13ca11401c03..f2df4b9023b1 100644 --- a/packages/SystemUI/res/values-sw600dp-land/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp-land/dimens.xml @@ -16,9 +16,6 @@ */ --> <resources> - <fraction name="keyguard_clock_y_fraction_max">37%</fraction> - <fraction name="keyguard_clock_y_fraction_min">20%</fraction> - <dimen name="keyguard_clock_notifications_margin">36dp</dimen> <dimen name="keyguard_indication_margin_bottom">80dp</dimen> diff --git a/packages/SystemUI/res/values-sw600dp/config.xml b/packages/SystemUI/res/values-sw600dp/config.xml index 63b9d75f5054..67dabdb7353d 100644 --- a/packages/SystemUI/res/values-sw600dp/config.xml +++ b/packages/SystemUI/res/values-sw600dp/config.xml @@ -26,10 +26,6 @@ <!-- The number of columns that the top level tiles span in the QuickSettings --> <integer name="quick_settings_user_time_settings_tile_span">1</integer> - <!-- The maximum count of notifications on Keyguard. The rest will be collapsed in an overflow - card. --> - <integer name="keyguard_max_notification_count">5</integer> - <!-- Set to true to enable the user switcher on the keyguard. --> <bool name="config_keyguardUserSwitcher">true</bool> diff --git a/packages/SystemUI/res/values-sw600dp/dimens.xml b/packages/SystemUI/res/values-sw600dp/dimens.xml index e95d9fee880b..923edc8f1e92 100644 --- a/packages/SystemUI/res/values-sw600dp/dimens.xml +++ b/packages/SystemUI/res/values-sw600dp/dimens.xml @@ -38,12 +38,6 @@ <!-- On tablets this is just the close_handle_height --> <dimen name="peek_height">@dimen/close_handle_height</dimen> - <!-- The fraction of the screen height where the clock on the Keyguard has its center. The - max value is used when no notifications are displaying, and the min value is when the - highest possible number of notifications are showing. --> - <fraction name="keyguard_clock_y_fraction_max">34%</fraction> - <fraction name="keyguard_clock_y_fraction_min">24%</fraction> - <!-- 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">44dp</dimen> diff --git a/packages/SystemUI/res/values-sw720dp-land/config.xml b/packages/SystemUI/res/values-sw720dp-land/config.xml deleted file mode 100644 index 1b502886d8da..000000000000 --- a/packages/SystemUI/res/values-sw720dp-land/config.xml +++ /dev/null @@ -1,20 +0,0 @@ -<?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 - --> -<resources> - <integer name="keyguard_max_notification_count">4</integer> -</resources> - diff --git a/packages/SystemUI/res/values-sw720dp-land/dimens.xml b/packages/SystemUI/res/values-sw720dp-land/dimens.xml deleted file mode 100644 index 511d45ffe71d..000000000000 --- a/packages/SystemUI/res/values-sw720dp-land/dimens.xml +++ /dev/null @@ -1,23 +0,0 @@ -<?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 - --> -<resources> - <!-- The fraction of the screen height where the clock on the Keyguard has its center. The - min value is used when no notifications are displaying, and the max value is when the - highest possible number of notifications are showing. --> - <fraction name="keyguard_clock_y_fraction_max">35%</fraction> - <fraction name="keyguard_clock_y_fraction_min">24%</fraction> -</resources> diff --git a/packages/SystemUI/res/values-sw720dp/dimens.xml b/packages/SystemUI/res/values-sw720dp/dimens.xml index 25e96c8848db..8cf4adb73a7c 100644 --- a/packages/SystemUI/res/values-sw720dp/dimens.xml +++ b/packages/SystemUI/res/values-sw720dp/dimens.xml @@ -28,11 +28,5 @@ <dimen name="notification_panel_min_height">770dp</dimen> <!-- Bottom margin (from display edge) for status bar panels --> <dimen name="panel_float">56dp</dimen> - - <!-- The fraction of the screen height where the clock on the Keyguard has its center. The - max value is used when no notifications are displaying, and the min value is when the - highest possible number of notifications are showing. --> - <fraction name="keyguard_clock_y_fraction_max">35%</fraction> - <fraction name="keyguard_clock_y_fraction_min">25%</fraction> </resources> diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml index 1ec59bf4140d..aefcb55ba13d 100644 --- a/packages/SystemUI/res/values/dimens.xml +++ b/packages/SystemUI/res/values/dimens.xml @@ -439,15 +439,10 @@ <!-- Minimum distance the user has to drag down to go to the full shade. --> <dimen name="keyguard_drag_down_min_distance">100dp</dimen> - <!-- The fraction of the screen height where the clock on the Keyguard has its center. The - max value is used when no notifications are displaying, and the min value is when the - highest possible number of notifications are showing. --> - <fraction name="keyguard_clock_y_fraction_max">45%</fraction> - <fraction name="keyguard_clock_y_fraction_min">19.8%</fraction> - - <!-- The margin between the clock and the notifications on Keyguard. See - keyguard_clock_height_fraction_* for the difference between min and max.--> + <!-- The margin between the clock and the notifications on Keyguard.--> <dimen name="keyguard_clock_notifications_margin">30dp</dimen> + <!-- Minimum margin between clock and top of screen or ambient indication --> + <dimen name="keyguard_clock_top_margin">26dp</dimen> <dimen name="heads_up_scrim_height">250dp</dimen> <item name="scrim_behind_alpha" format="float" type="dimen">0.62</item> @@ -885,9 +880,6 @@ burn-in on AOD --> <dimen name="burn_in_prevention_offset_y">50dp</dimen> - <!-- padding between the notification stack and the keyguard status view when dozing --> - <dimen name="dozing_stack_padding">30dp</dimen> - <dimen name="corner_size">16dp</dimen> <dimen name="top_padding">0dp</dimen> <dimen name="bottom_padding">48dp</dimen> diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java index 389be1ad6d77..0cf26df7b377 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardClockPositionAlgorithm.java @@ -19,11 +19,10 @@ package com.android.systemui.statusbar.phone; import static com.android.systemui.statusbar.notification.NotificationUtils.interpolate; import android.content.res.Resources; -import android.graphics.Path; import android.util.MathUtils; -import android.view.animation.AccelerateInterpolator; -import android.view.animation.PathInterpolator; +import com.android.keyguard.KeyguardStatusView; +import com.android.systemui.Interpolators; import com.android.systemui.R; /** @@ -31,54 +30,83 @@ import com.android.systemui.R; */ public class KeyguardClockPositionAlgorithm { - private static final float SLOW_DOWN_FACTOR = 0.4f; - - private static final float CLOCK_RUBBERBAND_FACTOR_MIN = 0.08f; - private static final float CLOCK_RUBBERBAND_FACTOR_MAX = 0.8f; - private static final float CLOCK_SCALE_FADE_START = 0.95f; - private static final float CLOCK_SCALE_FADE_END = 0.75f; - private static final float CLOCK_SCALE_FADE_END_NO_NOTIFS = 0.5f; - - private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN = 1.4f; - private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX = 3.2f; - private static final long MILLIS_PER_MINUTES = 1000 * 60; private static final float BURN_IN_PREVENTION_PERIOD_Y = 521; private static final float BURN_IN_PREVENTION_PERIOD_X = 83; + /** + * How much the clock height influences the shade position. + * 0 means nothing, 1 means move the shade up by the height of the clock + * 0.5f means move the shade up by half of the size of the clock. + */ + private static float CLOCK_HEIGHT_WEIGHT = 0.7f; + + /** + * Margin between the bottom of the clock and the notification shade. + */ private int mClockNotificationsMargin; - private float mClockYFractionMin; - private float mClockYFractionMax; - private int mMaxKeyguardNotifications; - private int mMaxPanelHeight; + + /** + * Current height of {@link NotificationPanelView}, considering how much the + * user collapsed it. + */ private float mExpandedHeight; - private int mNotificationCount; + + /** + * Height of the parent view - display size in px. + */ private int mHeight; + + /** + * Height of {@link KeyguardStatusView}. + */ private int mKeyguardStatusHeight; - private float mEmptyDragAmount; - private float mDensity; - private int mBurnInPreventionOffsetX; - private int mBurnInPreventionOffsetY; /** - * The number (fractional) of notifications the "more" card counts when calculating how many - * notifications are currently visible for the y positioning of the clock. + * Height of notification stack: Sum of height of each notification. + */ + private int mNotificationStackHeight; + + /** + * Minimum top margin to avoid overlap with status bar. */ - private float mMoreCardNotificationAmount; + private int mMinTopMargin; - private static final PathInterpolator sSlowDownInterpolator; + /** + * Maximum bottom padding to avoid overlap with {@link KeyguardBottomAreaView} or + * the ambient indication. + */ + private int mMaxShadeBottom; - static { - Path path = new Path(); - path.moveTo(0, 0); - path.cubicTo(0.3f, 0.875f, 0.6f, 1f, 1f, 1f); - sSlowDownInterpolator = new PathInterpolator(path); - } + /** + * Margin that we should respect within the available space. + */ + private int mContainerPadding; - private AccelerateInterpolator mAccelerateInterpolator = new AccelerateInterpolator(); - private int mClockBottom; + /** + * Position where clock should be when the panel is collapsed. + */ + private int mClockYTarget; + + /** + * @see NotificationPanelView#getMaxPanelHeight() + */ + private float mMaxPanelHeight; + + /** + * Burn-in prevention x translation. + */ + private int mBurnInPreventionOffsetX; + + /** + * Burn-in prevention y translation. + */ + private int mBurnInPreventionOffsetY; + + /** + * Doze/AOD transition amount. + */ private float mDarkAmount; - private int mDozingStackPadding; /** * Refreshes the dimension values. @@ -86,79 +114,95 @@ public class KeyguardClockPositionAlgorithm { public void loadDimens(Resources res) { mClockNotificationsMargin = res.getDimensionPixelSize( R.dimen.keyguard_clock_notifications_margin); - mClockYFractionMin = res.getFraction(R.fraction.keyguard_clock_y_fraction_min, 1, 1); - mClockYFractionMax = res.getFraction(R.fraction.keyguard_clock_y_fraction_max, 1, 1); - mMoreCardNotificationAmount = - (float) res.getDimensionPixelSize(R.dimen.notification_shelf_height) / - res.getDimensionPixelSize(R.dimen.notification_min_height); - mDensity = res.getDisplayMetrics().density; + mContainerPadding = res.getDimensionPixelSize( + R.dimen.keyguard_clock_top_margin); mBurnInPreventionOffsetX = res.getDimensionPixelSize( R.dimen.burn_in_prevention_offset_x); mBurnInPreventionOffsetY = res.getDimensionPixelSize( R.dimen.burn_in_prevention_offset_y); - mDozingStackPadding = res.getDimensionPixelSize(R.dimen.dozing_stack_padding); } - public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight, - int notificationCount, int height, int keyguardStatusHeight, float emptyDragAmount, - int clockBottom, float dark) { - mMaxKeyguardNotifications = maxKeyguardNotifications; - mMaxPanelHeight = maxPanelHeight; + public void setup(int minTopMargin, int maxShadeBottom, int notificationStackHeight, + float expandedHeight, float maxPanelHeight, int parentHeight, int keyguardStatusHeight, + float dark) { + mMinTopMargin = minTopMargin; + mMaxShadeBottom = maxShadeBottom; + mNotificationStackHeight = notificationStackHeight; mExpandedHeight = expandedHeight; - mNotificationCount = notificationCount; - mHeight = height; + mMaxPanelHeight = maxPanelHeight; + mHeight = parentHeight; mKeyguardStatusHeight = keyguardStatusHeight; - mEmptyDragAmount = emptyDragAmount; - mClockBottom = clockBottom; mDarkAmount = dark; - } - public float getMinStackScrollerPadding(int height, int keyguardStatusHeight) { - return mClockYFractionMin * height + keyguardStatusHeight / 2 - + mClockNotificationsMargin; + // Where the clock should stop when swiping up. + // This should be outside of the display when unlocked or + // under then status bar when the bouncer will be shown + mClockYTarget = -mKeyguardStatusHeight; + // TODO: on bouncer animation follow-up CL + // mClockYTarget = mMinTopMargin + mContainerPadding; } public void run(Result result) { - int y = getClockY() - mKeyguardStatusHeight / 2; - float clockAdjustment = getClockYExpansionAdjustment(); - float topPaddingAdjMultiplier = getTopPaddingAdjMultiplier(); - result.stackScrollerPaddingAdjustment = (int) (clockAdjustment*topPaddingAdjMultiplier); + final int y = getClockY(); result.clockY = y; - int clockNotificationsPadding = mClockNotificationsMargin - + result.stackScrollerPaddingAdjustment; - int padding = y + clockNotificationsPadding; - result.clockScale = getClockScale(mKeyguardStatusHeight + padding, - y, y + mClockNotificationsMargin + mKeyguardStatusHeight); - result.clockAlpha = getClockAlpha(result.clockScale); - - result.stackScrollerPadding = mClockBottom + y + mDozingStackPadding; + result.clockAlpha = getClockAlpha(y); + result.stackScrollerPadding = y + mKeyguardStatusHeight; result.clockX = (int) interpolate(0, burnInPreventionOffsetX(), mDarkAmount); } - private float getClockScale(int notificationPadding, int clockY, int startPadding) { - float scaleMultiplier = getNotificationAmountT() == 0 ? 6.0f : 5.0f; - float scaleEnd = clockY - mKeyguardStatusHeight * scaleMultiplier; - float distanceToScaleEnd = notificationPadding - scaleEnd; - float progress = distanceToScaleEnd / (startPadding - scaleEnd); - progress = Math.max(0.0f, Math.min(progress, 1.0f)); - progress = mAccelerateInterpolator.getInterpolation(progress); - progress *= Math.pow(1 + mEmptyDragAmount / mDensity / 300, 0.3f); - return interpolate(progress, 1, mDarkAmount); + public float getMinStackScrollerPadding() { + return mMinTopMargin + mKeyguardStatusHeight + mClockNotificationsMargin; + } + + private int getMaxClockY() { + return mHeight / 2 - mKeyguardStatusHeight - mClockNotificationsMargin; } - private float getClockYFraction() { - float t = getNotificationAmountT(); - t = Math.min(t, 1.0f); - return MathUtils.lerp(mClockYFractionMax, mClockYFractionMin, t); + public int getExpandedClockBottom() { + return getExpandedClockPosition() + mKeyguardStatusHeight; + } + + /** + * Vertically align the clock and the shade in the available space considering only + * a percentage of the clock height defined by {@code CLOCK_HEIGHT_WEIGHT}. + * @return Clock Y in pixels. + */ + private int getExpandedClockPosition() { + final int availableHeight = mMaxShadeBottom - mMinTopMargin; + final int containerCenter = mMinTopMargin + availableHeight / 2; + + float y = containerCenter - mKeyguardStatusHeight * CLOCK_HEIGHT_WEIGHT + - mClockNotificationsMargin - mNotificationStackHeight / 2; + if (y < mMinTopMargin + mContainerPadding) { + y = mMinTopMargin + mContainerPadding; + } + + // Don't allow the clock base to be under half of the screen + final float maxClockY = getMaxClockY(); + if (y > maxClockY) { + y = maxClockY; + } + + return (int) y; } private int getClockY() { // Dark: Align the bottom edge of the clock at about half of the screen: - float clockYDark = (mClockYFractionMax * mHeight + - (float) mKeyguardStatusHeight / 2 - mClockBottom) - + burnInPreventionOffsetY(); - float clockYRegular = getClockYFraction() * mHeight; - return (int) interpolate(clockYRegular, clockYDark, mDarkAmount); + final float clockYDark = getMaxClockY() + burnInPreventionOffsetY(); + float clockYRegular = getExpandedClockPosition(); + + // Move clock up while collapsing the shade + final float shadeExpansion = mExpandedHeight / mMaxPanelHeight; + final float clockY = MathUtils.lerp(mClockYTarget, clockYRegular, shadeExpansion); + + return (int) MathUtils.lerp(clockY, clockYDark, mDarkAmount); + } + + private float getClockAlpha(int y) { + float alphaKeyguard = Math.max(0, Math.min(1, (y - mMinTopMargin) + / Math.max(1f, getExpandedClockPosition() - mMinTopMargin))); + alphaKeyguard = Interpolators.ACCELERATE.getInterpolation(alphaKeyguard); + return MathUtils.lerp(alphaKeyguard, 1f, mDarkAmount); } private float burnInPreventionOffsetY() { @@ -190,61 +234,17 @@ public class KeyguardClockPositionAlgorithm { return interpolate(0, amplitude, interpolationAmount); } - private float getClockYExpansionAdjustment() { - float rubberbandFactor = getClockYExpansionRubberbandFactor(); - float value = (rubberbandFactor * (mMaxPanelHeight - mExpandedHeight)); - float t = value / mMaxPanelHeight; - float slowedDownValue = -sSlowDownInterpolator.getInterpolation(t) * SLOW_DOWN_FACTOR - * mMaxPanelHeight; - if (mNotificationCount == 0) { - return (-2*value + slowedDownValue)/3; - } else { - return slowedDownValue; - } - } - - private float getClockYExpansionRubberbandFactor() { - float t = getNotificationAmountT(); - t = Math.min(t, 1.0f); - t = (float) Math.pow(t, 0.3f); - return (1 - t) * CLOCK_RUBBERBAND_FACTOR_MAX + t * CLOCK_RUBBERBAND_FACTOR_MIN; - } - - private float getTopPaddingAdjMultiplier() { - float t = getNotificationAmountT(); - t = Math.min(t, 1.0f); - return (1 - t) * CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MIN - + t * CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX; - } - - private float getClockAlpha(float scale) { - float fadeEnd = getNotificationAmountT() == 0.0f - ? CLOCK_SCALE_FADE_END_NO_NOTIFS - : CLOCK_SCALE_FADE_END; - float alpha = (scale - fadeEnd) - / (CLOCK_SCALE_FADE_START - fadeEnd); - return Math.max(0, Math.min(1, alpha)); - } - - /** - * @return a value from 0 to 1 depending on how many notification there are - */ - private float getNotificationAmountT() { - return mNotificationCount - / (mMaxKeyguardNotifications + mMoreCardNotificationAmount); - } - public static class Result { /** - * The y translation of the clock. + * The x translation of the clock. */ - public int clockY; + public int clockX; /** - * The scale of the Clock + * The y translation of the clock. */ - public float clockScale; + public int clockY; /** * The alpha value of the clock. @@ -255,14 +255,5 @@ public class KeyguardClockPositionAlgorithm { * The top padding of the stack scroller, in pixels. */ public int stackScrollerPadding; - - /** - * The top padding adjustment of the stack scroller, in pixels. This value is used to adjust - * the padding, but not the overall panel size. - */ - public int stackScrollerPaddingAdjustment; - - /** The x translation of the clock. */ - public int clockX; } } 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 3b129fc5e08d..51d094e5f8b0 100644 --- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java +++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java @@ -37,6 +37,7 @@ import android.graphics.Rect; import android.os.PowerManager; import android.util.AttributeSet; import android.util.FloatProperty; +import android.util.Log; import android.util.MathUtils; import android.view.LayoutInflater; import android.view.MotionEvent; @@ -172,7 +173,6 @@ public class NotificationPanelView extends PanelView implements private Animator mClockAnimator; private int mClockAnimationTargetX = Integer.MIN_VALUE; private int mClockAnimationTargetY = Integer.MIN_VALUE; - private int mTopPaddingAdjustment; private KeyguardClockPositionAlgorithm mClockPositionAlgorithm = new KeyguardClockPositionAlgorithm(); private KeyguardClockPositionAlgorithm.Result mClockPositionResult = @@ -244,6 +244,7 @@ public class NotificationPanelView extends PanelView implements private int mQsNotificationTopPadding; private float mExpandOffset; private boolean mHideIconsDuringNotificationLaunch = true; + private int mStackScrollerMeasuringPass; public NotificationPanelView(Context context, AttributeSet attrs) { super(context, attrs); @@ -459,17 +460,17 @@ public class NotificationPanelView extends PanelView implements if (mStatusBarState != StatusBarState.KEYGUARD) { stackScrollerPadding = (mQs != null ? mQs.getHeader().getHeight() : 0) + mQsPeekHeight + mQsNotificationTopPadding; - mTopPaddingAdjustment = 0; } else { + final int totalHeight = getHeight(); + final int bottomPadding = Math.max(mIndicationBottomPadding, mAmbientIndicationBottomPadding); mClockPositionAlgorithm.setup( - mStatusBar.getMaxNotificationsWhileLocked(), - getMaxPanelHeight(), + mStatusBarMinHeight, + totalHeight - bottomPadding, + calculatePanelHeightShade() - mNotificationStackScroller.getTopPadding(), getExpandedHeight(), - mNotificationStackScroller.getNotGoneChildCount(), - getHeight(), + getMaxPanelHeight(), + totalHeight, mKeyguardStatusView.getHeight(), - mEmptyDragAmount, - mKeyguardStatusView.getClockBottom(), mDarkAmount); mClockPositionAlgorithm.run(mClockPositionResult); if (animate || mClockAnimator != null) { @@ -478,14 +479,16 @@ public class NotificationPanelView extends PanelView implements mKeyguardStatusView.setX(mClockPositionResult.clockX); mKeyguardStatusView.setY(mClockPositionResult.clockY); } - updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale); + updateClock(); stackScrollerPadding = mClockPositionResult.stackScrollerPadding; - mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment; } mNotificationStackScroller.setIntrinsicPadding(stackScrollerPadding); mNotificationStackScroller.setAntiBurnInOffsetX(mClockPositionResult.clockX); mKeyguardBottomArea.setBurnInXOffset(mClockPositionResult.clockX); + + mStackScrollerMeasuringPass++; requestScrollerTopPaddingUpdate(animate); + mStackScrollerMeasuringPass = 0; } /** @@ -493,8 +496,7 @@ public class NotificationPanelView extends PanelView implements * @return the maximum keyguard notifications that can fit on the screen */ public int computeMaxKeyguardNotifications(int maximum) { - float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding(getHeight(), - mKeyguardStatusView.getHeight()); + float minPadding = mClockPositionAlgorithm.getMinStackScrollerPadding(); int notificationPadding = Math.max(1, getResources().getDimensionPixelSize( R.dimen.notification_divider_height)); NotificationShelf shelf = mNotificationStackScroller.getNotificationShelf(); @@ -579,12 +581,10 @@ public class NotificationPanelView extends PanelView implements }); } - private void updateClock(float alpha, float scale) { + private void updateClock() { if (!mKeyguardStatusViewAnimating) { - mKeyguardStatusView.setAlpha(alpha * mQsClockAlphaOverride); + mKeyguardStatusView.setAlpha(mClockPositionResult.clockAlpha * mQsClockAlphaOverride); } - mKeyguardStatusView.setScaleX(scale); - mKeyguardStatusView.setScaleY(scale); } public void animateToFullShade(long delay) { @@ -1316,7 +1316,7 @@ public class NotificationPanelView extends PanelView implements newClockAlpha = 1 - MathUtils.constrain(newClockAlpha, 0, 1); if (newClockAlpha != mQsClockAlphaOverride) { mQsClockAlphaOverride = Interpolators.ALPHA_OUT.getInterpolation(newClockAlpha); - updateClock(mClockPositionResult.clockAlpha, mClockPositionResult.clockScale); + updateClock(); } if (mAccessibilityManager.isEnabled()) { @@ -1356,15 +1356,15 @@ public class NotificationPanelView extends PanelView implements && (mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted)) { // Either QS pushes the notifications down when fully expanded, or QS is fully above the - // notifications (mostly on tablets). maxNotifications denotes the normal top padding - // on Keyguard, maxQs denotes the top padding from the quick settings panel. We need to - // take the maximum and linearly interpolate with the panel expansion for a nice motion. - int maxNotifications = mClockPositionResult.stackScrollerPadding - - mClockPositionResult.stackScrollerPaddingAdjustment; - int maxQs = mQsMaxExpansionHeight + mQsNotificationTopPadding; + // notifications (mostly on tablets). maxNotificationPadding denotes the normal top + // padding on Keyguard, maxQsPadding denotes the top padding from the quick settings + // panel. We need to take the maximum and linearly interpolate with the panel expansion + // for a nice motion. + int maxNotificationPadding = mClockPositionResult.stackScrollerPadding; + int maxQsPadding = mQsMaxExpansionHeight + mQsNotificationTopPadding; int max = mStatusBarState == StatusBarState.KEYGUARD - ? Math.max(maxNotifications, maxQs) - : maxQs; + ? Math.max(maxNotificationPadding, maxQsPadding) + : maxQsPadding; return (int) interpolate(getExpandedFraction(), mQsMinExpansionHeight, max); } else if (mQsSizeChangeAnimator != null) { @@ -1507,7 +1507,7 @@ public class NotificationPanelView extends PanelView implements if (mQsExpandImmediate || mQsExpanded || mIsExpanding && mQsExpandedWhenExpandingStarted) { maxHeight = calculatePanelHeightQsExpanded(); } else { - maxHeight = calculatePanelHeightShade(); + maxHeight = Math.max(calculatePanelHeightShade(), calculatePanelHeightShadeExpanded()); } maxHeight = Math.max(maxHeight, min); return maxHeight; @@ -1524,7 +1524,15 @@ public class NotificationPanelView extends PanelView implements @Override protected void onHeightUpdated(float expandedHeight) { if (!mQsExpanded || mQsExpandImmediate || mIsExpanding && mQsExpandedWhenExpandingStarted) { - positionClockAndNotifications(); + // Updating the clock position will set the top padding which might + // trigger a new panel height and re-position the clock. + // This is a circular dependency and should be avoided, otherwise we'll have + // a stack overflow. + if (mStackScrollerMeasuringPass > 2) { + if (DEBUG) Log.d(TAG, "Unstable notification panel height. Aborting."); + } else { + positionClockAndNotifications(); + } } if (mQsExpandImmediate || mQsExpanded && !mQsTracking && mQsExpansionAnimator == null && !mQsExpansionFromOverscroll) { @@ -1568,12 +1576,18 @@ public class NotificationPanelView extends PanelView implements private int calculatePanelHeightShade() { int emptyBottomMargin = mNotificationStackScroller.getEmptyBottomMargin(); - int maxHeight = mNotificationStackScroller.getHeight() - emptyBottomMargin - - mTopPaddingAdjustment; + int maxHeight = mNotificationStackScroller.getHeight() - emptyBottomMargin; maxHeight += mNotificationStackScroller.getTopPaddingOverflow(); return maxHeight; } + private int calculatePanelHeightShadeExpanded() { + return mNotificationStackScroller.getHeight() + - mNotificationStackScroller.getEmptyBottomMargin() + - mNotificationStackScroller.getTopPadding() + + mClockPositionAlgorithm.getExpandedClockBottom(); + } + private int calculatePanelHeightQsExpanded() { float notificationHeight = mNotificationStackScroller.getHeight() - mNotificationStackScroller.getEmptyBottomMargin() @@ -1598,8 +1612,7 @@ public class NotificationPanelView extends PanelView implements } float totalHeight = Math.max( maxQsHeight, mStatusBarState == StatusBarState.KEYGUARD - ? mClockPositionResult.stackScrollerPadding - mTopPaddingAdjustment - : 0) + ? mClockPositionResult.stackScrollerPadding : 0) + notificationHeight + mNotificationStackScroller.getTopPaddingOverflow(); if (totalHeight > mNotificationStackScroller.getHeight()) { float fullyCollapsedHeight = maxQsHeight @@ -2272,8 +2285,9 @@ public class NotificationPanelView extends PanelView implements } @Override - protected void dispatchDraw(Canvas canvas) { - super.dispatchDraw(canvas); + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + if (DEBUG) { Paint p = new Paint(); p.setColor(Color.RED); @@ -2288,6 +2302,9 @@ public class NotificationPanelView extends PanelView implements p.setColor(Color.YELLOW); canvas.drawLine(0, calculatePanelHeightShade(), getWidth(), calculatePanelHeightShade(), p); + p.setColor(Color.GRAY); + canvas.drawLine(0, calculatePanelHeightShadeExpanded(), getWidth(), + calculatePanelHeightShadeExpanded(), p); p.setColor(Color.MAGENTA); canvas.drawLine(0, calculateQsTopPadding(), getWidth(), calculateQsTopPadding(), p); |