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

Commit 2528351e authored by Roman Birg's avatar Roman Birg Committed by Gerrit Code Review
Browse files

SystemUI: improve circle battery



While plugged in, the circle animation would cause the statusbar to
keep redrawing itself repeatedly, using up unnecessary cpu cycles,
even when idle.

- Removed circle animation in status bar
- Left animations on keyguard/notificaiton header
- Set layer type to hardware when animating for optimized quick drawing
- Cleaned up some logic and unnecessary locking
- Removed extra work done in each draw
- override onDraw instead of draw to let the View system decide when we
  should draw

Change-Id: If0624ab6e3723f4522ebbd9ce583b142c1cb4606
Signed-off-by: default avatarRoman Birg <roman@cyngn.com>
parent 8662a906
Loading
Loading
Loading
Loading
+55 −75
Original line number Diff line number Diff line
@@ -31,7 +31,6 @@ import android.graphics.RectF;
import android.graphics.Typeface;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;

@@ -69,6 +68,8 @@ public class BatteryMeterView extends View implements DemoMode,
    private final int mCriticalLevel;
    private final int mFrameColor;

    private boolean mAnimationsEnabled;

    private final Path mShapePath = new Path();
    private final Path mClipPath = new Path();
    private final Path mTextPath = new Path();
@@ -77,8 +78,6 @@ public class BatteryMeterView extends View implements DemoMode,
    private BatteryController mBatteryController;
    private boolean mPowerSaveEnabled;

    private final Handler mHandler;

    protected BatteryMeterMode mMeterMode = null;

    protected boolean mAttached;
@@ -87,7 +86,6 @@ public class BatteryMeterView extends View implements DemoMode,
    protected BatteryTracker mDemoTracker = new BatteryTracker();
    protected BatteryTracker mTracker = new BatteryTracker();
    private BatteryMeterDrawable mBatteryMeterDrawable;
    private final Object mLock = new Object();

    protected class BatteryTracker extends BroadcastReceiver {
        public static final int UNKNOWN_LEVEL = -1;
@@ -128,11 +126,9 @@ public class BatteryMeterView extends View implements DemoMode,

                setContentDescription(
                        context.getString(R.string.accessibility_battery_level, level));
                synchronized (mLock) {
                if (mBatteryMeterDrawable != null) {
                    setVisibility(View.VISIBLE);
                        invalidateIfVisible();
                    }
                    invalidate();
                }
            } else if (action.equals(ACTION_LEVEL_TEST)) {
                testmode = true;
@@ -180,12 +176,6 @@ public class BatteryMeterView extends View implements DemoMode,
        }
    }

    private final Runnable mInvalidate = new Runnable() {
        public void run() {
            invalidateIfVisible();
        }
    };

    @Override
    public void onAttachedToWindow() {
        super.onAttachedToWindow();
@@ -225,7 +215,6 @@ public class BatteryMeterView extends View implements DemoMode,

    public BatteryMeterView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        mHandler = new Handler();

        final Resources res = context.getResources();
        TypedArray atts = context.obtainStyledAttributes(attrs, R.styleable.BatteryMeterView,
@@ -253,6 +242,8 @@ public class BatteryMeterView extends View implements DemoMode,
                R.fraction.battery_subpixel_smoothing_left, 1, 1);
        mSubpixelSmoothingRight = context.getResources().getFraction(
                R.fraction.battery_subpixel_smoothing_right, 1, 1);

        setAnimationsEnabled(true);
    }

    protected BatteryMeterDrawable createBatteryMeterDrawable(BatteryMeterMode mode) {
@@ -311,6 +302,14 @@ public class BatteryMeterView extends View implements DemoMode,
        invalidate();
    }

    public void setAnimationsEnabled(boolean enabled) {
        if (mAnimationsEnabled != enabled) {
            mAnimationsEnabled = enabled;
            setLayerType(mAnimationsEnabled ? LAYER_TYPE_HARDWARE : LAYER_TYPE_NONE, null);
            invalidate();
        }
    }

    @Override
    public void onBatteryStyleChanged(int style, int percentMode) {
        boolean showInsidePercent = percentMode == BatteryController.PERCENTAGE_MODE_INSIDE;
@@ -337,29 +336,18 @@ public class BatteryMeterView extends View implements DemoMode,

        setMode(meterMode);
        mShowPercent = showInsidePercent;
        invalidateIfVisible();
        invalidate();
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        mHeight = h;
        mWidth = w;
        synchronized (mLock) {
        if (mBatteryMeterDrawable != null) {
            mBatteryMeterDrawable.onSizeChanged(w, h, oldw, oldh);
        }
    }
    }

    protected void invalidateIfVisible() {
        if (getVisibility() == View.VISIBLE && mAttached) {
            if (mAttached) {
                postInvalidate();
            } else {
                invalidate();
            }
        }
    }

    public void setMode(BatteryMeterMode mode) {
        if (mMeterMode == mode) {
@@ -371,16 +359,12 @@ public class BatteryMeterView extends View implements DemoMode,
        if (mode == BatteryMeterMode.BATTERY_METER_GONE ||
                mode == BatteryMeterMode.BATTERY_METER_TEXT) {
            setVisibility(View.GONE);
            synchronized (mLock) {
            mBatteryMeterDrawable = null;
            }
        } else {
            synchronized (mLock) {
            if (mBatteryMeterDrawable != null) {
                mBatteryMeterDrawable.onDispose();
            }
            mBatteryMeterDrawable = createBatteryMeterDrawable(mode);
            }
            if (mMeterMode == BatteryMeterMode.BATTERY_METER_ICON_PORTRAIT ||
                    mMeterMode == BatteryMeterMode.BATTERY_METER_ICON_LANDSCAPE) {
                ((NormalBatteryMeterDrawable)mBatteryMeterDrawable).loadBoltPoints(
@@ -388,8 +372,8 @@ public class BatteryMeterView extends View implements DemoMode,
            }
            if (tracker.present) {
                setVisibility(View.VISIBLE);
                postInvalidate();
                requestLayout();
                invalidate();
            } else {
                setVisibility(View.GONE);
            }
@@ -412,12 +396,10 @@ public class BatteryMeterView extends View implements DemoMode,
    }

    @Override
    public void draw(Canvas c) {
        synchronized (mLock) {
    protected void onDraw(Canvas canvas) {
        if (mBatteryMeterDrawable != null) {
            BatteryTracker tracker = mDemoMode ? mDemoTracker : mTracker;
                mBatteryMeterDrawable.onDraw(c, tracker);
            }
            mBatteryMeterDrawable.onDraw(canvas, tracker);
        }
    }

@@ -709,7 +691,6 @@ public class BatteryMeterView extends View implements DemoMode,

        @Override
        public void onDispose() {
            mHandler.removeCallbacks(mInvalidate);
            mDisposed = true;
        }

@@ -817,13 +798,14 @@ public class BatteryMeterView extends View implements DemoMode,
                initSizeBasedStuff();
            }

            updateChargeAnim(tracker);
            drawCircle(c, tracker, mTextX, mRectLeft);
            if (mAnimationsEnabled) {
                updateChargeAnim(tracker);
            }
        }

        @Override
        public void onDispose() {
            mHandler.removeCallbacks(mInvalidate);
            mDisposed = true;
        }

@@ -881,29 +863,7 @@ public class BatteryMeterView extends View implements DemoMode,
                canvas.drawText("?", textX, mTextY, mTextPaint);

            } else if (tracker.plugged) {
                // draw the bolt
                final float bl = (int)(drawRect.left + drawRect.width() / 3.2f);
                final float bt = (int)(drawRect.top + drawRect.height() / 4f);
                final float br = (int)(drawRect.right - drawRect.width() / 5.2f);
                final float bb = (int)(drawRect.bottom - drawRect.height() / 8f);
                if (mBoltFrame.left != bl || mBoltFrame.top != bt
                        || mBoltFrame.right != br || mBoltFrame.bottom != bb) {
                    mBoltFrame.set(bl, bt, br, bb);
                    mBoltPath.reset();
                    mBoltPath.moveTo(
                            mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
                            mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
                    for (int i = 2; i < mBoltPoints.length; i += 2) {
                        mBoltPath.lineTo(
                                mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(),
                                mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height());
                    }
                    mBoltPath.lineTo(
                            mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
                            mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
                }
                canvas.drawPath(mBoltPath, mBoltPaint);

            } else {
                if (level > mCriticalLevel
                        && (mShowPercent && !(tracker.level == 100 && !SHOW_100_PERCENT))) {
@@ -926,13 +886,12 @@ public class BatteryMeterView extends View implements DemoMode,
        private void updateChargeAnim(BatteryTracker tracker) {
            // Stop animation when battery is full or after the meter
            // rotated back to 0 after unplugging.
            if (!tracker.shouldIndicateCharging() && mAnimOffset == 0
            if (!tracker.shouldIndicateCharging()
                    || tracker.status == BatteryManager.BATTERY_STATUS_FULL
                    || tracker.level == 0) {
                if (mIsAnimating) {
                    mIsAnimating = false;
                    mAnimOffset = 0;
                    mHandler.removeCallbacks(mInvalidate);
                }
                return;
            }
@@ -945,8 +904,7 @@ public class BatteryMeterView extends View implements DemoMode,
                mAnimOffset += 3;
            }

            mHandler.removeCallbacks(mInvalidate);
            mHandler.postDelayed(mInvalidate, 50);
            postInvalidateDelayed(50);
        }

        /**
@@ -975,6 +933,28 @@ public class BatteryMeterView extends View implements DemoMode,
            // the +1dp at end of formula balances out rounding issues.works out on all resolutions
            mTextY = mCircleSize / 2.0f + (bounds.bottom - bounds.top) / 2.0f
                    - strokeWidth / 2.0f + getResources().getDisplayMetrics().density;

            // draw the bolt
            final float bl = (int) (mRectLeft.left + mRectLeft.width() / 3.2f);
            final float bt = (int) (mRectLeft.top + mRectLeft.height() / 4f);
            final float br = (int) (mRectLeft.right - mRectLeft.width() / 5.2f);
            final float bb = (int) (mRectLeft.bottom - mRectLeft.height() / 8f);
            if (mBoltFrame.left != bl || mBoltFrame.top != bt
                    || mBoltFrame.right != br || mBoltFrame.bottom != bb) {
                mBoltFrame.set(bl, bt, br, bb);
                mBoltPath.reset();
                mBoltPath.moveTo(
                        mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
                        mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
                for (int i = 2; i < mBoltPoints.length; i += 2) {
                    mBoltPath.lineTo(
                            mBoltFrame.left + mBoltPoints[i] * mBoltFrame.width(),
                            mBoltFrame.top + mBoltPoints[i + 1] * mBoltFrame.height());
                }
                mBoltPath.lineTo(
                        mBoltFrame.left + mBoltPoints[0] * mBoltFrame.width(),
                        mBoltFrame.top + mBoltPoints[1] * mBoltFrame.height());
            }
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -67,7 +67,7 @@ public class DockBatteryMeterView extends BatteryMeterView {
                            mMeterMode != BatteryMeterMode.BATTERY_METER_TEXT)) {
                        setContentDescription(context.getString(
                                R.string.accessibility_dock_battery_level, level));
                        invalidateIfVisible();
                        invalidate();
                        setVisibility(View.VISIBLE);
                    } else {
                        setContentDescription(null);
+1 −0
Original line number Diff line number Diff line
@@ -1283,6 +1283,7 @@ public class PhoneStatusBar extends BaseStatusBar implements DemoMode,
                ((BatteryMeterView) mStatusBarView.findViewById(R.id.battery));
        batteryMeterView.setBatteryStateRegistar(mBatteryController);
        batteryMeterView.setBatteryController(mBatteryController);
        batteryMeterView.setAnimationsEnabled(false);
        ((BatteryLevelTextView) mStatusBarView.findViewById(R.id.battery_level_text))
                .setBatteryStateRegistar(mBatteryController);
        mKeyguardStatusBar.setBatteryController(mBatteryController);