Alignment of clock and shade

Test: visual
Change-Id: If7ff8c34a5053d5df8f6dc38c53cc728fef89ede
Fixes: 72968018
Fixes: 72417398
Fixes: 73087486
Fixes: 72566197
This commit is contained in:
Lucas Dupin
2018-02-18 19:39:32 -08:00
parent 99ef04f717
commit 41ff695104
17 changed files with 192 additions and 349 deletions

View File

@@ -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"

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -437,15 +437,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>
@@ -883,9 +878,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>

View File

@@ -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;
/**
* Height of notification stack: Sum of height of each notification.
*/
private int mNotificationStackHeight;
/**
* Minimum top margin to avoid overlap with status bar.
*/
private int mMinTopMargin;
/**
* Maximum bottom padding to avoid overlap with {@link KeyguardBottomAreaView} or
* the ambient indication.
*/
private int mMaxShadeBottom;
/**
* Margin that we should respect within the available space.
*/
private int mContainerPadding;
/**
* 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;
/**
* The number (fractional) of notifications the "more" card counts when calculating how many
* notifications are currently visible for the y positioning of the clock.
* Doze/AOD transition amount.
*/
private float mMoreCardNotificationAmount;
private static final PathInterpolator sSlowDownInterpolator;
static {
Path path = new Path();
path.moveTo(0, 0);
path.cubicTo(0.3f, 0.875f, 0.6f, 1f, 1f, 1f);
sSlowDownInterpolator = new PathInterpolator(path);
}
private AccelerateInterpolator mAccelerateInterpolator = new AccelerateInterpolator();
private int mClockBottom;
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 float getClockYFraction() {
float t = getNotificationAmountT();
t = Math.min(t, 1.0f);
return MathUtils.lerp(mClockYFractionMax, mClockYFractionMin, t);
private int getMaxClockY() {
return mHeight / 2 - mKeyguardStatusHeight - mClockNotificationsMargin;
}
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,62 +234,18 @@ 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 x translation of the clock.
*/
public int clockX;
/**
* The y translation of the clock.
*/
public int clockY;
/**
* The scale of the Clock
*/
public float clockScale;
/**
* 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;
}
}

View File

@@ -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);