summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/widget/NotificationProgressBar.java209
-rw-r--r--core/java/com/android/internal/widget/NotificationProgressDrawable.java46
-rw-r--r--core/res/res/drawable/notification_progress.xml1
-rw-r--r--core/res/res/values/attrs.xml7
-rw-r--r--core/res/res/values/dimens.xml2
-rw-r--r--core/res/res/values/symbols.xml1
-rw-r--r--core/tests/coretests/src/com/android/internal/widget/NotificationProgressBarTest.java412
7 files changed, 581 insertions, 97 deletions
diff --git a/core/java/com/android/internal/widget/NotificationProgressBar.java b/core/java/com/android/internal/widget/NotificationProgressBar.java
index d8001d82b3e9..f0b54937546b 100644
--- a/core/java/com/android/internal/widget/NotificationProgressBar.java
+++ b/core/java/com/android/internal/widget/NotificationProgressBar.java
@@ -32,6 +32,7 @@ import android.graphics.drawable.LayerDrawable;
import android.os.Bundle;
import android.util.AttributeSet;
import android.util.Log;
+import android.util.Pair;
import android.view.RemotableViewMethod;
import android.widget.ProgressBar;
import android.widget.RemoteViews;
@@ -67,6 +68,7 @@ public final class NotificationProgressBar extends ProgressBar implements
@Nullable
private List<Part> mParts = null;
+ // List of drawable parts before segment splitting by process.
@Nullable
private List<NotificationProgressDrawable.Part> mProgressDrawableParts = null;
@@ -81,7 +83,13 @@ public final class NotificationProgressBar extends ProgressBar implements
private final Matrix mMatrix = new Matrix();
private Matrix mTrackerDrawMatrix = null;
- private float mScale = 0;
+ private float mProgressFraction = 0;
+ /**
+ * The location of progress on the stretched and rescaled progress bar, in fraction. Used for
+ * calculating the tracker position. If stretching and rescaling is not needed, ==
+ * mProgressFraction.
+ */
+ private float mAdjustedProgressFraction = 0;
/** Indicates whether mTrackerPos needs to be recalculated before the tracker is drawn. */
private boolean mTrackerPosIsDirty = false;
@@ -143,6 +151,10 @@ public final class NotificationProgressBar extends ProgressBar implements
final int indeterminateColor = mProgressModel.getIndeterminateColor();
setIndeterminateTintList(ColorStateList.valueOf(indeterminateColor));
} else {
+ // TODO: b/372908709 - maybe don't rerun the entire calculation every time the
+ // progress model is updated? For example, if the segments and parts aren't changed,
+ // there is no need to call `processAndConvertToViewParts` again.
+
final int progress = mProgressModel.getProgress();
final int progressMax = mProgressModel.getProgressMax();
@@ -342,10 +354,10 @@ public final class NotificationProgressBar extends ProgressBar implements
}
private void onMaybeVisualProgressChanged() {
- float scale = getScale();
- if (mScale == scale) return;
+ float progressFraction = getProgressFraction();
+ if (mProgressFraction == progressFraction) return;
- mScale = scale;
+ mProgressFraction = progressFraction;
mTrackerPosIsDirty = true;
invalidate();
}
@@ -427,12 +439,21 @@ public final class NotificationProgressBar extends ProgressBar implements
mNotificationProgressDrawable.getSegSegGap(),
mNotificationProgressDrawable.getSegPointGap(),
mNotificationProgressDrawable.getPointRadius(),
- mHasTrackerIcon,
- getScale() * width,
- mProgressModel.isStyledByProgress());
+ mHasTrackerIcon
+ );
+ Pair<List<NotificationProgressDrawable.Part>, Float> p = maybeStretchAndRescaleSegments(
+ mParts,
+ mProgressDrawableParts,
+ mNotificationProgressDrawable.getSegmentMinWidth(),
+ mNotificationProgressDrawable.getPointRadius(),
+ getProgressFraction(),
+ width,
+ mProgressModel.isStyledByProgress(),
+ mHasTrackerIcon ? 0F : mNotificationProgressDrawable.getSegSegGap());
Log.d(TAG, "Updating NotificationProgressDrawable parts");
- mNotificationProgressDrawable.setParts(mProgressDrawableParts);
+ mNotificationProgressDrawable.setParts(p.first);
+ mAdjustedProgressFraction = p.second / width;
}
private void updateTrackerAndBarPos(int w, int h) {
@@ -465,11 +486,11 @@ public final class NotificationProgressBar extends ProgressBar implements
}
if (tracker != null) {
- setTrackerPos(w, tracker, mScale, trackerOffsetY);
+ setTrackerPos(w, tracker, mAdjustedProgressFraction, trackerOffsetY);
}
}
- private float getScale() {
+ private float getProgressFraction() {
int min = getMin();
int max = getMax();
int range = max - min;
@@ -481,17 +502,17 @@ public final class NotificationProgressBar extends ProgressBar implements
*
* @param w Width of the view, including padding
* @param tracker Drawable used for the tracker
- * @param scale Current progress between 0 and 1
+ * @param progressFraction Current progress between 0 and 1
* @param offsetY Vertical offset for centering. If set to
* {@link Integer#MIN_VALUE}, the current offset will be used.
*/
- private void setTrackerPos(int w, Drawable tracker, float scale, int offsetY) {
+ private void setTrackerPos(int w, Drawable tracker, float progressFraction, int offsetY) {
int available = w - mPaddingLeft - mPaddingRight;
final int trackerWidth = tracker.getIntrinsicWidth();
final int trackerHeight = tracker.getIntrinsicHeight();
available -= ((mTrackerHeight <= 0) ? trackerWidth : mTrackerWidth);
- final int trackerPos = (int) (scale * available + 0.5f);
+ final int trackerPos = (int) (progressFraction * available + 0.5f);
final int top, bottom;
if (offsetY == Integer.MIN_VALUE) {
@@ -545,7 +566,7 @@ public final class NotificationProgressBar extends ProgressBar implements
if (mTracker == null) return;
if (mTrackerPosIsDirty) {
- setTrackerPos(getWidth(), mTracker, mScale, Integer.MIN_VALUE);
+ setTrackerPos(getWidth(), mTracker, mAdjustedProgressFraction, Integer.MIN_VALUE);
}
final int saveCount = canvas.save();
@@ -594,7 +615,7 @@ public final class NotificationProgressBar extends ProgressBar implements
final Drawable tracker = mTracker;
if (tracker != null) {
- setTrackerPos(getWidth(), tracker, mScale, Integer.MIN_VALUE);
+ setTrackerPos(getWidth(), tracker, mAdjustedProgressFraction, Integer.MIN_VALUE);
// Since we draw translated, the drawable's bounds that it signals
// for invalidation won't be the actual bounds we want invalidated,
@@ -776,9 +797,7 @@ public final class NotificationProgressBar extends ProgressBar implements
float segSegGap,
float segPointGap,
float pointRadius,
- boolean hasTrackerIcon,
- float progressX,
- boolean isStyledByProgress
+ boolean hasTrackerIcon
) {
List<NotificationProgressDrawable.Part> drawableParts = new ArrayList<>();
@@ -826,12 +845,7 @@ public final class NotificationProgressBar extends ProgressBar implements
}
}
- return maybeSplitDrawableSegmentsByProgress(
- isStyledByProgress,
- parts,
- drawableParts,
- progressX,
- hasTrackerIcon ? 0F : segSegGap);
+ return drawableParts;
}
private static float getSegStartOffset(Part prevPart, float pointRadius, float segPointGap,
@@ -859,33 +873,148 @@ public final class NotificationProgressBar extends ProgressBar implements
return segPointGap + pointRadius + pointOffset;
}
- // If isStyledByProgress is true, also split the segment with the progress value in its range.
- private static List<NotificationProgressDrawable.Part> maybeSplitDrawableSegmentsByProgress(
+ /**
+ * Processes the list of {@code NotificationProgressBar.Part} data and convert to a pair of:
+ * - list of {@code NotificationProgressDrawable.Part}.
+ * - location of progress on the stretched and rescaled progress bar.
+ */
+ @VisibleForTesting
+ public static Pair<List<NotificationProgressDrawable.Part>, Float>
+ maybeStretchAndRescaleSegments(
+ List<Part> parts,
+ List<NotificationProgressDrawable.Part> drawableParts,
+ float segmentMinWidth,
+ float pointRadius,
+ float progressFraction,
+ float totalWidth,
boolean isStyledByProgress,
+ float progressGap
+ ) {
+ final List<NotificationProgressDrawable.Segment> drawableSegments = drawableParts
+ .stream()
+ .filter(NotificationProgressDrawable.Segment.class::isInstance)
+ .map(NotificationProgressDrawable.Segment.class::cast)
+ .toList();
+ float totalExcessWidth = 0;
+ float totalPositiveExcessWidth = 0;
+ for (NotificationProgressDrawable.Segment drawableSegment : drawableSegments) {
+ final float excessWidth = drawableSegment.getWidth() - segmentMinWidth;
+ totalExcessWidth += excessWidth;
+ if (excessWidth > 0) totalPositiveExcessWidth += excessWidth;
+ }
+
+ // All drawable segments are above minimum width. No need to stretch and rescale.
+ if (totalExcessWidth == totalPositiveExcessWidth) {
+ return maybeSplitDrawableSegmentsByProgress(
+ parts,
+ drawableParts,
+ progressFraction,
+ totalWidth,
+ isStyledByProgress,
+ progressGap);
+ }
+
+ if (totalExcessWidth < 0) {
+ // TODO: b/372908709 - throw an error so that the caller can catch and go to fallback
+ // option. (instead of return.)
+ Log.w(TAG, "Not enough width to satisfy the minimum width for segments.");
+ return maybeSplitDrawableSegmentsByProgress(
+ parts,
+ drawableParts,
+ progressFraction,
+ totalWidth,
+ isStyledByProgress,
+ progressGap);
+ }
+
+ final int nParts = drawableParts.size();
+ float startOffset = 0;
+ for (int iPart = 0; iPart < nParts; iPart++) {
+ final NotificationProgressDrawable.Part drawablePart = drawableParts.get(iPart);
+ if (drawablePart instanceof NotificationProgressDrawable.Segment drawableSegment) {
+ final float origDrawableSegmentWidth = drawableSegment.getWidth();
+
+ float drawableSegmentWidth = segmentMinWidth;
+ // Allocate the totalExcessWidth to the segments above minimum, proportionally to
+ // their initial excessWidth.
+ if (origDrawableSegmentWidth > segmentMinWidth) {
+ drawableSegmentWidth +=
+ totalExcessWidth * (origDrawableSegmentWidth - segmentMinWidth)
+ / totalPositiveExcessWidth;
+ }
+
+ final float widthDiff = drawableSegmentWidth - drawableSegment.getWidth();
+
+ // Adjust drawable segments to new widths
+ drawableSegment.setStart(drawableSegment.getStart() + startOffset);
+ drawableSegment.setEnd(
+ drawableSegment.getStart() + origDrawableSegmentWidth + widthDiff);
+
+ // Also adjust view segments to new width. (For view segments, only start is
+ // needed?)
+ // Check that segments and drawableSegments are of the same size?
+ final Segment segment = (Segment) parts.get(iPart);
+ final float origSegmentWidth = segment.getWidth();
+ segment.mStart = segment.mStart + startOffset;
+ segment.mEnd = segment.mStart + origSegmentWidth + widthDiff;
+
+ // Increase startOffset for the subsequent segments.
+ startOffset += widthDiff;
+ } else if (drawablePart instanceof NotificationProgressDrawable.Point drawablePoint) {
+ drawablePoint.setStart(drawablePoint.getStart() + startOffset);
+ drawablePoint.setEnd(drawablePoint.getStart() + 2 * pointRadius);
+ }
+ }
+
+ return maybeSplitDrawableSegmentsByProgress(
+ parts,
+ drawableParts,
+ progressFraction,
+ totalWidth,
+ isStyledByProgress,
+ progressGap);
+ }
+
+ // Find the location of progress on the stretched and rescaled progress bar.
+ // If isStyledByProgress is true, also split the segment with the progress value in its range.
+ private static Pair<List<NotificationProgressDrawable.Part>, Float>
+ maybeSplitDrawableSegmentsByProgress(
// Needed to get the original segment start and end positions in pixels.
List<Part> parts,
List<NotificationProgressDrawable.Part> drawableParts,
- float progressX,
+ float progressFraction,
+ float totalWidth,
+ boolean isStyledByProgress,
float progressGap
) {
- if (!isStyledByProgress) return drawableParts;
+ if (progressFraction == 1) return new Pair<>(drawableParts, totalWidth);
int iPartFirstSegmentToStyle = -1;
int iPartSegmentToSplit = -1;
+ float rescaledProgressX = 0;
+ float startFraction = 0;
final int nParts = parts.size();
for (int iPart = 0; iPart < nParts; iPart++) {
final Part part = parts.get(iPart);
if (!(part instanceof Segment)) continue;
final Segment segment = (Segment) part;
- if (segment.mStart == progressX) {
+ if (startFraction == progressFraction) {
iPartFirstSegmentToStyle = iPart;
+ rescaledProgressX = segment.mStart;
break;
- } else if (segment.mStart < progressX && progressX < segment.mEnd) {
+ } else if (startFraction < progressFraction
+ && progressFraction < startFraction + segment.mFraction) {
iPartSegmentToSplit = iPart;
+ rescaledProgressX =
+ segment.mStart + (progressFraction - startFraction) / segment.mFraction
+ * segment.getWidth();
break;
}
+ startFraction += segment.mFraction;
}
+ if (!isStyledByProgress) return new Pair<>(drawableParts, rescaledProgressX);
+
List<NotificationProgressDrawable.Part> splitDrawableParts = new ArrayList<>();
boolean styleRemainingParts = false;
for (int iPart = 0; iPart < nParts; iPart++) {
@@ -899,22 +1028,23 @@ public final class NotificationProgressBar extends ProgressBar implements
if (iPart == iPartFirstSegmentToStyle) styleRemainingParts = true;
if (drawablePart instanceof NotificationProgressDrawable.Segment drawableSegment) {
if (iPart == iPartSegmentToSplit) {
- if (progressX <= drawableSegment.getStart()) {
+ if (rescaledProgressX <= drawableSegment.getStart()) {
styleRemainingParts = true;
final int color = maybeGetFadedColor(drawableSegment.getColor(), true);
splitDrawableParts.add(
new NotificationProgressDrawable.Segment(drawableSegment.getStart(),
drawableSegment.getEnd(),
color, true));
- } else if (drawableSegment.getStart() < progressX
- && progressX < drawableSegment.getEnd()) {
+ } else if (drawableSegment.getStart() < rescaledProgressX
+ && rescaledProgressX < drawableSegment.getEnd()) {
splitDrawableParts.add(
new NotificationProgressDrawable.Segment(drawableSegment.getStart(),
- progressX - progressGap,
+ rescaledProgressX - progressGap,
drawableSegment.getColor()));
final int color = maybeGetFadedColor(drawableSegment.getColor(), true);
- splitDrawableParts.add(new NotificationProgressDrawable.Segment(progressX,
- drawableSegment.getEnd(), color, true));
+ splitDrawableParts.add(
+ new NotificationProgressDrawable.Segment(rescaledProgressX,
+ drawableSegment.getEnd(), color, true));
styleRemainingParts = true;
} else {
splitDrawableParts.add(
@@ -934,7 +1064,7 @@ public final class NotificationProgressBar extends ProgressBar implements
}
}
- return splitDrawableParts;
+ return new Pair<>(splitDrawableParts, rescaledProgressX);
}
/**
@@ -984,6 +1114,11 @@ public final class NotificationProgressBar extends ProgressBar implements
mFaded = faded;
}
+ /** Returns the calculated drawing width of the part */
+ public float getWidth() {
+ return mEnd - mStart;
+ }
+
@Override
public String toString() {
return "Segment(fraction=" + this.mFraction + ", color=" + this.mColor + ", faded="
diff --git a/core/java/com/android/internal/widget/NotificationProgressDrawable.java b/core/java/com/android/internal/widget/NotificationProgressDrawable.java
index 3327b942c8e3..ef0a5d5cdec2 100644
--- a/core/java/com/android/internal/widget/NotificationProgressDrawable.java
+++ b/core/java/com/android/internal/widget/NotificationProgressDrawable.java
@@ -95,6 +95,13 @@ public final class NotificationProgressDrawable extends Drawable {
}
/**
+ * Returns the gap between a segment and a point.
+ */
+ public float getSegmentMinWidth() {
+ return mState.mSegmentMinWidth;
+ }
+
+ /**
* Returns the radius for the points.
*/
public float getPointRadius() {
@@ -322,6 +329,8 @@ public final class NotificationProgressDrawable extends Drawable {
// Extract the theme attributes, if any.
state.mThemeAttrsSegments = a.extractThemeAttrs();
+ state.mSegmentMinWidth = a.getDimension(
+ R.styleable.NotificationProgressDrawableSegments_minWidth, state.mSegmentMinWidth);
state.mSegmentHeight = a.getDimension(
R.styleable.NotificationProgressDrawableSegments_height, state.mSegmentHeight);
state.mFadedSegmentHeight = a.getDimension(
@@ -408,10 +417,12 @@ public final class NotificationProgressDrawable extends Drawable {
* varying drawing width, or a {@link Point} with zero length and fixed size for drawing.
*/
public abstract static class Part {
- /** Start position for drawing (in pixels). */
- protected final float mStart;
- /** End position for drawing (in pixels). */
- protected final float mEnd;
+ // TODO: b/372908709 - maybe rename start/end to left/right, to be consistent with the
+ // bounds rect.
+ /** Start position for drawing (in pixels) */
+ protected float mStart;
+ /** End position for drawing (in pixels) */
+ protected float mEnd;
/** Drawing color. */
@ColorInt protected final int mColor;
@@ -425,10 +436,23 @@ public final class NotificationProgressDrawable extends Drawable {
return this.mStart;
}
+ public void setStart(float start) {
+ mStart = start;
+ }
+
public float getEnd() {
return this.mEnd;
}
+ public void setEnd(float end) {
+ mEnd = end;
+ }
+
+ /** Returns the calculated drawing width of the part */
+ public float getWidth() {
+ return mEnd - mStart;
+ }
+
public int getColor() {
return this.mColor;
}
@@ -537,6 +561,7 @@ public final class NotificationProgressDrawable extends Drawable {
int mChangingConfigurations;
float mSegSegGap = 0.0f;
float mSegPointGap = 0.0f;
+ float mSegmentMinWidth = 0.0f;
float mSegmentHeight;
float mFadedSegmentHeight;
float mSegmentCornerRadius;
@@ -558,6 +583,7 @@ public final class NotificationProgressDrawable extends Drawable {
mChangingConfigurations = orig.mChangingConfigurations;
mSegSegGap = orig.mSegSegGap;
mSegPointGap = orig.mSegPointGap;
+ mSegmentMinWidth = orig.mSegmentMinWidth;
mSegmentHeight = orig.mSegmentHeight;
mFadedSegmentHeight = orig.mFadedSegmentHeight;
mSegmentCornerRadius = orig.mSegmentCornerRadius;
@@ -576,6 +602,18 @@ public final class NotificationProgressDrawable extends Drawable {
}
private void applyDensityScaling(int sourceDensity, int targetDensity) {
+ if (mSegSegGap > 0) {
+ mSegSegGap = scaleFromDensity(
+ mSegSegGap, sourceDensity, targetDensity);
+ }
+ if (mSegPointGap > 0) {
+ mSegPointGap = scaleFromDensity(
+ mSegPointGap, sourceDensity, targetDensity);
+ }
+ if (mSegmentMinWidth > 0) {
+ mSegmentMinWidth = scaleFromDensity(
+ mSegmentMinWidth, sourceDensity, targetDensity);
+ }
if (mSegmentHeight > 0) {
mSegmentHeight = scaleFromDensity(
mSegmentHeight, sourceDensity, targetDensity);
diff --git a/core/res/res/drawable/notification_progress.xml b/core/res/res/drawable/notification_progress.xml
index 5d272fb00e34..ff5450ee106f 100644
--- a/core/res/res/drawable/notification_progress.xml
+++ b/core/res/res/drawable/notification_progress.xml
@@ -24,6 +24,7 @@
android:segPointGap="@dimen/notification_progress_segPoint_gap">
<segments
android:color="?attr/colorProgressBackgroundNormal"
+ android:minWidth="@dimen/notification_progress_segments_min_width"
android:height="@dimen/notification_progress_segments_height"
android:fadedHeight="@dimen/notification_progress_segments_faded_height"
android:cornerRadius="@dimen/notification_progress_segments_corner_radius"/>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 02207f8c7ea4..8372aecf0d27 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -7584,6 +7584,13 @@
<!-- Used to config the segments of a NotificationProgressDrawable. -->
<!-- @hide internal use only -->
<declare-styleable name="NotificationProgressDrawableSegments">
+ <!-- TODO: b/372908709 - maybe move this to NotificationProgressBar, because that's the only
+ place this is used actually. Same for NotificationProgressDrawable.segSegGap/segPointGap
+ above. -->
+ <!-- Minimum required drawing width. The drawing width refers to the width after
+ the original segments have been adjusted for the neighboring Points and gaps. This is
+ enforced by stretching the segments that are too short. -->
+ <attr name="minWidth" format="dimension" />
<!-- Height of the solid segments. -->
<attr name="height" />
<!-- Height of the faded segments. -->
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 2adb79118ed9..593618b086c5 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -888,6 +888,8 @@
<dimen name="notification_progress_segSeg_gap">4dp</dimen>
<!-- The gap between a segment and a point in the notification progress bar -->
<dimen name="notification_progress_segPoint_gap">4dp</dimen>
+ <!-- The minimum required drawing width of the notification progress bar segments -->
+ <dimen name="notification_progress_segments_min_width">16dp</dimen>
<!-- The height of the notification progress bar segments -->
<dimen name="notification_progress_segments_height">6dp</dimen>
<!-- The height of the notification progress bar faded segments -->
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a18f923d625b..3e8e7f6fbc6e 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3939,6 +3939,7 @@
<java-symbol type="dimen" name="notification_progress_tracker_height" />
<java-symbol type="dimen" name="notification_progress_segSeg_gap" />
<java-symbol type="dimen" name="notification_progress_segPoint_gap" />
+ <java-symbol type="dimen" name="notification_progress_segments_min_width" />
<java-symbol type="dimen" name="notification_progress_segments_height" />
<java-symbol type="dimen" name="notification_progress_segments_faded_height" />
<java-symbol type="dimen" name="notification_progress_segments_corner_radius" />
diff --git a/core/tests/coretests/src/com/android/internal/widget/NotificationProgressBarTest.java b/core/tests/coretests/src/com/android/internal/widget/NotificationProgressBarTest.java
index 6a74b4451308..f105ec305eab 100644
--- a/core/tests/coretests/src/com/android/internal/widget/NotificationProgressBarTest.java
+++ b/core/tests/coretests/src/com/android/internal/widget/NotificationProgressBarTest.java
@@ -20,6 +20,7 @@ import static com.google.common.truth.Truth.assertThat;
import android.app.Notification.ProgressStyle;
import android.graphics.Color;
+import android.util.Pair;
import androidx.test.ext.junit.runners.AndroidJUnit4;
@@ -109,9 +110,6 @@ public class NotificationProgressBarTest {
List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(segments, points,
progress, progressMax);
- // Colors with 40% opacity
- int fadedRed = 0x66FF0000;
-
List<Part> expectedParts = new ArrayList<>(List.of(new Segment(1f, Color.RED)));
assertThat(parts).isEqualTo(expectedParts);
@@ -121,17 +119,32 @@ public class NotificationProgressBarTest {
float segPointGap = 4;
float pointRadius = 6;
boolean hasTrackerIcon = true;
- float progressX = 0;
- boolean isStyledByProgress = true;
+
List<NotificationProgressDrawable.Part> drawableParts =
NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
- segSegGap, segPointGap, pointRadius, hasTrackerIcon, progressX,
- isStyledByProgress);
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
- List.of(new NotificationProgressDrawable.Segment(0, 300, fadedRed, true)));
+ List.of(new NotificationProgressDrawable.Segment(0, 300, Color.RED)));
assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 16;
+ boolean isStyledByProgress = true;
+
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 300,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ // Colors with 40% opacity
+ int fadedRed = 0x66FF0000;
+ expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Segment(0, 300, fadedRed, true)));
+
+ assertThat(p.second).isEqualTo(0);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
}
@Test
@@ -154,17 +167,27 @@ public class NotificationProgressBarTest {
float segPointGap = 4;
float pointRadius = 6;
boolean hasTrackerIcon = true;
- float progressX = 300;
- boolean isStyledByProgress = true;
+
List<NotificationProgressDrawable.Part> drawableParts =
NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
- segSegGap, segPointGap, pointRadius, hasTrackerIcon, progressX,
- isStyledByProgress);
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
List.of(new NotificationProgressDrawable.Segment(0, 300, Color.RED)));
assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 16;
+ boolean isStyledByProgress = true;
+
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 300,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ assertThat(p.second).isEqualTo(300);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
}
@Test(expected = IllegalArgumentException.class)
@@ -217,9 +240,6 @@ public class NotificationProgressBarTest {
List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(
segments, points, progress, progressMax);
- // Colors with 40% opacity
- int fadedGreen = 0x6600FF00;
-
List<Part> expectedParts = new ArrayList<>(List.of(
new Segment(0.50f, Color.RED),
new Segment(0.50f, Color.GREEN)));
@@ -231,19 +251,34 @@ public class NotificationProgressBarTest {
float segPointGap = 4;
float pointRadius = 6;
boolean hasTrackerIcon = true;
- float progressX = 180;
- boolean isStyledByProgress = true;
+
List<NotificationProgressDrawable.Part> drawableParts =
NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
- segSegGap, segPointGap, pointRadius, hasTrackerIcon, progressX,
- isStyledByProgress);
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
List.of(new NotificationProgressDrawable.Segment(0, 146, Color.RED),
+ new NotificationProgressDrawable.Segment(150, 300, Color.GREEN)));
+
+ assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 16;
+ boolean isStyledByProgress = true;
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 300,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ // Colors with 40% opacity
+ int fadedGreen = 0x6600FF00;
+ expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Segment(0, 146, Color.RED),
new NotificationProgressDrawable.Segment(150, 180, Color.GREEN),
new NotificationProgressDrawable.Segment(180, 300, fadedGreen, true)));
- assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+ assertThat(p.second).isEqualTo(180);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
}
@Test
@@ -257,9 +292,6 @@ public class NotificationProgressBarTest {
List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(segments, points,
progress, progressMax);
- // Colors with 40% opacity
- int fadedGreen = 0x6600FF00;
-
List<Part> expectedParts = new ArrayList<>(List.of(
new Segment(0.50f, Color.RED),
new Segment(0.50f, Color.GREEN)));
@@ -271,19 +303,34 @@ public class NotificationProgressBarTest {
float segPointGap = 4;
float pointRadius = 6;
boolean hasTrackerIcon = false;
- float progressX = 180;
- boolean isStyledByProgress = true;
+
List<NotificationProgressDrawable.Part> drawableParts =
NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
- segSegGap, segPointGap, pointRadius, hasTrackerIcon, progressX,
- isStyledByProgress);
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
List.of(new NotificationProgressDrawable.Segment(0, 146, Color.RED),
+ new NotificationProgressDrawable.Segment(150, 300, Color.GREEN)));
+
+ assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 16;
+ boolean isStyledByProgress = true;
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 300,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ // Colors with 40% opacity
+ int fadedGreen = 0x6600FF00;
+ expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Segment(0, 146, Color.RED),
new NotificationProgressDrawable.Segment(150, 176, Color.GREEN),
new NotificationProgressDrawable.Segment(180, 300, fadedGreen, true)));
- assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+ assertThat(p.second).isEqualTo(180);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
}
@Test
@@ -298,9 +345,8 @@ public class NotificationProgressBarTest {
int progress = 60;
int progressMax = 100;
- // Colors with 40% opacity
- int fadedBlue = 0x660000FF;
- int fadedYellow = 0x66FFFF00;
+ List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(segments, points,
+ progress, progressMax);
List<Part> expectedParts = new ArrayList<>(List.of(
new Segment(0.15f, Color.BLUE),
@@ -313,9 +359,6 @@ public class NotificationProgressBarTest {
new Point(Color.YELLOW),
new Segment(0.25f, Color.BLUE)));
- List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(segments, points,
- progress, progressMax);
-
assertThat(parts).isEqualTo(expectedParts);
float drawableWidth = 300;
@@ -323,12 +366,11 @@ public class NotificationProgressBarTest {
float segPointGap = 4;
float pointRadius = 6;
boolean hasTrackerIcon = true;
- float progressX = 180;
- boolean isStyledByProgress = true;
+
List<NotificationProgressDrawable.Part> drawableParts =
NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
- segSegGap, segPointGap, pointRadius, hasTrackerIcon, progressX,
- isStyledByProgress);
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
List.of(new NotificationProgressDrawable.Segment(0, 35, Color.BLUE),
@@ -337,11 +379,38 @@ public class NotificationProgressBarTest {
new NotificationProgressDrawable.Point(69, 81, Color.BLUE),
new NotificationProgressDrawable.Segment(85, 170, Color.BLUE),
new NotificationProgressDrawable.Point(174, 186, Color.BLUE),
- new NotificationProgressDrawable.Segment(190, 215, fadedBlue, true),
- new NotificationProgressDrawable.Point(219, 231, fadedYellow),
- new NotificationProgressDrawable.Segment(235, 300, fadedBlue, true)));
+ new NotificationProgressDrawable.Segment(190, 215, Color.BLUE),
+ new NotificationProgressDrawable.Point(219, 231, Color.YELLOW),
+ new NotificationProgressDrawable.Segment(235, 300, Color.BLUE)));
assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 16;
+ boolean isStyledByProgress = true;
+
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 300,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ // Colors with 40% opacity
+ int fadedBlue = 0x660000FF;
+ int fadedYellow = 0x66FFFF00;
+ expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Segment(0, 34.219177F, Color.BLUE),
+ new NotificationProgressDrawable.Point(38.219177F, 50.219177F, Color.RED),
+ new NotificationProgressDrawable.Segment(54.219177F, 70.21918F, Color.BLUE),
+ new NotificationProgressDrawable.Point(74.21918F, 86.21918F, Color.BLUE),
+ new NotificationProgressDrawable.Segment(90.21918F, 172.38356F, Color.BLUE),
+ new NotificationProgressDrawable.Point(176.38356F, 188.38356F, Color.BLUE),
+ new NotificationProgressDrawable.Segment(192.38356F, 217.0137F, fadedBlue,
+ true),
+ new NotificationProgressDrawable.Point(221.0137F, 233.0137F, fadedYellow),
+ new NotificationProgressDrawable.Segment(237.0137F, 300F, fadedBlue,
+ true)));
+
+ assertThat(p.second).isEqualTo(182.38356F);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
}
@Test
@@ -360,10 +429,6 @@ public class NotificationProgressBarTest {
List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(segments, points,
progress, progressMax);
- // Colors with 40% opacity
- int fadedGreen = 0x6600FF00;
- int fadedYellow = 0x66FFFF00;
-
List<Part> expectedParts = new ArrayList<>(List.of(
new Segment(0.15f, Color.RED),
new Point(Color.RED),
@@ -383,12 +448,10 @@ public class NotificationProgressBarTest {
float segPointGap = 4;
float pointRadius = 6;
boolean hasTrackerIcon = true;
- float progressX = 180;
- boolean isStyledByProgress = true;
List<NotificationProgressDrawable.Part> drawableParts =
NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
- segSegGap, segPointGap, pointRadius, hasTrackerIcon, progressX,
- isStyledByProgress);
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
List.of(new NotificationProgressDrawable.Segment(0, 35, Color.RED),
@@ -398,11 +461,41 @@ public class NotificationProgressBarTest {
new NotificationProgressDrawable.Segment(85, 146, Color.RED),
new NotificationProgressDrawable.Segment(150, 170, Color.GREEN),
new NotificationProgressDrawable.Point(174, 186, Color.BLUE),
- new NotificationProgressDrawable.Segment(190, 215, fadedGreen, true),
- new NotificationProgressDrawable.Point(219, 231, fadedYellow),
- new NotificationProgressDrawable.Segment(235, 300, fadedGreen, true)));
+ new NotificationProgressDrawable.Segment(190, 215, Color.GREEN),
+ new NotificationProgressDrawable.Point(219, 231, Color.YELLOW),
+ new NotificationProgressDrawable.Segment(235, 300, Color.GREEN)));
assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 16;
+ boolean isStyledByProgress = true;
+
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 300,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ // Colors with 40% opacity
+ int fadedGreen = 0x6600FF00;
+ int fadedYellow = 0x66FFFF00;
+ expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Segment(0, 34.095238F, Color.RED),
+ new NotificationProgressDrawable.Point(38.095238F, 50.095238F, Color.RED),
+ new NotificationProgressDrawable.Segment(54.095238F, 70.09524F, Color.RED),
+ new NotificationProgressDrawable.Point(74.09524F, 86.09524F, Color.BLUE),
+ new NotificationProgressDrawable.Segment(90.09524F, 148.9524F, Color.RED),
+ new NotificationProgressDrawable.Segment(152.95238F, 172.7619F,
+ Color.GREEN),
+ new NotificationProgressDrawable.Point(176.7619F, 188.7619F, Color.BLUE),
+ new NotificationProgressDrawable.Segment(192.7619F, 217.33333F,
+ fadedGreen, true),
+ new NotificationProgressDrawable.Point(221.33333F, 233.33333F,
+ fadedYellow),
+ new NotificationProgressDrawable.Segment(237.33333F, 299.99997F,
+ fadedGreen, true)));
+
+ assertThat(p.second).isEqualTo(182.7619F);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
}
@Test
@@ -437,12 +530,11 @@ public class NotificationProgressBarTest {
float segPointGap = 4;
float pointRadius = 6;
boolean hasTrackerIcon = true;
- float progressX = 180;
- boolean isStyledByProgress = false;
+
List<NotificationProgressDrawable.Part> drawableParts =
NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
- segSegGap, segPointGap, pointRadius, hasTrackerIcon, progressX,
- isStyledByProgress);
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
List.of(new NotificationProgressDrawable.Segment(0, 35, Color.RED),
@@ -455,5 +547,213 @@ public class NotificationProgressBarTest {
new NotificationProgressDrawable.Segment(235, 300, Color.GREEN)));
assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 16;
+ boolean isStyledByProgress = false;
+
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 300,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Segment(0, 34.296295F, Color.RED),
+ new NotificationProgressDrawable.Point(38.296295F, 50.296295F, Color.RED),
+ new NotificationProgressDrawable.Segment(54.296295F, 70.296295F, Color.RED),
+ new NotificationProgressDrawable.Point(74.296295F, 86.296295F, Color.BLUE),
+ new NotificationProgressDrawable.Segment(90.296295F, 149.62962F, Color.RED),
+ new NotificationProgressDrawable.Segment(153.62962F, 216.8148F,
+ Color.GREEN),
+ new NotificationProgressDrawable.Point(220.81482F, 232.81482F,
+ Color.YELLOW),
+ new NotificationProgressDrawable.Segment(236.81482F, 300, Color.GREEN)));
+
+ assertThat(p.second).isEqualTo(182.9037F);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
+ }
+
+ // The only difference from the `zeroWidthDrawableSegment` test below is the longer
+ // segmentMinWidth (= 16dp).
+ @Test
+ public void maybeStretchAndRescaleSegments_negativeWidthDrawableSegment() {
+ List<ProgressStyle.Segment> segments = new ArrayList<>();
+ segments.add(new ProgressStyle.Segment(100).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(200).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(300).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(400).setColor(Color.BLUE));
+ List<ProgressStyle.Point> points = new ArrayList<>();
+ points.add(new ProgressStyle.Point(0).setColor(Color.BLUE));
+ int progress = 1000;
+ int progressMax = 1000;
+
+ List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(
+ segments, points, progress, progressMax);
+
+ List<Part> expectedParts = new ArrayList<>(List.of(
+ new Point(Color.BLUE),
+ new Segment(0.1f, Color.BLUE),
+ new Segment(0.2f, Color.BLUE),
+ new Segment(0.3f, Color.BLUE),
+ new Segment(0.4f, Color.BLUE)));
+
+ assertThat(parts).isEqualTo(expectedParts);
+
+ float drawableWidth = 200;
+ float segSegGap = 4;
+ float segPointGap = 4;
+ float pointRadius = 6;
+ boolean hasTrackerIcon = true;
+ List<NotificationProgressDrawable.Part> drawableParts =
+ NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
+
+ List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Point(0, 12, Color.BLUE),
+ new NotificationProgressDrawable.Segment(16, 16, Color.BLUE),
+ new NotificationProgressDrawable.Segment(20, 56, Color.BLUE),
+ new NotificationProgressDrawable.Segment(60, 116, Color.BLUE),
+ new NotificationProgressDrawable.Segment(120, 200, Color.BLUE)));
+
+ assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 16;
+ boolean isStyledByProgress = true;
+
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 200,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Point(0, 12, Color.BLUE),
+ new NotificationProgressDrawable.Segment(16, 32, Color.BLUE),
+ new NotificationProgressDrawable.Segment(36, 69.41936F, Color.BLUE),
+ new NotificationProgressDrawable.Segment(73.41936F, 124.25807F, Color.BLUE),
+ new NotificationProgressDrawable.Segment(128.25807F, 200, Color.BLUE)));
+
+ assertThat(p.second).isEqualTo(200);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
+ }
+
+ // The only difference from the `negativeWidthDrawableSegment` test above is the shorter
+ // segmentMinWidth (= 10dp).
+ @Test
+ public void maybeStretchAndRescaleSegments_zeroWidthDrawableSegment() {
+ List<ProgressStyle.Segment> segments = new ArrayList<>();
+ segments.add(new ProgressStyle.Segment(100).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(200).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(300).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(400).setColor(Color.BLUE));
+ List<ProgressStyle.Point> points = new ArrayList<>();
+ points.add(new ProgressStyle.Point(0).setColor(Color.BLUE));
+ int progress = 1000;
+ int progressMax = 1000;
+
+ List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(
+ segments, points, progress, progressMax);
+
+ List<Part> expectedParts = new ArrayList<>(List.of(
+ new Point(Color.BLUE),
+ new Segment(0.1f, Color.BLUE),
+ new Segment(0.2f, Color.BLUE),
+ new Segment(0.3f, Color.BLUE),
+ new Segment(0.4f, Color.BLUE)));
+
+ assertThat(parts).isEqualTo(expectedParts);
+
+ float drawableWidth = 200;
+ float segSegGap = 4;
+ float segPointGap = 4;
+ float pointRadius = 6;
+ boolean hasTrackerIcon = true;
+ List<NotificationProgressDrawable.Part> drawableParts =
+ NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
+
+ List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Point(0, 12, Color.BLUE),
+ new NotificationProgressDrawable.Segment(16, 16, Color.BLUE),
+ new NotificationProgressDrawable.Segment(20, 56, Color.BLUE),
+ new NotificationProgressDrawable.Segment(60, 116, Color.BLUE),
+ new NotificationProgressDrawable.Segment(120, 200, Color.BLUE)));
+
+ assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 10;
+ boolean isStyledByProgress = true;
+
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 200,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Point(0, 12, Color.BLUE),
+ new NotificationProgressDrawable.Segment(16, 26, Color.BLUE),
+ new NotificationProgressDrawable.Segment(30, 64.169014F, Color.BLUE),
+ new NotificationProgressDrawable.Segment(68.169014F, 120.92958F,
+ Color.BLUE),
+ new NotificationProgressDrawable.Segment(124.92958F, 200, Color.BLUE)));
+
+ assertThat(p.second).isEqualTo(200);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
+ }
+
+ @Test
+ public void maybeStretchAndRescaleSegments_noStretchingNecessary() {
+ List<ProgressStyle.Segment> segments = new ArrayList<>();
+ segments.add(new ProgressStyle.Segment(200).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(100).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(300).setColor(Color.BLUE));
+ segments.add(new ProgressStyle.Segment(400).setColor(Color.BLUE));
+ List<ProgressStyle.Point> points = new ArrayList<>();
+ points.add(new ProgressStyle.Point(0).setColor(Color.BLUE));
+ int progress = 1000;
+ int progressMax = 1000;
+
+ List<Part> parts = NotificationProgressBar.processAndConvertToViewParts(
+ segments, points, progress, progressMax);
+
+ List<Part> expectedParts = new ArrayList<>(List.of(
+ new Point(Color.BLUE),
+ new Segment(0.2f, Color.BLUE),
+ new Segment(0.1f, Color.BLUE),
+ new Segment(0.3f, Color.BLUE),
+ new Segment(0.4f, Color.BLUE)));
+
+ assertThat(parts).isEqualTo(expectedParts);
+
+ float drawableWidth = 200;
+ float segSegGap = 4;
+ float segPointGap = 4;
+ float pointRadius = 6;
+ boolean hasTrackerIcon = true;
+
+ List<NotificationProgressDrawable.Part> drawableParts =
+ NotificationProgressBar.processAndConvertToDrawableParts(parts, drawableWidth,
+ segSegGap, segPointGap, pointRadius, hasTrackerIcon
+ );
+
+ List<NotificationProgressDrawable.Part> expectedDrawableParts = new ArrayList<>(
+ List.of(new NotificationProgressDrawable.Point(0, 12, Color.BLUE),
+ new NotificationProgressDrawable.Segment(16, 36, Color.BLUE),
+ new NotificationProgressDrawable.Segment(40, 56, Color.BLUE),
+ new NotificationProgressDrawable.Segment(60, 116, Color.BLUE),
+ new NotificationProgressDrawable.Segment(120, 200, Color.BLUE)));
+
+ assertThat(drawableParts).isEqualTo(expectedDrawableParts);
+
+ float segmentMinWidth = 10;
+ boolean isStyledByProgress = true;
+
+ Pair<List<NotificationProgressDrawable.Part>, Float> p =
+ NotificationProgressBar.maybeStretchAndRescaleSegments(parts, drawableParts,
+ segmentMinWidth, pointRadius, (float) progress / progressMax, 200,
+ isStyledByProgress, hasTrackerIcon ? 0 : segSegGap);
+
+ assertThat(p.second).isEqualTo(200);
+ assertThat(p.first).isEqualTo(expectedDrawableParts);
}
}