Loading src/com/android/settings/datausage/ChartDataUsagePreference.java +1 −1 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ public class ChartDataUsagePreference extends Preference { int top = getTop(); chart.clearPaths(); chart.configureGraph(toInt(mEnd - mStart), top, false, false); chart.configureGraph(toInt(mEnd - mStart), top); calcPoints(chart); chart.setBottomLabels(new CharSequence[] { Utils.formatDateRange(getContext(), mStart, mStart), Loading src/com/android/settings/fuelgauge/BatteryInfo.java +16 −6 Original line number Diff line number Diff line Loading @@ -55,18 +55,23 @@ public class BatteryInfo { public void bindHistory(final UsageView view, BatteryDataParser... parsers) { BatteryDataParser parser = new BatteryDataParser() { SparseIntArray points = new SparseIntArray(); int lastTime = -1; byte lastLevel; int maxTime; @Override public void onParsingStarted(long startTime, long endTime) { timePeriod = endTime - startTime - remainingTimeUs / 1000; this.maxTime = (int) (endTime - startTime); timePeriod = maxTime - (remainingTimeUs / 1000); view.clearPaths(); view.configureGraph((int) (endTime - startTime), 100, remainingTimeUs != 0, mCharging); view.configureGraph(maxTime, 100); } @Override public void onDataPoint(long time, HistoryItem record) { points.put((int) time, record.batteryLevel); lastTime = (int) time; lastLevel = record.batteryLevel; points.put(lastTime, lastLevel); } @Override Loading @@ -79,8 +84,13 @@ public class BatteryInfo { @Override public void onParsingDone() { if (points.size() > 1) { view.addPath(points); onDataGap(); // Add linear projection if (lastTime >= 0 && remainingTimeUs != 0) { points.put(lastTime, lastLevel); points.put(maxTime, mCharging ? 100 : 0); view.addProjectedPath(points); } } }; Loading src/com/android/settings/graph/UsageGraph.java +71 −64 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.util.AttributeSet; import android.util.SparseIntArray; import android.util.TypedValue; import android.view.View; import com.android.settingslib.R; public class UsageGraph extends View { Loading @@ -52,11 +53,14 @@ public class UsageGraph extends View { private final SparseIntArray mPaths = new SparseIntArray(); // Paths in local coordinates for drawing. private final SparseIntArray mLocalPaths = new SparseIntArray(); private final int mCornerRadius; // Paths for projection in coordinates they are passed in. private final SparseIntArray mProjectedPaths = new SparseIntArray(); // Paths for projection in local coordinates for drawing. private final SparseIntArray mLocalProjectedPaths = new SparseIntArray(); private final int mCornerRadius; private int mAccentColor; private boolean mShowProjection; private boolean mProjectUp; private float mMaxX = 100; private float mMaxY = 100; Loading Loading @@ -98,6 +102,9 @@ public class UsageGraph extends View { void clearPaths() { mPaths.clear(); mLocalPaths.clear(); mProjectedPaths.clear(); mLocalProjectedPaths.clear(); } void setMax(int maxX, int maxY) { Loading @@ -115,11 +122,21 @@ public class UsageGraph extends View { } public void addPath(SparseIntArray points) { for (int i = 0; i < points.size(); i++) { mPaths.put(points.keyAt(i), points.valueAt(i)); addPathAndUpdate(points, mPaths, mLocalPaths); } mPaths.put(points.keyAt(points.size() - 1) + 1, PATH_DELIM); calculateLocalPaths(); public void addProjectedPath(SparseIntArray points) { addPathAndUpdate(points, mProjectedPaths, mLocalProjectedPaths); } private void addPathAndUpdate(SparseIntArray points, SparseIntArray paths, SparseIntArray localPaths) { for (int i = 0, size = points.size(); i < size; i++) { paths.put(points.keyAt(i), points.valueAt(i)); } // Add a delimiting value immediately after the last point. paths.put(points.keyAt(points.size() - 1) + 1, PATH_DELIM); calculateLocalPaths(paths, localPaths); postInvalidate(); } Loading @@ -130,48 +147,45 @@ public class UsageGraph extends View { postInvalidate(); } void setShowProjection(boolean showProjection, boolean projectUp) { mShowProjection = showProjection; mProjectUp = projectUp; postInvalidate(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); updateGradient(); calculateLocalPaths(); calculateLocalPaths(mPaths, mLocalPaths); calculateLocalPaths(mProjectedPaths, mLocalProjectedPaths); } private void calculateLocalPaths() { if (getWidth() == 0) return; mLocalPaths.clear(); private void calculateLocalPaths(SparseIntArray paths, SparseIntArray localPaths) { if (getWidth() == 0) { return; } localPaths.clear(); int pendingXLoc = 0; int pendingYLoc = PATH_DELIM; for (int i = 0; i < mPaths.size(); i++) { int x = mPaths.keyAt(i); int y = mPaths.valueAt(i); for (int i = 0; i < paths.size(); i++) { int x = paths.keyAt(i); int y = paths.valueAt(i); if (y == PATH_DELIM) { if (i == mPaths.size() - 1 && pendingYLoc != PATH_DELIM) { if (i == paths.size() - 1 && pendingYLoc != PATH_DELIM) { // Connect to the end of the graph. mLocalPaths.put(pendingXLoc, pendingYLoc); localPaths.put(pendingXLoc, pendingYLoc); } // Clear out any pending points. pendingYLoc = PATH_DELIM; mLocalPaths.put(pendingXLoc + 1, PATH_DELIM); localPaths.put(pendingXLoc + 1, PATH_DELIM); } else { final int lx = getX(x); final int ly = getY(y); pendingXLoc = lx; if (mLocalPaths.size() > 0) { int lastX = mLocalPaths.keyAt(mLocalPaths.size() - 1); int lastY = mLocalPaths.valueAt(mLocalPaths.size() - 1); if (localPaths.size() > 0) { int lastX = localPaths.keyAt(localPaths.size() - 1); int lastY = localPaths.valueAt(localPaths.size() - 1); if (lastY != PATH_DELIM && !hasDiff(lastX, lx) && !hasDiff(lastY, ly)) { pendingYLoc = ly; continue; } } mLocalPaths.put(lx, ly); localPaths.put(lx, ly); } } } Loading @@ -189,8 +203,9 @@ public class UsageGraph extends View { } private void updateGradient() { mFillPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), getColor(mAccentColor, .2f), 0, TileMode.CLAMP)); mFillPaint.setShader( new LinearGradient(0, 0, 0, getHeight(), getColor(mAccentColor, .2f), 0, TileMode.CLAMP)); } private int getColor(int color, float alphaScale) { Loading @@ -207,62 +222,54 @@ public class UsageGraph extends View { mMiddleDividerTint); drawDivider(canvas.getHeight() - mDividerSize, canvas, -1); if (mLocalPaths.size() == 0) { if (mLocalPaths.size() == 0 && mProjectedPaths.size() == 0) { return; } if (mShowProjection) { drawProjection(canvas); } drawFilledPath(canvas); drawLinePath(canvas); drawLinePath(canvas, mLocalProjectedPaths, mDottedPaint); drawFilledPath(canvas, mLocalPaths, mFillPaint); drawLinePath(canvas, mLocalPaths, mLinePaint); } private void drawProjection(Canvas canvas) { mPath.reset(); int x = mLocalPaths.keyAt(mLocalPaths.size() - 2); int y = mLocalPaths.valueAt(mLocalPaths.size() - 2); mPath.moveTo(x, y); mPath.lineTo(canvas.getWidth(), mProjectUp ? 0 : canvas.getHeight()); canvas.drawPath(mPath, mDottedPaint); private void drawLinePath(Canvas canvas, SparseIntArray localPaths, Paint paint) { if (localPaths.size() == 0) { return; } private void drawLinePath(Canvas canvas) { mPath.reset(); mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0)); for (int i = 1; i < mLocalPaths.size(); i++) { int x = mLocalPaths.keyAt(i); int y = mLocalPaths.valueAt(i); mPath.moveTo(localPaths.keyAt(0), localPaths.valueAt(0)); for (int i = 1; i < localPaths.size(); i++) { int x = localPaths.keyAt(i); int y = localPaths.valueAt(i); if (y == PATH_DELIM) { if (++i < mLocalPaths.size()) { mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i)); if (++i < localPaths.size()) { mPath.moveTo(localPaths.keyAt(i), localPaths.valueAt(i)); } } else { mPath.lineTo(x, y); } } canvas.drawPath(mPath, mLinePaint); canvas.drawPath(mPath, paint); } private void drawFilledPath(Canvas canvas) { private void drawFilledPath(Canvas canvas, SparseIntArray localPaths, Paint paint) { mPath.reset(); float lastStartX = mLocalPaths.keyAt(0); mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0)); for (int i = 1; i < mLocalPaths.size(); i++) { int x = mLocalPaths.keyAt(i); int y = mLocalPaths.valueAt(i); float lastStartX = localPaths.keyAt(0); mPath.moveTo(localPaths.keyAt(0), localPaths.valueAt(0)); for (int i = 1; i < localPaths.size(); i++) { int x = localPaths.keyAt(i); int y = localPaths.valueAt(i); if (y == PATH_DELIM) { mPath.lineTo(mLocalPaths.keyAt(i - 1), getHeight()); mPath.lineTo(localPaths.keyAt(i - 1), getHeight()); mPath.lineTo(lastStartX, getHeight()); mPath.close(); if (++i < mLocalPaths.size()) { lastStartX = mLocalPaths.keyAt(i); mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i)); if (++i < localPaths.size()) { lastStartX = localPaths.keyAt(i); mPath.moveTo(localPaths.keyAt(i), localPaths.valueAt(i)); } } else { mPath.lineTo(x, y); } } canvas.drawPath(mPath, mFillPaint); canvas.drawPath(mPath, paint); } private void drawDivider(int y, Canvas canvas, int tintColor) { Loading src/com/android/settings/graph/UsageView.java +5 −2 Original line number Diff line number Diff line Loading @@ -91,9 +91,12 @@ public class UsageView extends FrameLayout { mUsageGraph.addPath(points); } public void configureGraph(int maxX, int maxY, boolean showProjection, boolean projectUp) { public void addProjectedPath(SparseIntArray points) { mUsageGraph.addProjectedPath(points); } public void configureGraph(int maxX, int maxY) { mUsageGraph.setMax(maxX, maxY); mUsageGraph.setShowProjection(showProjection, projectUp); } public void setAccentColor(int color) { Loading Loading
src/com/android/settings/datausage/ChartDataUsagePreference.java +1 −1 Original line number Diff line number Diff line Loading @@ -62,7 +62,7 @@ public class ChartDataUsagePreference extends Preference { int top = getTop(); chart.clearPaths(); chart.configureGraph(toInt(mEnd - mStart), top, false, false); chart.configureGraph(toInt(mEnd - mStart), top); calcPoints(chart); chart.setBottomLabels(new CharSequence[] { Utils.formatDateRange(getContext(), mStart, mStart), Loading
src/com/android/settings/fuelgauge/BatteryInfo.java +16 −6 Original line number Diff line number Diff line Loading @@ -55,18 +55,23 @@ public class BatteryInfo { public void bindHistory(final UsageView view, BatteryDataParser... parsers) { BatteryDataParser parser = new BatteryDataParser() { SparseIntArray points = new SparseIntArray(); int lastTime = -1; byte lastLevel; int maxTime; @Override public void onParsingStarted(long startTime, long endTime) { timePeriod = endTime - startTime - remainingTimeUs / 1000; this.maxTime = (int) (endTime - startTime); timePeriod = maxTime - (remainingTimeUs / 1000); view.clearPaths(); view.configureGraph((int) (endTime - startTime), 100, remainingTimeUs != 0, mCharging); view.configureGraph(maxTime, 100); } @Override public void onDataPoint(long time, HistoryItem record) { points.put((int) time, record.batteryLevel); lastTime = (int) time; lastLevel = record.batteryLevel; points.put(lastTime, lastLevel); } @Override Loading @@ -79,8 +84,13 @@ public class BatteryInfo { @Override public void onParsingDone() { if (points.size() > 1) { view.addPath(points); onDataGap(); // Add linear projection if (lastTime >= 0 && remainingTimeUs != 0) { points.put(lastTime, lastLevel); points.put(maxTime, mCharging ? 100 : 0); view.addProjectedPath(points); } } }; Loading
src/com/android/settings/graph/UsageGraph.java +71 −64 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.util.AttributeSet; import android.util.SparseIntArray; import android.util.TypedValue; import android.view.View; import com.android.settingslib.R; public class UsageGraph extends View { Loading @@ -52,11 +53,14 @@ public class UsageGraph extends View { private final SparseIntArray mPaths = new SparseIntArray(); // Paths in local coordinates for drawing. private final SparseIntArray mLocalPaths = new SparseIntArray(); private final int mCornerRadius; // Paths for projection in coordinates they are passed in. private final SparseIntArray mProjectedPaths = new SparseIntArray(); // Paths for projection in local coordinates for drawing. private final SparseIntArray mLocalProjectedPaths = new SparseIntArray(); private final int mCornerRadius; private int mAccentColor; private boolean mShowProjection; private boolean mProjectUp; private float mMaxX = 100; private float mMaxY = 100; Loading Loading @@ -98,6 +102,9 @@ public class UsageGraph extends View { void clearPaths() { mPaths.clear(); mLocalPaths.clear(); mProjectedPaths.clear(); mLocalProjectedPaths.clear(); } void setMax(int maxX, int maxY) { Loading @@ -115,11 +122,21 @@ public class UsageGraph extends View { } public void addPath(SparseIntArray points) { for (int i = 0; i < points.size(); i++) { mPaths.put(points.keyAt(i), points.valueAt(i)); addPathAndUpdate(points, mPaths, mLocalPaths); } mPaths.put(points.keyAt(points.size() - 1) + 1, PATH_DELIM); calculateLocalPaths(); public void addProjectedPath(SparseIntArray points) { addPathAndUpdate(points, mProjectedPaths, mLocalProjectedPaths); } private void addPathAndUpdate(SparseIntArray points, SparseIntArray paths, SparseIntArray localPaths) { for (int i = 0, size = points.size(); i < size; i++) { paths.put(points.keyAt(i), points.valueAt(i)); } // Add a delimiting value immediately after the last point. paths.put(points.keyAt(points.size() - 1) + 1, PATH_DELIM); calculateLocalPaths(paths, localPaths); postInvalidate(); } Loading @@ -130,48 +147,45 @@ public class UsageGraph extends View { postInvalidate(); } void setShowProjection(boolean showProjection, boolean projectUp) { mShowProjection = showProjection; mProjectUp = projectUp; postInvalidate(); } @Override protected void onSizeChanged(int w, int h, int oldw, int oldh) { super.onSizeChanged(w, h, oldw, oldh); updateGradient(); calculateLocalPaths(); calculateLocalPaths(mPaths, mLocalPaths); calculateLocalPaths(mProjectedPaths, mLocalProjectedPaths); } private void calculateLocalPaths() { if (getWidth() == 0) return; mLocalPaths.clear(); private void calculateLocalPaths(SparseIntArray paths, SparseIntArray localPaths) { if (getWidth() == 0) { return; } localPaths.clear(); int pendingXLoc = 0; int pendingYLoc = PATH_DELIM; for (int i = 0; i < mPaths.size(); i++) { int x = mPaths.keyAt(i); int y = mPaths.valueAt(i); for (int i = 0; i < paths.size(); i++) { int x = paths.keyAt(i); int y = paths.valueAt(i); if (y == PATH_DELIM) { if (i == mPaths.size() - 1 && pendingYLoc != PATH_DELIM) { if (i == paths.size() - 1 && pendingYLoc != PATH_DELIM) { // Connect to the end of the graph. mLocalPaths.put(pendingXLoc, pendingYLoc); localPaths.put(pendingXLoc, pendingYLoc); } // Clear out any pending points. pendingYLoc = PATH_DELIM; mLocalPaths.put(pendingXLoc + 1, PATH_DELIM); localPaths.put(pendingXLoc + 1, PATH_DELIM); } else { final int lx = getX(x); final int ly = getY(y); pendingXLoc = lx; if (mLocalPaths.size() > 0) { int lastX = mLocalPaths.keyAt(mLocalPaths.size() - 1); int lastY = mLocalPaths.valueAt(mLocalPaths.size() - 1); if (localPaths.size() > 0) { int lastX = localPaths.keyAt(localPaths.size() - 1); int lastY = localPaths.valueAt(localPaths.size() - 1); if (lastY != PATH_DELIM && !hasDiff(lastX, lx) && !hasDiff(lastY, ly)) { pendingYLoc = ly; continue; } } mLocalPaths.put(lx, ly); localPaths.put(lx, ly); } } } Loading @@ -189,8 +203,9 @@ public class UsageGraph extends View { } private void updateGradient() { mFillPaint.setShader(new LinearGradient(0, 0, 0, getHeight(), getColor(mAccentColor, .2f), 0, TileMode.CLAMP)); mFillPaint.setShader( new LinearGradient(0, 0, 0, getHeight(), getColor(mAccentColor, .2f), 0, TileMode.CLAMP)); } private int getColor(int color, float alphaScale) { Loading @@ -207,62 +222,54 @@ public class UsageGraph extends View { mMiddleDividerTint); drawDivider(canvas.getHeight() - mDividerSize, canvas, -1); if (mLocalPaths.size() == 0) { if (mLocalPaths.size() == 0 && mProjectedPaths.size() == 0) { return; } if (mShowProjection) { drawProjection(canvas); } drawFilledPath(canvas); drawLinePath(canvas); drawLinePath(canvas, mLocalProjectedPaths, mDottedPaint); drawFilledPath(canvas, mLocalPaths, mFillPaint); drawLinePath(canvas, mLocalPaths, mLinePaint); } private void drawProjection(Canvas canvas) { mPath.reset(); int x = mLocalPaths.keyAt(mLocalPaths.size() - 2); int y = mLocalPaths.valueAt(mLocalPaths.size() - 2); mPath.moveTo(x, y); mPath.lineTo(canvas.getWidth(), mProjectUp ? 0 : canvas.getHeight()); canvas.drawPath(mPath, mDottedPaint); private void drawLinePath(Canvas canvas, SparseIntArray localPaths, Paint paint) { if (localPaths.size() == 0) { return; } private void drawLinePath(Canvas canvas) { mPath.reset(); mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0)); for (int i = 1; i < mLocalPaths.size(); i++) { int x = mLocalPaths.keyAt(i); int y = mLocalPaths.valueAt(i); mPath.moveTo(localPaths.keyAt(0), localPaths.valueAt(0)); for (int i = 1; i < localPaths.size(); i++) { int x = localPaths.keyAt(i); int y = localPaths.valueAt(i); if (y == PATH_DELIM) { if (++i < mLocalPaths.size()) { mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i)); if (++i < localPaths.size()) { mPath.moveTo(localPaths.keyAt(i), localPaths.valueAt(i)); } } else { mPath.lineTo(x, y); } } canvas.drawPath(mPath, mLinePaint); canvas.drawPath(mPath, paint); } private void drawFilledPath(Canvas canvas) { private void drawFilledPath(Canvas canvas, SparseIntArray localPaths, Paint paint) { mPath.reset(); float lastStartX = mLocalPaths.keyAt(0); mPath.moveTo(mLocalPaths.keyAt(0), mLocalPaths.valueAt(0)); for (int i = 1; i < mLocalPaths.size(); i++) { int x = mLocalPaths.keyAt(i); int y = mLocalPaths.valueAt(i); float lastStartX = localPaths.keyAt(0); mPath.moveTo(localPaths.keyAt(0), localPaths.valueAt(0)); for (int i = 1; i < localPaths.size(); i++) { int x = localPaths.keyAt(i); int y = localPaths.valueAt(i); if (y == PATH_DELIM) { mPath.lineTo(mLocalPaths.keyAt(i - 1), getHeight()); mPath.lineTo(localPaths.keyAt(i - 1), getHeight()); mPath.lineTo(lastStartX, getHeight()); mPath.close(); if (++i < mLocalPaths.size()) { lastStartX = mLocalPaths.keyAt(i); mPath.moveTo(mLocalPaths.keyAt(i), mLocalPaths.valueAt(i)); if (++i < localPaths.size()) { lastStartX = localPaths.keyAt(i); mPath.moveTo(localPaths.keyAt(i), localPaths.valueAt(i)); } } else { mPath.lineTo(x, y); } } canvas.drawPath(mPath, mFillPaint); canvas.drawPath(mPath, paint); } private void drawDivider(int y, Canvas canvas, int tintColor) { Loading
src/com/android/settings/graph/UsageView.java +5 −2 Original line number Diff line number Diff line Loading @@ -91,9 +91,12 @@ public class UsageView extends FrameLayout { mUsageGraph.addPath(points); } public void configureGraph(int maxX, int maxY, boolean showProjection, boolean projectUp) { public void addProjectedPath(SparseIntArray points) { mUsageGraph.addProjectedPath(points); } public void configureGraph(int maxX, int maxY) { mUsageGraph.setMax(maxX, maxY); mUsageGraph.setShowProjection(showProjection, projectUp); } public void setAccentColor(int color) { Loading