Loading core/java/com/android/internal/widget/NotificationProgressBar.java +70 −83 Original line number Diff line number Diff line Loading @@ -42,6 +42,9 @@ import androidx.annotation.ColorInt; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.internal.widget.NotificationProgressDrawable.DrawablePart; import com.android.internal.widget.NotificationProgressDrawable.DrawablePoint; import com.android.internal.widget.NotificationProgressDrawable.DrawableSegment; import java.util.ArrayList; import java.util.HashMap; Loading Loading @@ -71,7 +74,7 @@ public final class NotificationProgressBar extends ProgressBar implements // List of drawable parts before segment splitting by process. @Nullable private List<NotificationProgressDrawable.Part> mProgressDrawableParts = null; private List<DrawablePart> mProgressDrawableParts = null; @Nullable private Drawable mTracker = null; Loading Loading @@ -110,8 +113,8 @@ public final class NotificationProgressBar extends ProgressBar implements int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.NotificationProgressBar, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NotificationProgressBar, defStyleAttr, defStyleRes); saveAttributeDataForStyleable(context, R.styleable.NotificationProgressBar, attrs, a, defStyleAttr, defStyleRes); Loading Loading @@ -141,8 +144,7 @@ public final class NotificationProgressBar extends ProgressBar implements */ @RemotableViewMethod public void setProgressModel(@Nullable Bundle bundle) { Preconditions.checkArgument(bundle != null, "Bundle shouldn't be null"); Preconditions.checkArgument(bundle != null, "Bundle shouldn't be null"); mProgressModel = NotificationProgressModel.fromBundle(bundle); final boolean isIndeterminate = mProgressModel.isIndeterminate(); Loading Loading @@ -382,8 +384,7 @@ public final class NotificationProgressBar extends ProgressBar implements super.drawableStateChanged(); final Drawable tracker = mTracker; if (tracker != null && tracker.isStateful() && tracker.setState(getDrawableState())) { if (tracker != null && tracker.isStateful() && tracker.setState(getDrawableState())) { invalidateDrawable(tracker); } } Loading Loading @@ -446,7 +447,7 @@ public final class NotificationProgressBar extends ProgressBar implements mNotificationProgressDrawable.getPointRadius(), mHasTrackerIcon ); Pair<List<NotificationProgressDrawable.Part>, Float> p = maybeStretchAndRescaleSegments( Pair<List<DrawablePart>, Float> p = maybeStretchAndRescaleSegments( mParts, mProgressDrawableParts, mNotificationProgressDrawable.getSegmentMinWidth(), Loading Loading @@ -539,8 +540,8 @@ public final class NotificationProgressBar extends ProgressBar implements if (background != null) { final int bkgOffsetX = mPaddingLeft; final int bkgOffsetY = mPaddingTop; background.setHotspotBounds(left + bkgOffsetX, top + bkgOffsetY, right + bkgOffsetX, bottom + bkgOffsetY); background.setHotspotBounds(left + bkgOffsetX, top + bkgOffsetY, right + bkgOffsetX, bottom + bkgOffsetY); } // Canvas will be translated, so 0,0 is where we start drawing Loading Loading @@ -675,8 +676,8 @@ public final class NotificationProgressBar extends ProgressBar implements final SortedSet<Integer> sortedPos = generateSortedPositionSet(startToSegmentMap, positionToPointMap); final Map<Integer, ProgressStyle.Segment> startToSplitSegmentMap = splitSegmentsByPoints(startToSegmentMap, sortedPos, progressMax); final Map<Integer, ProgressStyle.Segment> startToSplitSegmentMap = splitSegmentsByPoints( startToSegmentMap, sortedPos, progressMax); return convertToViewParts(startToSplitSegmentMap, positionToPointMap, sortedPos, progressMax); Loading @@ -698,8 +699,7 @@ public final class NotificationProgressBar extends ProgressBar implements final ProgressStyle.Segment prevSeg = startToSegmentMap.get(prevSegStart); final ProgressStyle.Segment leftSeg = new ProgressStyle.Segment( pos - prevSegStart).setColor( prevSeg.getColor()); pos - prevSegStart).setColor(prevSeg.getColor()); final ProgressStyle.Segment rightSeg = new ProgressStyle.Segment( prevSegStart + prevSeg.getLength() - pos).setColor(prevSeg.getColor()); Loading @@ -726,8 +726,7 @@ public final class NotificationProgressBar extends ProgressBar implements } if (startToSegmentMap.containsKey(pos)) { final ProgressStyle.Segment seg = startToSegmentMap.get(pos); parts.add(new Segment( (float) seg.getLength() / progressMax, seg.getColor())); parts.add(new Segment((float) seg.getLength() / progressMax, seg.getColor())); } } Loading Loading @@ -794,11 +793,10 @@ public final class NotificationProgressBar extends ProgressBar implements } /** * Processes the list of {@code Part} and convert to a list of * {@code NotificationProgressDrawable.Part}. * Processes the list of {@code Part} and convert to a list of {@code DrawablePart}. */ @VisibleForTesting public static List<NotificationProgressDrawable.Part> processAndConvertToDrawableParts( public static List<DrawablePart> processAndConvertToDrawableParts( List<Part> parts, float totalWidth, float segSegGap, Loading @@ -806,7 +804,7 @@ public final class NotificationProgressBar extends ProgressBar implements float pointRadius, boolean hasTrackerIcon ) { List<NotificationProgressDrawable.Part> drawableParts = new ArrayList<>(); List<DrawablePart> drawableParts = new ArrayList<>(); // generally, we will start drawing at (x, y) and end at (x+w, y) float x = (float) 0; Loading @@ -827,9 +825,7 @@ public final class NotificationProgressBar extends ProgressBar implements segSegGap, x + segWidth, totalWidth, hasTrackerIcon); final float end = x + segWidth - endOffset; drawableParts.add( new NotificationProgressDrawable.Segment(start, end, segment.mColor, segment.mFaded)); drawableParts.add(new DrawableSegment(start, end, segment.mColor, segment.mFaded)); segment.mStart = x; segment.mEnd = x + segWidth; Loading @@ -847,8 +843,7 @@ public final class NotificationProgressBar extends ProgressBar implements if (totalWidth > pointWidth) start = totalWidth - pointWidth; } drawableParts.add( new NotificationProgressDrawable.Point(start, end, point.mColor)); drawableParts.add(new DrawablePoint(start, end, point.mColor)); } } Loading @@ -863,8 +858,8 @@ public final class NotificationProgressBar extends ProgressBar implements } private static float getSegEndOffset(Segment seg, Part nextPart, float pointRadius, float segPointGap, float segSegGap, float endX, float totalWidth, boolean hasTrackerIcon) { float segPointGap, float segSegGap, float endX, float totalWidth, boolean hasTrackerIcon) { if (nextPart == null) return 0F; if (nextPart instanceof Segment nextSeg) { if (!seg.mFaded && nextSeg.mFaded) { Loading @@ -881,15 +876,14 @@ public final class NotificationProgressBar extends ProgressBar implements } /** * Processes the list of {@code NotificationProgressBar.Part} data and convert to a pair of: * - list of {@code NotificationProgressDrawable.Part}. * Processes the list of {@code DrawablePart} data and convert to a pair of: * - list of processed {@code DrawablePart}. * - location of progress on the stretched and rescaled progress bar. */ @VisibleForTesting public static Pair<List<NotificationProgressDrawable.Part>, Float> maybeStretchAndRescaleSegments( public static Pair<List<DrawablePart>, Float> maybeStretchAndRescaleSegments( List<Part> parts, List<NotificationProgressDrawable.Part> drawableParts, List<DrawablePart> drawableParts, float segmentMinWidth, float pointRadius, float progressFraction, Loading @@ -897,14 +891,14 @@ public final class NotificationProgressBar extends ProgressBar implements boolean isStyledByProgress, float progressGap ) { final List<NotificationProgressDrawable.Segment> drawableSegments = drawableParts final List<DrawableSegment> drawableSegments = drawableParts .stream() .filter(NotificationProgressDrawable.Segment.class::isInstance) .map(NotificationProgressDrawable.Segment.class::cast) .filter(DrawableSegment.class::isInstance) .map(DrawableSegment.class::cast) .toList(); float totalExcessWidth = 0; float totalPositiveExcessWidth = 0; for (NotificationProgressDrawable.Segment drawableSegment : drawableSegments) { for (DrawableSegment drawableSegment : drawableSegments) { final float excessWidth = drawableSegment.getWidth() - segmentMinWidth; totalExcessWidth += excessWidth; if (excessWidth > 0) totalPositiveExcessWidth += excessWidth; Loading Loading @@ -937,8 +931,8 @@ public final class NotificationProgressBar extends ProgressBar implements 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 DrawablePart drawablePart = drawableParts.get(iPart); if (drawablePart instanceof DrawableSegment drawableSegment) { final float origDrawableSegmentWidth = drawableSegment.getWidth(); float drawableSegmentWidth = segmentMinWidth; Loading Loading @@ -967,7 +961,7 @@ public final class NotificationProgressBar extends ProgressBar implements // Increase startOffset for the subsequent segments. startOffset += widthDiff; } else if (drawablePart instanceof NotificationProgressDrawable.Point drawablePoint) { } else if (drawablePart instanceof DrawablePoint drawablePoint) { drawablePoint.setStart(drawablePoint.getStart() + startOffset); drawablePoint.setEnd(drawablePoint.getStart() + 2 * pointRadius); } Loading @@ -982,13 +976,15 @@ public final class NotificationProgressBar extends ProgressBar implements 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( /** * Find the location of progress on the stretched and rescaled progress bar. * If isStyledByProgress is true, also split the drawable segment with the progress value in its * range. Style the drawable parts after process with reduced opacity and segment height. */ private static Pair<List<DrawablePart>, Float> maybeSplitDrawableSegmentsByProgress( // Needed to get the original segment start and end positions in pixels. List<Part> parts, List<NotificationProgressDrawable.Part> drawableParts, List<DrawablePart> drawableParts, float progressFraction, float totalWidth, boolean isStyledByProgress, Loading @@ -1012,8 +1008,8 @@ public final class NotificationProgressBar extends ProgressBar implements } else if (startFraction < progressFraction && progressFraction < startFraction + segment.mFraction) { iPartSegmentToSplit = iPart; rescaledProgressX = segment.mStart + (progressFraction - startFraction) / segment.mFraction rescaledProgressX = segment.mStart + (progressFraction - startFraction) / segment.mFraction * segment.getWidth(); break; } Loading @@ -1022,51 +1018,42 @@ public final class NotificationProgressBar extends ProgressBar implements if (!isStyledByProgress) return new Pair<>(drawableParts, rescaledProgressX); List<NotificationProgressDrawable.Part> splitDrawableParts = new ArrayList<>(); List<DrawablePart> splitDrawableParts = new ArrayList<>(); boolean styleRemainingParts = false; for (int iPart = 0; iPart < nParts; iPart++) { final NotificationProgressDrawable.Part drawablePart = drawableParts.get(iPart); if (drawablePart instanceof NotificationProgressDrawable.Point drawablePoint) { final DrawablePart drawablePart = drawableParts.get(iPart); if (drawablePart instanceof DrawablePoint drawablePoint) { final int color = maybeGetFadedColor(drawablePoint.getColor(), styleRemainingParts); splitDrawableParts.add( new NotificationProgressDrawable.Point(drawablePoint.getStart(), drawablePoint.getEnd(), color)); new DrawablePoint(drawablePoint.getStart(), drawablePoint.getEnd(), color)); } if (iPart == iPartFirstSegmentToStyle) styleRemainingParts = true; if (drawablePart instanceof NotificationProgressDrawable.Segment drawableSegment) { if (drawablePart instanceof DrawableSegment drawableSegment) { if (iPart == iPartSegmentToSplit) { if (rescaledProgressX <= drawableSegment.getStart()) { styleRemainingParts = true; final int color = maybeGetFadedColor(drawableSegment.getColor(), true); splitDrawableParts.add( new NotificationProgressDrawable.Segment(drawableSegment.getStart(), drawableSegment.getEnd(), color, true)); splitDrawableParts.add(new DrawableSegment(drawableSegment.getStart(), drawableSegment.getEnd(), color, true)); } else if (drawableSegment.getStart() < rescaledProgressX && rescaledProgressX < drawableSegment.getEnd()) { splitDrawableParts.add( new NotificationProgressDrawable.Segment(drawableSegment.getStart(), rescaledProgressX - progressGap, drawableSegment.getColor())); splitDrawableParts.add(new DrawableSegment(drawableSegment.getStart(), rescaledProgressX - progressGap, drawableSegment.getColor())); final int color = maybeGetFadedColor(drawableSegment.getColor(), true); splitDrawableParts.add( new NotificationProgressDrawable.Segment(rescaledProgressX, drawableSegment.getEnd(), color, true)); new DrawableSegment(rescaledProgressX, drawableSegment.getEnd(), color, true)); styleRemainingParts = true; } else { splitDrawableParts.add( new NotificationProgressDrawable.Segment(drawableSegment.getStart(), drawableSegment.getEnd(), drawableSegment.getColor())); splitDrawableParts.add(new DrawableSegment(drawableSegment.getStart(), drawableSegment.getEnd(), drawableSegment.getColor())); styleRemainingParts = true; } } else { final int color = maybeGetFadedColor(drawableSegment.getColor(), styleRemainingParts); splitDrawableParts.add( new NotificationProgressDrawable.Segment(drawableSegment.getStart(), drawableSegment.getEnd(), color, styleRemainingParts)); splitDrawableParts.add(new DrawableSegment(drawableSegment.getStart(), drawableSegment.getEnd(), color, styleRemainingParts)); } } } Loading @@ -1080,20 +1067,19 @@ public final class NotificationProgressBar extends ProgressBar implements */ // TODO: b/372908709 - maybe this should be made private? Only test the final // NotificationDrawable.Parts. // TODO: b/372908709 - rename to BarPart, BarSegment, BarPoint. This avoids naming ambiguity // with the types in NotificationProgressDrawable. public interface Part { } /** * A segment is a part of the progress bar with non-zero length. For example, it can * represent a portion in a navigation journey with certain traffic condition. * */ public static final class Segment implements Part { private final float mFraction; @ColorInt private final int mColor; /** Whether the segment is faded or not. @ColorInt private final int mColor; /** * Whether the segment is faded or not. * <p> * <pre> * When mFaded is set to true, a combination of the following is done to the segment: Loading Loading @@ -1157,7 +1143,8 @@ public final class NotificationProgressBar extends ProgressBar implements * ride-share journey. */ public static final class Point implements Part { @ColorInt private final int mColor; @ColorInt private final int mColor; public Point(@ColorInt int color) { mColor = color; Loading core/java/com/android/internal/widget/NotificationProgressDrawable.java +20 −19 Original line number Diff line number Diff line Loading @@ -51,8 +51,8 @@ import java.util.Objects; * segments, which have non-zero length varying drawing width, and points, which have zero length * and fixed size for drawing. * * @see Segment * @see Point * @see DrawableSegment * @see DrawablePoint */ public final class NotificationProgressDrawable extends Drawable { private static final String TAG = "NotifProgressDrawable"; Loading @@ -63,7 +63,7 @@ public final class NotificationProgressDrawable extends Drawable { private State mState; private boolean mMutated; private final ArrayList<Part> mParts = new ArrayList<>(); private final ArrayList<DrawablePart> mParts = new ArrayList<>(); private final RectF mSegRectF = new RectF(); private final RectF mPointRectF = new RectF(); Loading Loading @@ -111,7 +111,7 @@ public final class NotificationProgressDrawable extends Drawable { /** * Set the segments and points that constitute the drawable. */ public void setParts(List<Part> parts) { public void setParts(List<DrawablePart> parts) { mParts.clear(); mParts.addAll(parts); Loading @@ -121,7 +121,7 @@ public final class NotificationProgressDrawable extends Drawable { /** * Set the segments and points that constitute the drawable. */ public void setParts(@NonNull Part... parts) { public void setParts(@NonNull DrawablePart... parts) { setParts(Arrays.asList(parts)); } Loading @@ -133,10 +133,10 @@ public final class NotificationProgressDrawable extends Drawable { final int numParts = mParts.size(); for (int iPart = 0; iPart < numParts; iPart++) { final Part part = mParts.get(iPart); final DrawablePart part = mParts.get(iPart); final float start = left + part.mStart; final float end = left + part.mEnd; if (part instanceof Segment segment) { if (part instanceof DrawableSegment segment) { // No space left to draw the segment if (start > end) continue; Loading @@ -148,7 +148,7 @@ public final class NotificationProgressDrawable extends Drawable { mSegRectF.set(start, centerY - radiusY, end, centerY + radiusY); canvas.drawRoundRect(mSegRectF, cornerRadius, cornerRadius, mFillPaint); } else if (part instanceof Point point) { } else if (part instanceof DrawablePoint point) { // TODO: b/367804171 - actually use a vector asset for the default point // rather than drawing it as a box? mPointRectF.set(start, centerY - pointRadius, end, centerY + pointRadius); Loading Loading @@ -413,10 +413,11 @@ public final class NotificationProgressDrawable extends Drawable { } /** * A part of the progress bar, which is either a {@link Segment} with non-zero length and * varying drawing width, or a {@link Point} with zero length and fixed size for drawing. * A part of the progress drawable, which is either a {@link DrawableSegment} with non-zero * length and varying drawing width, or a {@link DrawablePoint} with zero length and fixed size * for drawing. */ public abstract static class Part { public abstract static class DrawablePart { // TODO: b/372908709 - maybe rename start/end to left/right, to be consistent with the // bounds rect. /** Start position for drawing (in pixels) */ Loading @@ -426,7 +427,7 @@ public final class NotificationProgressDrawable extends Drawable { /** Drawing color. */ @ColorInt protected final int mColor; protected Part(float start, float end, @ColorInt int color) { protected DrawablePart(float start, float end, @ColorInt int color) { mStart = start; mEnd = end; mColor = color; Loading Loading @@ -464,7 +465,7 @@ public final class NotificationProgressDrawable extends Drawable { if (other == null || getClass() != other.getClass()) return false; Part that = (Part) other; DrawablePart that = (DrawablePart) other; if (Float.compare(this.mStart, that.mStart) != 0) return false; if (Float.compare(this.mEnd, that.mEnd) != 0) return false; return this.mColor == that.mColor; Loading @@ -484,7 +485,7 @@ public final class NotificationProgressDrawable extends Drawable { * the Points and gaps neighboring the segment. * </p> */ public static final class Segment extends Part { public static final class DrawableSegment extends DrawablePart { /** * Whether the segment is faded or not. * <p> Loading @@ -493,11 +494,11 @@ public final class NotificationProgressDrawable extends Drawable { */ private final boolean mFaded; public Segment(float start, float end, int color) { public DrawableSegment(float start, float end, int color) { this(start, end, color, false); } public Segment(float start, float end, int color, boolean faded) { public DrawableSegment(float start, float end, int color, boolean faded) { super(start, end, color); mFaded = faded; } Loading @@ -513,7 +514,7 @@ public final class NotificationProgressDrawable extends Drawable { public boolean equals(@Nullable Object other) { if (!super.equals(other)) return false; Segment that = (Segment) other; DrawableSegment that = (DrawableSegment) other; return this.mFaded == that.mFaded; } Loading @@ -528,8 +529,8 @@ public final class NotificationProgressDrawable extends Drawable { * progress bar to visualize distinct stages or milestones. For example, a stop in a multi-stop * ride-share journey. */ public static final class Point extends Part { public Point(float start, float end, int color) { public static final class DrawablePoint extends DrawablePart { public DrawablePoint(float start, float end, int color) { super(start, end, color); } Loading core/tests/coretests/src/com/android/internal/widget/NotificationProgressBarTest.java +199 −262 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/com/android/internal/widget/NotificationProgressBar.java +70 −83 Original line number Diff line number Diff line Loading @@ -42,6 +42,9 @@ import androidx.annotation.ColorInt; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.util.Preconditions; import com.android.internal.widget.NotificationProgressDrawable.DrawablePart; import com.android.internal.widget.NotificationProgressDrawable.DrawablePoint; import com.android.internal.widget.NotificationProgressDrawable.DrawableSegment; import java.util.ArrayList; import java.util.HashMap; Loading Loading @@ -71,7 +74,7 @@ public final class NotificationProgressBar extends ProgressBar implements // List of drawable parts before segment splitting by process. @Nullable private List<NotificationProgressDrawable.Part> mProgressDrawableParts = null; private List<DrawablePart> mProgressDrawableParts = null; @Nullable private Drawable mTracker = null; Loading Loading @@ -110,8 +113,8 @@ public final class NotificationProgressBar extends ProgressBar implements int defStyleRes) { super(context, attrs, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes( attrs, R.styleable.NotificationProgressBar, defStyleAttr, defStyleRes); final TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.NotificationProgressBar, defStyleAttr, defStyleRes); saveAttributeDataForStyleable(context, R.styleable.NotificationProgressBar, attrs, a, defStyleAttr, defStyleRes); Loading Loading @@ -141,8 +144,7 @@ public final class NotificationProgressBar extends ProgressBar implements */ @RemotableViewMethod public void setProgressModel(@Nullable Bundle bundle) { Preconditions.checkArgument(bundle != null, "Bundle shouldn't be null"); Preconditions.checkArgument(bundle != null, "Bundle shouldn't be null"); mProgressModel = NotificationProgressModel.fromBundle(bundle); final boolean isIndeterminate = mProgressModel.isIndeterminate(); Loading Loading @@ -382,8 +384,7 @@ public final class NotificationProgressBar extends ProgressBar implements super.drawableStateChanged(); final Drawable tracker = mTracker; if (tracker != null && tracker.isStateful() && tracker.setState(getDrawableState())) { if (tracker != null && tracker.isStateful() && tracker.setState(getDrawableState())) { invalidateDrawable(tracker); } } Loading Loading @@ -446,7 +447,7 @@ public final class NotificationProgressBar extends ProgressBar implements mNotificationProgressDrawable.getPointRadius(), mHasTrackerIcon ); Pair<List<NotificationProgressDrawable.Part>, Float> p = maybeStretchAndRescaleSegments( Pair<List<DrawablePart>, Float> p = maybeStretchAndRescaleSegments( mParts, mProgressDrawableParts, mNotificationProgressDrawable.getSegmentMinWidth(), Loading Loading @@ -539,8 +540,8 @@ public final class NotificationProgressBar extends ProgressBar implements if (background != null) { final int bkgOffsetX = mPaddingLeft; final int bkgOffsetY = mPaddingTop; background.setHotspotBounds(left + bkgOffsetX, top + bkgOffsetY, right + bkgOffsetX, bottom + bkgOffsetY); background.setHotspotBounds(left + bkgOffsetX, top + bkgOffsetY, right + bkgOffsetX, bottom + bkgOffsetY); } // Canvas will be translated, so 0,0 is where we start drawing Loading Loading @@ -675,8 +676,8 @@ public final class NotificationProgressBar extends ProgressBar implements final SortedSet<Integer> sortedPos = generateSortedPositionSet(startToSegmentMap, positionToPointMap); final Map<Integer, ProgressStyle.Segment> startToSplitSegmentMap = splitSegmentsByPoints(startToSegmentMap, sortedPos, progressMax); final Map<Integer, ProgressStyle.Segment> startToSplitSegmentMap = splitSegmentsByPoints( startToSegmentMap, sortedPos, progressMax); return convertToViewParts(startToSplitSegmentMap, positionToPointMap, sortedPos, progressMax); Loading @@ -698,8 +699,7 @@ public final class NotificationProgressBar extends ProgressBar implements final ProgressStyle.Segment prevSeg = startToSegmentMap.get(prevSegStart); final ProgressStyle.Segment leftSeg = new ProgressStyle.Segment( pos - prevSegStart).setColor( prevSeg.getColor()); pos - prevSegStart).setColor(prevSeg.getColor()); final ProgressStyle.Segment rightSeg = new ProgressStyle.Segment( prevSegStart + prevSeg.getLength() - pos).setColor(prevSeg.getColor()); Loading @@ -726,8 +726,7 @@ public final class NotificationProgressBar extends ProgressBar implements } if (startToSegmentMap.containsKey(pos)) { final ProgressStyle.Segment seg = startToSegmentMap.get(pos); parts.add(new Segment( (float) seg.getLength() / progressMax, seg.getColor())); parts.add(new Segment((float) seg.getLength() / progressMax, seg.getColor())); } } Loading Loading @@ -794,11 +793,10 @@ public final class NotificationProgressBar extends ProgressBar implements } /** * Processes the list of {@code Part} and convert to a list of * {@code NotificationProgressDrawable.Part}. * Processes the list of {@code Part} and convert to a list of {@code DrawablePart}. */ @VisibleForTesting public static List<NotificationProgressDrawable.Part> processAndConvertToDrawableParts( public static List<DrawablePart> processAndConvertToDrawableParts( List<Part> parts, float totalWidth, float segSegGap, Loading @@ -806,7 +804,7 @@ public final class NotificationProgressBar extends ProgressBar implements float pointRadius, boolean hasTrackerIcon ) { List<NotificationProgressDrawable.Part> drawableParts = new ArrayList<>(); List<DrawablePart> drawableParts = new ArrayList<>(); // generally, we will start drawing at (x, y) and end at (x+w, y) float x = (float) 0; Loading @@ -827,9 +825,7 @@ public final class NotificationProgressBar extends ProgressBar implements segSegGap, x + segWidth, totalWidth, hasTrackerIcon); final float end = x + segWidth - endOffset; drawableParts.add( new NotificationProgressDrawable.Segment(start, end, segment.mColor, segment.mFaded)); drawableParts.add(new DrawableSegment(start, end, segment.mColor, segment.mFaded)); segment.mStart = x; segment.mEnd = x + segWidth; Loading @@ -847,8 +843,7 @@ public final class NotificationProgressBar extends ProgressBar implements if (totalWidth > pointWidth) start = totalWidth - pointWidth; } drawableParts.add( new NotificationProgressDrawable.Point(start, end, point.mColor)); drawableParts.add(new DrawablePoint(start, end, point.mColor)); } } Loading @@ -863,8 +858,8 @@ public final class NotificationProgressBar extends ProgressBar implements } private static float getSegEndOffset(Segment seg, Part nextPart, float pointRadius, float segPointGap, float segSegGap, float endX, float totalWidth, boolean hasTrackerIcon) { float segPointGap, float segSegGap, float endX, float totalWidth, boolean hasTrackerIcon) { if (nextPart == null) return 0F; if (nextPart instanceof Segment nextSeg) { if (!seg.mFaded && nextSeg.mFaded) { Loading @@ -881,15 +876,14 @@ public final class NotificationProgressBar extends ProgressBar implements } /** * Processes the list of {@code NotificationProgressBar.Part} data and convert to a pair of: * - list of {@code NotificationProgressDrawable.Part}. * Processes the list of {@code DrawablePart} data and convert to a pair of: * - list of processed {@code DrawablePart}. * - location of progress on the stretched and rescaled progress bar. */ @VisibleForTesting public static Pair<List<NotificationProgressDrawable.Part>, Float> maybeStretchAndRescaleSegments( public static Pair<List<DrawablePart>, Float> maybeStretchAndRescaleSegments( List<Part> parts, List<NotificationProgressDrawable.Part> drawableParts, List<DrawablePart> drawableParts, float segmentMinWidth, float pointRadius, float progressFraction, Loading @@ -897,14 +891,14 @@ public final class NotificationProgressBar extends ProgressBar implements boolean isStyledByProgress, float progressGap ) { final List<NotificationProgressDrawable.Segment> drawableSegments = drawableParts final List<DrawableSegment> drawableSegments = drawableParts .stream() .filter(NotificationProgressDrawable.Segment.class::isInstance) .map(NotificationProgressDrawable.Segment.class::cast) .filter(DrawableSegment.class::isInstance) .map(DrawableSegment.class::cast) .toList(); float totalExcessWidth = 0; float totalPositiveExcessWidth = 0; for (NotificationProgressDrawable.Segment drawableSegment : drawableSegments) { for (DrawableSegment drawableSegment : drawableSegments) { final float excessWidth = drawableSegment.getWidth() - segmentMinWidth; totalExcessWidth += excessWidth; if (excessWidth > 0) totalPositiveExcessWidth += excessWidth; Loading Loading @@ -937,8 +931,8 @@ public final class NotificationProgressBar extends ProgressBar implements 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 DrawablePart drawablePart = drawableParts.get(iPart); if (drawablePart instanceof DrawableSegment drawableSegment) { final float origDrawableSegmentWidth = drawableSegment.getWidth(); float drawableSegmentWidth = segmentMinWidth; Loading Loading @@ -967,7 +961,7 @@ public final class NotificationProgressBar extends ProgressBar implements // Increase startOffset for the subsequent segments. startOffset += widthDiff; } else if (drawablePart instanceof NotificationProgressDrawable.Point drawablePoint) { } else if (drawablePart instanceof DrawablePoint drawablePoint) { drawablePoint.setStart(drawablePoint.getStart() + startOffset); drawablePoint.setEnd(drawablePoint.getStart() + 2 * pointRadius); } Loading @@ -982,13 +976,15 @@ public final class NotificationProgressBar extends ProgressBar implements 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( /** * Find the location of progress on the stretched and rescaled progress bar. * If isStyledByProgress is true, also split the drawable segment with the progress value in its * range. Style the drawable parts after process with reduced opacity and segment height. */ private static Pair<List<DrawablePart>, Float> maybeSplitDrawableSegmentsByProgress( // Needed to get the original segment start and end positions in pixels. List<Part> parts, List<NotificationProgressDrawable.Part> drawableParts, List<DrawablePart> drawableParts, float progressFraction, float totalWidth, boolean isStyledByProgress, Loading @@ -1012,8 +1008,8 @@ public final class NotificationProgressBar extends ProgressBar implements } else if (startFraction < progressFraction && progressFraction < startFraction + segment.mFraction) { iPartSegmentToSplit = iPart; rescaledProgressX = segment.mStart + (progressFraction - startFraction) / segment.mFraction rescaledProgressX = segment.mStart + (progressFraction - startFraction) / segment.mFraction * segment.getWidth(); break; } Loading @@ -1022,51 +1018,42 @@ public final class NotificationProgressBar extends ProgressBar implements if (!isStyledByProgress) return new Pair<>(drawableParts, rescaledProgressX); List<NotificationProgressDrawable.Part> splitDrawableParts = new ArrayList<>(); List<DrawablePart> splitDrawableParts = new ArrayList<>(); boolean styleRemainingParts = false; for (int iPart = 0; iPart < nParts; iPart++) { final NotificationProgressDrawable.Part drawablePart = drawableParts.get(iPart); if (drawablePart instanceof NotificationProgressDrawable.Point drawablePoint) { final DrawablePart drawablePart = drawableParts.get(iPart); if (drawablePart instanceof DrawablePoint drawablePoint) { final int color = maybeGetFadedColor(drawablePoint.getColor(), styleRemainingParts); splitDrawableParts.add( new NotificationProgressDrawable.Point(drawablePoint.getStart(), drawablePoint.getEnd(), color)); new DrawablePoint(drawablePoint.getStart(), drawablePoint.getEnd(), color)); } if (iPart == iPartFirstSegmentToStyle) styleRemainingParts = true; if (drawablePart instanceof NotificationProgressDrawable.Segment drawableSegment) { if (drawablePart instanceof DrawableSegment drawableSegment) { if (iPart == iPartSegmentToSplit) { if (rescaledProgressX <= drawableSegment.getStart()) { styleRemainingParts = true; final int color = maybeGetFadedColor(drawableSegment.getColor(), true); splitDrawableParts.add( new NotificationProgressDrawable.Segment(drawableSegment.getStart(), drawableSegment.getEnd(), color, true)); splitDrawableParts.add(new DrawableSegment(drawableSegment.getStart(), drawableSegment.getEnd(), color, true)); } else if (drawableSegment.getStart() < rescaledProgressX && rescaledProgressX < drawableSegment.getEnd()) { splitDrawableParts.add( new NotificationProgressDrawable.Segment(drawableSegment.getStart(), rescaledProgressX - progressGap, drawableSegment.getColor())); splitDrawableParts.add(new DrawableSegment(drawableSegment.getStart(), rescaledProgressX - progressGap, drawableSegment.getColor())); final int color = maybeGetFadedColor(drawableSegment.getColor(), true); splitDrawableParts.add( new NotificationProgressDrawable.Segment(rescaledProgressX, drawableSegment.getEnd(), color, true)); new DrawableSegment(rescaledProgressX, drawableSegment.getEnd(), color, true)); styleRemainingParts = true; } else { splitDrawableParts.add( new NotificationProgressDrawable.Segment(drawableSegment.getStart(), drawableSegment.getEnd(), drawableSegment.getColor())); splitDrawableParts.add(new DrawableSegment(drawableSegment.getStart(), drawableSegment.getEnd(), drawableSegment.getColor())); styleRemainingParts = true; } } else { final int color = maybeGetFadedColor(drawableSegment.getColor(), styleRemainingParts); splitDrawableParts.add( new NotificationProgressDrawable.Segment(drawableSegment.getStart(), drawableSegment.getEnd(), color, styleRemainingParts)); splitDrawableParts.add(new DrawableSegment(drawableSegment.getStart(), drawableSegment.getEnd(), color, styleRemainingParts)); } } } Loading @@ -1080,20 +1067,19 @@ public final class NotificationProgressBar extends ProgressBar implements */ // TODO: b/372908709 - maybe this should be made private? Only test the final // NotificationDrawable.Parts. // TODO: b/372908709 - rename to BarPart, BarSegment, BarPoint. This avoids naming ambiguity // with the types in NotificationProgressDrawable. public interface Part { } /** * A segment is a part of the progress bar with non-zero length. For example, it can * represent a portion in a navigation journey with certain traffic condition. * */ public static final class Segment implements Part { private final float mFraction; @ColorInt private final int mColor; /** Whether the segment is faded or not. @ColorInt private final int mColor; /** * Whether the segment is faded or not. * <p> * <pre> * When mFaded is set to true, a combination of the following is done to the segment: Loading Loading @@ -1157,7 +1143,8 @@ public final class NotificationProgressBar extends ProgressBar implements * ride-share journey. */ public static final class Point implements Part { @ColorInt private final int mColor; @ColorInt private final int mColor; public Point(@ColorInt int color) { mColor = color; Loading
core/java/com/android/internal/widget/NotificationProgressDrawable.java +20 −19 Original line number Diff line number Diff line Loading @@ -51,8 +51,8 @@ import java.util.Objects; * segments, which have non-zero length varying drawing width, and points, which have zero length * and fixed size for drawing. * * @see Segment * @see Point * @see DrawableSegment * @see DrawablePoint */ public final class NotificationProgressDrawable extends Drawable { private static final String TAG = "NotifProgressDrawable"; Loading @@ -63,7 +63,7 @@ public final class NotificationProgressDrawable extends Drawable { private State mState; private boolean mMutated; private final ArrayList<Part> mParts = new ArrayList<>(); private final ArrayList<DrawablePart> mParts = new ArrayList<>(); private final RectF mSegRectF = new RectF(); private final RectF mPointRectF = new RectF(); Loading Loading @@ -111,7 +111,7 @@ public final class NotificationProgressDrawable extends Drawable { /** * Set the segments and points that constitute the drawable. */ public void setParts(List<Part> parts) { public void setParts(List<DrawablePart> parts) { mParts.clear(); mParts.addAll(parts); Loading @@ -121,7 +121,7 @@ public final class NotificationProgressDrawable extends Drawable { /** * Set the segments and points that constitute the drawable. */ public void setParts(@NonNull Part... parts) { public void setParts(@NonNull DrawablePart... parts) { setParts(Arrays.asList(parts)); } Loading @@ -133,10 +133,10 @@ public final class NotificationProgressDrawable extends Drawable { final int numParts = mParts.size(); for (int iPart = 0; iPart < numParts; iPart++) { final Part part = mParts.get(iPart); final DrawablePart part = mParts.get(iPart); final float start = left + part.mStart; final float end = left + part.mEnd; if (part instanceof Segment segment) { if (part instanceof DrawableSegment segment) { // No space left to draw the segment if (start > end) continue; Loading @@ -148,7 +148,7 @@ public final class NotificationProgressDrawable extends Drawable { mSegRectF.set(start, centerY - radiusY, end, centerY + radiusY); canvas.drawRoundRect(mSegRectF, cornerRadius, cornerRadius, mFillPaint); } else if (part instanceof Point point) { } else if (part instanceof DrawablePoint point) { // TODO: b/367804171 - actually use a vector asset for the default point // rather than drawing it as a box? mPointRectF.set(start, centerY - pointRadius, end, centerY + pointRadius); Loading Loading @@ -413,10 +413,11 @@ public final class NotificationProgressDrawable extends Drawable { } /** * A part of the progress bar, which is either a {@link Segment} with non-zero length and * varying drawing width, or a {@link Point} with zero length and fixed size for drawing. * A part of the progress drawable, which is either a {@link DrawableSegment} with non-zero * length and varying drawing width, or a {@link DrawablePoint} with zero length and fixed size * for drawing. */ public abstract static class Part { public abstract static class DrawablePart { // TODO: b/372908709 - maybe rename start/end to left/right, to be consistent with the // bounds rect. /** Start position for drawing (in pixels) */ Loading @@ -426,7 +427,7 @@ public final class NotificationProgressDrawable extends Drawable { /** Drawing color. */ @ColorInt protected final int mColor; protected Part(float start, float end, @ColorInt int color) { protected DrawablePart(float start, float end, @ColorInt int color) { mStart = start; mEnd = end; mColor = color; Loading Loading @@ -464,7 +465,7 @@ public final class NotificationProgressDrawable extends Drawable { if (other == null || getClass() != other.getClass()) return false; Part that = (Part) other; DrawablePart that = (DrawablePart) other; if (Float.compare(this.mStart, that.mStart) != 0) return false; if (Float.compare(this.mEnd, that.mEnd) != 0) return false; return this.mColor == that.mColor; Loading @@ -484,7 +485,7 @@ public final class NotificationProgressDrawable extends Drawable { * the Points and gaps neighboring the segment. * </p> */ public static final class Segment extends Part { public static final class DrawableSegment extends DrawablePart { /** * Whether the segment is faded or not. * <p> Loading @@ -493,11 +494,11 @@ public final class NotificationProgressDrawable extends Drawable { */ private final boolean mFaded; public Segment(float start, float end, int color) { public DrawableSegment(float start, float end, int color) { this(start, end, color, false); } public Segment(float start, float end, int color, boolean faded) { public DrawableSegment(float start, float end, int color, boolean faded) { super(start, end, color); mFaded = faded; } Loading @@ -513,7 +514,7 @@ public final class NotificationProgressDrawable extends Drawable { public boolean equals(@Nullable Object other) { if (!super.equals(other)) return false; Segment that = (Segment) other; DrawableSegment that = (DrawableSegment) other; return this.mFaded == that.mFaded; } Loading @@ -528,8 +529,8 @@ public final class NotificationProgressDrawable extends Drawable { * progress bar to visualize distinct stages or milestones. For example, a stop in a multi-stop * ride-share journey. */ public static final class Point extends Part { public Point(float start, float end, int color) { public static final class DrawablePoint extends DrawablePart { public DrawablePoint(float start, float end, int color) { super(start, end, color); } Loading
core/tests/coretests/src/com/android/internal/widget/NotificationProgressBarTest.java +199 −262 File changed.Preview size limit exceeded, changes collapsed. Show changes