Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b37637b6 authored by Jorim Jaggi's avatar Jorim Jaggi Committed by Android (Google) Code Review
Browse files

Merge "Move clock and top padding while dismissing Keyguard."

parents 5c013261 afc11f19
Loading
Loading
Loading
Loading
+186 −0
Original line number Diff line number Diff line
/*
 * 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.res.Resources;
import android.graphics.Path;
import android.view.animation.PathInterpolator;

import com.android.systemui.R;

/**
 * Utility class to calculate the clock position and top padding of notifications on Keyguard.
 */
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_ADJ_TOP_PADDING_MULTIPLIER_MIN = 1.4f;
    private static final float CLOCK_ADJ_TOP_PADDING_MULTIPLIER_MAX = 3.2f;

    private int mClockNotificationsMarginMin;
    private int mClockNotificationsMarginMax;
    private float mClockYFractionMin;
    private float mClockYFractionMax;
    private int mMaxKeyguardNotifications;
    private int mMaxPanelHeight;
    private float mExpandedHeight;
    private int mNotificationCount;
    private int mHeight;
    private int mKeyguardStatusHeight;

    /**
     * The number (fractional) of notifications the "more" card counts when calculating how many
     * notifications are currently visible for the y positioning of the clock.
     */
    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);
    }

    /**
     * Refreshes the dimension values.
     */
    public void loadDimens(Resources res) {
        mClockNotificationsMarginMin = res.getDimensionPixelSize(
                R.dimen.keyguard_clock_notifications_margin_min);
        mClockNotificationsMarginMax = res.getDimensionPixelSize(
                R.dimen.keyguard_clock_notifications_margin_max);
        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_summary_height) /
                        res.getDimensionPixelSize(R.dimen.notification_min_height);
    }

    public void setup(int maxKeyguardNotifications, int maxPanelHeight, float expandedHeight,
            int notificationCount, int height, int keyguardStatusHeight) {
        mMaxKeyguardNotifications = maxKeyguardNotifications;
        mMaxPanelHeight = maxPanelHeight;
        mExpandedHeight = expandedHeight;
        mNotificationCount = notificationCount;
        mHeight = height;
        mKeyguardStatusHeight = keyguardStatusHeight;
    }

    public void run(Result result) {
        int y = getClockY() - mKeyguardStatusHeight/2;
        float clockAdjustment = getClockYExpansionAdjustment();
        float topPaddingAdjMultiplier = getTopPaddingAdjMultiplier();
        result.stackScrollerPaddingAdjustment = (int) (clockAdjustment*topPaddingAdjMultiplier);
        int clockNotificationsPadding = getClockNotificationsPadding()
                + result.stackScrollerPaddingAdjustment;
        int padding = y + clockNotificationsPadding;
        y += clockAdjustment;
        result.clockY = y;
        result.stackScrollerPadding = mKeyguardStatusHeight + padding;
        result.clockAlpha = getClockAlpha(result.stackScrollerPadding
                - (y + mKeyguardStatusHeight));
    }

    private int getClockNotificationsPadding() {
        float t = getNotificationAmountT();
        t = Math.min(t, 1.0f);
        return (int) (t * mClockNotificationsMarginMin + (1 - t) * mClockNotificationsMarginMax);
    }

    private float getClockYFraction() {
        float t = getNotificationAmountT();
        t = Math.min(t, 1.0f);
        return (1 - t) * mClockYFractionMax + t * mClockYFractionMin;
    }

    private int getClockY() {
        return (int) (getClockYFraction() * mHeight);
    }

    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(int clockNotificationPadding) {
        float t = getNotificationAmountT();
        t = (float) Math.pow(t, 0.3f);
        float multiplier = 1 + 2 * (1 - t);
        float alpha = 1 + (float) clockNotificationPadding * multiplier / mKeyguardStatusHeight * 3;
        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.
         */
        public int clockY;

        /**
         * The alpha value of the clock.
         */
        public float clockAlpha;

        /**
         * 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;
    }
}
+35 −45
Original line number Diff line number Diff line
@@ -19,10 +19,11 @@ package com.android.systemui.statusbar.phone;
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.content.Context;
import android.graphics.Path;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.VelocityTracker;
import android.view.View;
@@ -31,6 +32,7 @@ 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;
@@ -82,19 +84,14 @@ public class NotificationPanelView extends PanelView implements
    private FlingAnimationUtils mFlingAnimationUtils;
    private int mStatusBarMinHeight;

    private int mClockNotificationsMarginMin;
    private int mClockNotificationsMarginMax;
    private float mClockYFractionMin;
    private float mClockYFractionMax;
    private Interpolator mFastOutSlowInInterpolator;
    private ObjectAnimator mClockAnimator;
    private int mClockAnimationTarget = -1;

    /**
     * The number (fractional) of notifications the "more" card counts when calculating how many
     * notifications are currently visible for the y positioning of the clock.
     */
    private float mMoreCardNotificationAmount;
    private int mTopPaddingAdjustment;
    private KeyguardClockPositionAlgorithm mClockPositionAlgorithm =
            new KeyguardClockPositionAlgorithm();
    private KeyguardClockPositionAlgorithm.Result mClockPositionResult =
            new KeyguardClockPositionAlgorithm.Result();

    public NotificationPanelView(Context context, AttributeSet attrs) {
        super(context, attrs);
@@ -139,20 +136,10 @@ public class NotificationPanelView extends PanelView implements
        mNotificationTopPadding = getResources().getDimensionPixelSize(
                R.dimen.notifications_top_padding);
        mMinStackHeight = getResources().getDimensionPixelSize(R.dimen.collapsed_stack_height);
        mClockNotificationsMarginMin = getResources().getDimensionPixelSize(
                R.dimen.keyguard_clock_notifications_margin_min);
        mClockNotificationsMarginMax = getResources().getDimensionPixelSize(
                R.dimen.keyguard_clock_notifications_margin_max);
        mClockYFractionMin =
                getResources().getFraction(R.fraction.keyguard_clock_y_fraction_min, 1, 1);
        mClockYFractionMax =
                getResources().getFraction(R.fraction.keyguard_clock_y_fraction_max, 1, 1);
        mMoreCardNotificationAmount =
                (float) getResources().getDimensionPixelSize(R.dimen.notification_summary_height) /
                        getResources().getDimensionPixelSize(R.dimen.notification_min_height);
        mFlingAnimationUtils = new FlingAnimationUtils(getContext(), 0.4f);
        mStatusBarMinHeight = getResources().getDimensionPixelSize(
                com.android.internal.R.dimen.status_bar_height);
        mClockPositionAlgorithm.loadDimens(getResources());
    }

    @Override
@@ -160,6 +147,7 @@ public class NotificationPanelView extends PanelView implements
        super.onLayout(changed, left, top, right, bottom);
        if (!mQsExpanded) {
            positionClockAndNotifications();
            mNotificationStackScroller.setStackHeight(getExpandedHeight());
        }

        // Calculate quick setting heights.
@@ -178,16 +166,24 @@ public class NotificationPanelView extends PanelView implements
        boolean animateClock = mNotificationStackScroller.isAddOrRemoveAnimationPending();
        if (mStatusBar.getBarState() != StatusBarState.KEYGUARD) {
            mStackScrollerIntrinsicPadding = mHeader.getBottom() + mNotificationTopPadding;
            mTopPaddingAdjustment = 0;
        } else {
            int notificationCount = mNotificationStackScroller.getNotGoneChildCount();
            int y = getClockY(notificationCount) - mKeyguardStatusView.getHeight()/2;
            int padding = getClockNotificationsPadding(notificationCount);
            mClockPositionAlgorithm.setup(
                    mStatusBar.getMaxKeyguardNotifications(),
                    getMaxPanelHeight(),
                    getExpandedHeight(),
                    mNotificationStackScroller.getNotGoneChildCount(),
                    getHeight(),
                    mKeyguardStatusView.getHeight());
            mClockPositionAlgorithm.run(mClockPositionResult);
            if (animateClock || mClockAnimator != null) {
                startClockAnimation(y);
                startClockAnimation(mClockPositionResult.clockY);
            } else {
                mKeyguardStatusView.setY(y);
                mKeyguardStatusView.setY(mClockPositionResult.clockY);
            }
            mStackScrollerIntrinsicPadding = y + mKeyguardStatusView.getHeight() + padding;
            applyClockAlpha(mClockPositionResult.clockAlpha);
            mStackScrollerIntrinsicPadding = mClockPositionResult.stackScrollerPadding;
            mTopPaddingAdjustment = mClockPositionResult.stackScrollerPaddingAdjustment;
        }
        mNotificationStackScroller.setTopPadding(mStackScrollerIntrinsicPadding,
                mAnimateNextTopPaddingChange || animateClock);
@@ -224,22 +220,13 @@ public class NotificationPanelView extends PanelView implements
        });
    }

    private int getClockNotificationsPadding(int notificationCount) {
        float t = notificationCount
                / (mStatusBar.getMaxKeyguardNotifications() + mMoreCardNotificationAmount);
        t = Math.min(t, 1.0f);
        return (int) (t * mClockNotificationsMarginMin + (1 - t) * mClockNotificationsMarginMax);
    }

    private float getClockYFraction(int notificationCount) {
        float t = notificationCount
                / (mStatusBar.getMaxKeyguardNotifications() + mMoreCardNotificationAmount);
        t = Math.min(t, 1.0f);
        return (1 - t) * mClockYFractionMax + t * mClockYFractionMin;
    private void applyClockAlpha(float alpha) {
        if (alpha != 1.0f) {
            mKeyguardStatusView.setLayerType(LAYER_TYPE_HARDWARE, null);
        } else {
            mKeyguardStatusView.setLayerType(LAYER_TYPE_NONE, null);
        }

    private int getClockY(int notificationCount) {
        return (int) (getClockYFraction(notificationCount) * getHeight());
        mKeyguardStatusView.setAlpha(alpha);
    }

    public void animateToFullShade() {
@@ -626,7 +613,7 @@ public class NotificationPanelView extends PanelView implements
        int emptyBottomMargin = mStackScrollerContainer.getHeight()
                - mNotificationStackScroller.getHeight()
                + mNotificationStackScroller.getEmptyBottomMargin();
        int maxHeight = maxPanelHeight - emptyBottomMargin;
        int maxHeight = maxPanelHeight - emptyBottomMargin - mTopPaddingAdjustment;
        maxHeight = Math.max(maxHeight, mStatusBarMinHeight);
        return maxHeight;
    }
@@ -637,6 +624,9 @@ public class NotificationPanelView extends PanelView implements

    @Override
    protected void onHeightUpdated(float expandedHeight) {
        if (!mQsExpanded) {
            positionClockAndNotifications();
        }
        mNotificationStackScroller.setStackHeight(expandedHeight);
    }

+1 −1
Original line number Diff line number Diff line
@@ -402,7 +402,7 @@ public class PanelView extends FrameLayout {

    public void setExpandedHeightInternal(float h) {
        float fh = getMaxPanelHeight();
        mExpandedHeight = h;
        mExpandedHeight = Math.min(fh, h);

        if (DEBUG) {
            logf("setExpansion: height=%.1f fh=%.1f tracking=%s", h, fh, mTracking ? "T" : "f");