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

Commit 173bae2c authored by Daniel Sandler's avatar Daniel Sandler
Browse files

Improvements to notification/settings panels:

A) Hide icons corresponding to the active panel with a
   downward push animation. Notes:
   1. this animation will now apply any time the status bar
	  icons are disabled via DISABLE_NOTIFICATION_ICONS.
   2. DISABLE_SYSTEM_INFO will now only hide the right hand
      icons (system status icons, battery, clock). But you
	  weren't using it anyway, right?

B) Stop pulling down the panels in response to just a touch
   on the status bar. (That should never have worked.) In
   general, we now require that a fling proceed more than
   10dp to be treated as a fling with velocity (as opposed
   to a v=0 fling, or "let-go").

C) If a panel is pulled down more than halfway and then let
   go with v=0, it is expanded. If less than halfway, it is
   contracted. (Helps fix B) above, plus it just makes good
   sense.)

Bug: 7211541 (A)
Bug: 7227237 (B)
Bug: 7228541 (B)
Change-Id: I5662269b753376804bf629239835dc212716d5c3
parent a8a7e714
Loading
Loading
Loading
Loading
+38 −32
Original line number Diff line number Diff line
@@ -41,7 +41,7 @@
        android:visibility="gone"
        />

    <LinearLayout android:id="@+id/icons"
    <LinearLayout android:id="@+id/status_bar_contents"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:paddingLeft="6dip"
@@ -71,6 +71,11 @@
                android:orientation="horizontal"/>  
        </LinearLayout>

        <LinearLayout android:id="@+id/system_icon_area"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <LinearLayout android:id="@+id/statusIcons"
                android:layout_width="wrap_content"
                android:layout_height="match_parent"
@@ -108,6 +113,7 @@
                android:gravity="center_vertical|left"
                />
        </LinearLayout>
    </LinearLayout>
        
    <LinearLayout android:id="@+id/ticker"
        android:layout_width="match_parent"
+3 −0
Original line number Diff line number Diff line
@@ -107,6 +107,9 @@
    <!-- Cap on overall resulting fling speed (s^-1) -->
    <dimen name="fling_gesture_max_output_velocity">3000dp</dimen>

    <!-- Minimum distance a fling must travel (anti-jitter) -->
    <dimen name="fling_gesture_min_dist">10dp</dimen>

    <!-- Minimum fraction of the display a gesture must travel, at any velocity, to qualify as a
         collapse request -->
    <item type="dimen" name="collapse_min_display_fraction">10%</item>
+8 −0
Original line number Diff line number Diff line
@@ -6,6 +6,7 @@ import android.content.Context;
import android.util.AttributeSet;
import android.util.Slog;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

public class PanelBar extends FrameLayout {
@@ -101,6 +102,7 @@ public class PanelBar extends FrameLayout {
        PanelView fullyOpenedPanel = null;
        LOG("panelExpansionChanged: start state=%d panel=%s", mState, panel.getName());
        for (PanelView pv : mPanels) {
            final boolean visible = pv.getVisibility() == View.VISIBLE;
            // adjust any other panels that may be partially visible
            if (pv.getExpandedHeight() > 0f) {
                if (mState == STATE_CLOSED) {
@@ -116,6 +118,11 @@ public class PanelBar extends FrameLayout {
                    pv.setExpandedFraction(1f-frac);
                }
            }
            if (pv.getExpandedHeight() > 0f) {
                if (!visible) pv.setVisibility(View.VISIBLE);
            } else {
                if (visible) pv.setVisibility(View.GONE);
            }
        }
        if (fullyOpenedPanel != null && !mTracking) {
            go(STATE_OPEN);
@@ -138,6 +145,7 @@ public class PanelBar extends FrameLayout {
            } else {
                pv.setExpandedFraction(0); // just in case
            }
            pv.setVisibility(View.GONE);
        }
        if (!waiting) {
            // it's possible that nothing animated, so we replicate the termination 
+27 −2
Original line number Diff line number Diff line
@@ -37,6 +37,8 @@ public class PanelView extends FrameLayout {
    private float mExpandMinDisplayFraction; // classic value: 0.5 (drag open halfway to expand)
    private float mFlingGestureMaxXVelocityPx; // classic value: 150px/s

    private float mFlingGestureMinDistPx;

    private float mExpandAccelPx; // classic value: 2000px/s/s
    private float mCollapseAccelPx; // classic value: 2000px/s/s (will be negated to collapse "up")

@@ -78,6 +80,8 @@ public class PanelView extends FrameLayout {
    private float mVel, mAccel;
    private int mFullHeight = 0;
    private String mViewName;
    protected float mInitialTouchY;
    protected float mFinalTouchY;

    private void animationTick(long dtms) {
        if (!mTimeAnimator.isStarted()) {
@@ -88,7 +92,14 @@ public class PanelView extends FrameLayout {
            mTimeAnimator.start();
            
            mRubberbanding = STRETCH_PAST_CONTENTS && mExpandedHeight > getFullHeight();
            mClosing = (mExpandedHeight > 0 && mVel < 0) || mRubberbanding;
            if (mRubberbanding) {
                mClosing = true;
            } else if (mVel == 0) {
                // if the panel is less than halfway open, close it 
                mClosing = (mFinalTouchY / getFullHeight()) < 0.5f;
            } else {
                mClosing = mExpandedHeight > 0 && mVel < 0;
            }
        } else if (dtms > 0) {
            final float dt = dtms * 0.001f;                  // ms -> s
            LOG("tick: v=%.2fpx/s dt=%.4fs", mVel, dt);
@@ -159,6 +170,8 @@ public class PanelView extends FrameLayout {
        mFlingExpandMinVelocityPx = res.getDimension(R.dimen.fling_expand_min_velocity);
        mFlingCollapseMinVelocityPx = res.getDimension(R.dimen.fling_collapse_min_velocity);

        mFlingGestureMinDistPx = res.getDimension(R.dimen.fling_gesture_min_dist);

        mCollapseMinDisplayFraction = res.getFraction(R.dimen.collapse_min_display_fraction, 1, 1);
        mExpandMinDisplayFraction = res.getFraction(R.dimen.expand_min_display_fraction, 1, 1);

@@ -207,6 +220,7 @@ public class PanelView extends FrameLayout {
                    switch (event.getAction()) {
                        case MotionEvent.ACTION_DOWN:
                            mTracking = true;
                            mInitialTouchY = y;
                            mVelocityTracker = VelocityTracker.obtain();
                            trackMovement(event);
                            mBar.onTrackingStarted(PanelView.this);
@@ -223,6 +237,7 @@ public class PanelView extends FrameLayout {

                        case MotionEvent.ACTION_UP:
                        case MotionEvent.ACTION_CANCEL:
                            mFinalTouchY = y;
                            mTracking = false;
                            mBar.onTrackingStopped(PanelView.this);
                            trackMovement(event);
@@ -243,11 +258,21 @@ public class PanelView extends FrameLayout {
                            if (vel > mFlingGestureMaxOutputVelocityPx) {
                                vel = mFlingGestureMaxOutputVelocityPx;
                            }

                            // if you've barely moved your finger, we treat the velocity as 0
                            // preventing spurious flings due to touch screen jitter
                            final float deltaY = (float)Math.abs(mFinalTouchY - mInitialTouchY);
                            if (deltaY < mFlingGestureMinDistPx
                                    || vel < mFlingGestureMinDistPx) {
                                vel = 0;
                            }

                            if (negative) {
                                vel = -vel;
                            }

                            LOG("gesture: vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f",
                            LOG("gesture: dy=%f vraw=(%f,%f) vnorm=(%f,%f) vlinear=%f",
                                    deltaY,
                                    mVelocityTracker.getXVelocity(),
                                    mVelocityTracker.getYVelocity(),
                                    xVel, yVel,
+48 −84
Original line number Diff line number Diff line
@@ -153,11 +153,18 @@ public class PhoneStatusBar extends BaseStatusBar {
    int mPixelFormat;
    Object mQueueLock = new Object();

    // icons
    LinearLayout mIcons;
    // viewgroup containing the normal contents of the statusbar
    LinearLayout mStatusBarContents;
    
    // right-hand icons
    LinearLayout mSystemIconArea;
    
    // left-hand icons 
    LinearLayout mStatusIcons;
    // the icons themselves
    IconMerger mNotificationIcons;
    // [+>
    View mMoreIcon;
    LinearLayout mStatusIcons;

    // expanded notifications
    PanelView mNotificationPanel; // the sliding/resizing panel within the notification window
@@ -226,8 +233,8 @@ public class PhoneStatusBar extends BaseStatusBar {
    int[] mAbsPos = new int[2];
    Runnable mPostCollapseCleanup = null;

    private AnimatorSet mLightsOutAnimation;
    private AnimatorSet mLightsOnAnimation;
    private Animator mLightsOutAnimation;
    private Animator mLightsOnAnimation;

    // for disabling the status bar
    int mDisabled = 0;
@@ -245,9 +252,9 @@ public class PhoneStatusBar extends BaseStatusBar {
        @Override
        public void onAnimationEnd(Animator animation) {
            // double-check to avoid races
            if (mIcons.getAlpha() == 0) {
            if (mStatusBarContents.getAlpha() == 0) {
                Slog.d(TAG, "makeIconsInvisible");
                mIcons.setVisibility(View.INVISIBLE);
                mStatusBarContents.setVisibility(View.INVISIBLE);
            }
        }
    };
@@ -307,8 +314,7 @@ public class PhoneStatusBar extends BaseStatusBar {
        mNotificationPanelIsFullScreenWidth =
            (mNotificationPanel.getLayoutParams().width == ViewGroup.LayoutParams.MATCH_PARENT);
        mNotificationPanel.setSystemUiVisibility(
                  View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER
                | (mNotificationPanelIsFullScreenWidth ? 0 : View.STATUS_BAR_DISABLE_SYSTEM_INFO));
                  View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | View.STATUS_BAR_DISABLE_NOTIFICATION_ICONS);

        if (!ActivityManager.isHighEndGfx()) {
            mStatusBarWindow.setBackground(null);
@@ -343,10 +349,12 @@ public class PhoneStatusBar extends BaseStatusBar {

        // figure out which pixel-format to use for the status bar.
        mPixelFormat = PixelFormat.OPAQUE;

        mSystemIconArea = (LinearLayout) mStatusBarView.findViewById(R.id.system_icon_area);
        mStatusIcons = (LinearLayout)mStatusBarView.findViewById(R.id.statusIcons);
        mNotificationIcons = (IconMerger)mStatusBarView.findViewById(R.id.notificationIcons);
        mNotificationIcons.setOverflowIndicator(mMoreIcon);
        mIcons = (LinearLayout)mStatusBarView.findViewById(R.id.icons);
        mStatusBarContents = (LinearLayout)mStatusBarView.findViewById(R.id.status_bar_contents);
        mTickerView = mStatusBarView.findViewById(R.id.ticker);

        mPile = (NotificationRowLayout)mStatusBarWindow.findViewById(R.id.latestItems);
@@ -431,6 +439,8 @@ public class PhoneStatusBar extends BaseStatusBar {
        mSettingsPanel.setService(this);
        mSettingsPanel.setup(mNetworkController, mBluetoothController, mBatteryController,
                mLocationController);
        mSettingsPanel.setSystemUiVisibility(
                View.STATUS_BAR_DISABLE_NOTIFICATION_TICKER | View.STATUS_BAR_DISABLE_SYSTEM_INFO);

        if (!ActivityManager.isHighEndGfx()) {
            mSettingsPanel.setBackground(new FastColorDrawable(context.getResources().getColor(
@@ -1016,22 +1026,18 @@ public class PhoneStatusBar extends BaseStatusBar {
        Slog.d(TAG, flagdbg.toString());

        if ((diff & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
            mIcons.animate().cancel();
            mSystemIconArea.animate().cancel();
            if ((state & StatusBarManager.DISABLE_SYSTEM_INFO) != 0) {
                if (mTicking) {
                    mTicker.halt();
                }
                mIcons.animate()
                mSystemIconArea.animate()
                    .alpha(0f)
                    .translationY(mNaturalBarHeight*0.5f)
                    //.setStartDelay(100)
                    .setDuration(175)
                    .setInterpolator(new DecelerateInterpolator(1.5f))
                    .setListener(mMakeIconsInvisible)
                    .start();
            } else {
                mIcons.setVisibility(View.VISIBLE);
                mIcons.animate()
                mSystemIconArea.setVisibility(View.VISIBLE);
                mSystemIconArea.animate()
                    .alpha(1f)
                    .translationY(0)
                    .setStartDelay(0)
@@ -1068,13 +1074,24 @@ public class PhoneStatusBar extends BaseStatusBar {
            if ((state & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
                if (mTicking) {
                    mTicker.halt();
                } else {
                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
                }

                mNotificationIcons.animate()
                    .alpha(0f)
                    .translationY(mNaturalBarHeight*0.5f)
                    .setDuration(175)
                    .setInterpolator(new DecelerateInterpolator(1.5f))
                    .setListener(mMakeIconsInvisible)
                    .start();
            } else {
                if (!mExpandedVisible) {
                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
                }
                mNotificationIcons.setVisibility(View.VISIBLE);
                mNotificationIcons.animate()
                    .alpha(1f)
                    .translationY(0)
                    .setStartDelay(0)
                    .setInterpolator(new DecelerateInterpolator(1.5f))
                    .setDuration(175)
                    .start();
            }
        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
            if (mTicking && (state & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
@@ -1340,30 +1357,11 @@ public class PhoneStatusBar extends BaseStatusBar {

    private void setStatusBarLowProfile(boolean lightsOut) {
        if (mLightsOutAnimation == null) {
            final View notifications = mStatusBarView.findViewById(R.id.notification_icon_area);
            final View systemIcons = mStatusBarView.findViewById(R.id.statusIcons);
            final View signal = mStatusBarView.findViewById(R.id.signal_cluster);
            final View battery = mStatusBarView.findViewById(R.id.battery);
            final View clock = mStatusBarView.findViewById(R.id.clock);

            mLightsOutAnimation = new AnimatorSet();
            mLightsOutAnimation.playTogether(
                    ObjectAnimator.ofFloat(notifications, View.ALPHA, 0),
                    ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 0),
                    ObjectAnimator.ofFloat(signal, View.ALPHA, 0),
                    ObjectAnimator.ofFloat(battery, View.ALPHA, 0.5f),
                    ObjectAnimator.ofFloat(clock, View.ALPHA, 0.5f)
                );
            mLightsOutAnimation = ObjectAnimator.ofFloat(mStatusBarContents, View.ALPHA, 0);
            mLightsOutAnimation.setDuration(750);

            mLightsOnAnimation = new AnimatorSet();
            mLightsOnAnimation.playTogether(
                    ObjectAnimator.ofFloat(notifications, View.ALPHA, 1),
                    ObjectAnimator.ofFloat(systemIcons, View.ALPHA, 1),
                    ObjectAnimator.ofFloat(signal, View.ALPHA, 1),
                    ObjectAnimator.ofFloat(battery, View.ALPHA, 1),
                    ObjectAnimator.ofFloat(clock, View.ALPHA, 1)
                );
            mLightsOnAnimation = ObjectAnimator.ofFloat(mStatusBarContents, View.ALPHA, 1);
            mLightsOnAnimation.setDuration(250);
        }

@@ -1453,25 +1451,25 @@ public class PhoneStatusBar extends BaseStatusBar {
        @Override
        public void tickerStarting() {
            mTicking = true;
            mIcons.setVisibility(View.GONE);
            mStatusBarContents.setVisibility(View.GONE);
            mTickerView.setVisibility(View.VISIBLE);
            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_up_in, null));
            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
            mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_up_out, null));
        }

        @Override
        public void tickerDone() {
            mIcons.setVisibility(View.VISIBLE);
            mStatusBarContents.setVisibility(View.VISIBLE);
            mTickerView.setVisibility(View.GONE);
            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
            mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.push_down_in, null));
            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.push_down_out,
                        mTickingDoneListener));
        }

        public void tickerHalting() {
            mIcons.setVisibility(View.VISIBLE);
            mStatusBarContents.setVisibility(View.VISIBLE);
            mTickerView.setVisibility(View.GONE);
            mIcons.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
            mStatusBarContents.startAnimation(loadAnim(com.android.internal.R.anim.fade_in, null));
            mTickerView.startAnimation(loadAnim(com.android.internal.R.anim.fade_out,
                        mTickingDoneListener));
        }
@@ -1649,40 +1647,6 @@ public class PhoneStatusBar extends BaseStatusBar {
                String.format("%dx%d", mDisplayMetrics.widthPixels, mDisplayMetrics.heightPixels));
    }

    void performDisableActions(int net) {
        int old = mDisabled;
        int diff = net ^ old;
        mDisabled = net;

        // act accordingly
        if ((diff & StatusBarManager.DISABLE_EXPAND) != 0) {
            if ((net & StatusBarManager.DISABLE_EXPAND) != 0) {
                Slog.d(TAG, "DISABLE_EXPAND: yes");
                animateCollapse();
            }
        }
        if ((diff & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
            if ((net & StatusBarManager.DISABLE_NOTIFICATION_ICONS) != 0) {
                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: yes");
                if (mTicking) {
                    mNotificationIcons.setVisibility(View.INVISIBLE);
                    mTicker.halt();
                } else {
                    setNotificationIconVisibility(false, com.android.internal.R.anim.fade_out);
                }
            } else {
                Slog.d(TAG, "DISABLE_NOTIFICATION_ICONS: no");
                if (!mExpandedVisible) {
                    setNotificationIconVisibility(true, com.android.internal.R.anim.fade_in);
                }
            }
        } else if ((diff & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
            if (mTicking && (net & StatusBarManager.DISABLE_NOTIFICATION_TICKER) != 0) {
                mTicker.halt();
            }
        }
    }

    private View.OnClickListener mClearButtonListener = new View.OnClickListener() {
        public void onClick(View v) {
            synchronized (mNotificationData) {