| Index: chrome/browser/download/download_shelf.cc | 
| diff --git a/chrome/browser/download/download_shelf.cc b/chrome/browser/download/download_shelf.cc | 
| index d120fe2e3270e5a7051eb5def0e01589e0060ef3..9bc203def5eafab99fc6af8326fd602358f712aa 100644 | 
| --- a/chrome/browser/download/download_shelf.cc | 
| +++ b/chrome/browser/download/download_shelf.cc | 
| @@ -14,6 +14,7 @@ | 
| #include "base/single_thread_task_runner.h" | 
| #include "base/strings/string_number_conversions.h" | 
| #include "base/thread_task_runner_handle.h" | 
| +#include "base/time/time.h" | 
| #include "chrome/browser/download/download_item_model.h" | 
| #include "chrome/browser/download/download_service.h" | 
| #include "chrome/browser/download/download_service_factory.h" | 
| @@ -28,11 +29,12 @@ | 
| #include "content/public/browser/download_manager.h" | 
| #include "content/public/browser/web_contents.h" | 
| #include "grit/theme_resources.h" | 
| +#include "third_party/skia/include/core/SkPaint.h" | 
| +#include "third_party/skia/include/core/SkPath.h" | 
| #include "ui/base/l10n/l10n_util.h" | 
| #include "ui/base/resource/resource_bundle.h" | 
| #include "ui/gfx/animation/animation.h" | 
| #include "ui/gfx/canvas.h" | 
| -#include "ui/gfx/image/image_skia.h" | 
|  | 
| using content::DownloadItem; | 
|  | 
| @@ -66,115 +68,63 @@ DownloadShelf::~DownloadShelf() {} | 
|  | 
| // Download progress painting -------------------------------------------------- | 
|  | 
| -// Common images used for download progress animations. We load them once the | 
| -// first time we do a progress paint, then reuse them as they are always the | 
| -// same. | 
| -gfx::ImageSkia* g_foreground_16 = NULL; | 
| -gfx::ImageSkia* g_background_16 = NULL; | 
| - | 
| // static | 
| void DownloadShelf::PaintDownloadProgress( | 
| gfx::Canvas* canvas, | 
| -    const BoundsAdjusterCallback& rtl_mirror, | 
| -    int origin_x, | 
| -    int origin_y, | 
| -    int start_angle, | 
| +    const base::TimeTicks& progress_start_time, | 
| int percent_done) { | 
| -  // Load up our common images. | 
| -  if (!g_background_16) { | 
| -    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 
| -    g_foreground_16 = rb.GetImageSkiaNamed(IDR_DOWNLOAD_PROGRESS_FOREGROUND_16); | 
| -    g_background_16 = rb.GetImageSkiaNamed(IDR_DOWNLOAD_PROGRESS_BACKGROUND_16); | 
| -    DCHECK_EQ(g_foreground_16->width(), g_background_16->width()); | 
| -    DCHECK_EQ(g_foreground_16->height(), g_background_16->height()); | 
| -  } | 
| - | 
| -  // We start by storing the bounds of the images so that it is easy to mirror | 
| -  // the bounds if the UI layout is RTL. | 
| -  gfx::Rect bounds(origin_x, origin_y, g_background_16->width(), | 
| -                   g_background_16->height()); | 
| - | 
| -  // Mirror the positions if necessary. | 
| -  rtl_mirror.Run(&bounds); | 
| - | 
| -  // Draw the background progress image. | 
| -  canvas->DrawImageInt(*g_background_16, bounds.x(), bounds.y()); | 
| - | 
| -  // Layer the foreground progress image in an arc proportional to the download | 
| -  // progress. The arc grows clockwise, starting in the midnight position, as | 
| -  // the download progresses. However, if the download does not have known total | 
| -  // size (the server didn't give us one), then we just spin an arc around until | 
| -  // we're done. | 
| -  float sweep_angle = 0.0; | 
| -  float start_pos = static_cast<float>(kStartAngleDegrees); | 
| +  // Draw background (light blue circle). | 
| +  SkPaint bg_paint; | 
| +  bg_paint.setStyle(SkPaint::kFill_Style); | 
| +  bg_paint.setColor(SkColorSetRGB(0xD7, 0xE4, 0xFA)); | 
| +  bg_paint.setAntiAlias(true); | 
| +  SkPath bg; | 
| +  bg.addCircle(20, 20, 13); | 
| +  canvas->DrawPath(bg, bg_paint); | 
| + | 
| +  // Calculate progress. | 
| +  SkScalar sweep_angle = 0.f; | 
| +  // Start at 12 o'clock. | 
| +  SkScalar start_pos = SkIntToScalar(270); | 
| if (percent_done < 0) { | 
| -    sweep_angle = kUnknownAngleDegrees; | 
| -    start_pos = static_cast<float>(start_angle); | 
| +    // For unknown size downloads, draw a 50 degree sweep that moves at | 
| +    // 0.08 degrees per millisecond. | 
| +    sweep_angle = 50.f; | 
| +    start_pos += static_cast<SkScalar>( | 
| +        (base::TimeTicks::Now() - progress_start_time).InMilliseconds() * 0.08); | 
| } else if (percent_done > 0) { | 
| -    sweep_angle = static_cast<float>(kMaxDegrees / 100.0 * percent_done); | 
| +    sweep_angle = static_cast<SkScalar>(360 * percent_done / 100.0); | 
| } | 
|  | 
| -  // Set up an arc clipping region for the foreground image. Don't bother using | 
| -  // a clipping region if it would round to 360 (really 0) degrees, since that | 
| -  // would eliminate the foreground completely and be quite confusing (it would | 
| -  // look like 0% complete when it should be almost 100%). | 
| -  canvas->Save(); | 
| -  if (sweep_angle < static_cast<float>(kMaxDegrees - 1)) { | 
| -    SkRect oval; | 
| -    oval.set(SkIntToScalar(bounds.x()), SkIntToScalar(bounds.y()), | 
| -             SkIntToScalar(bounds.x() + DownloadShelf::kSmallProgressIconSize), | 
| -             SkIntToScalar(bounds.y() + DownloadShelf::kSmallProgressIconSize)); | 
| -    SkPath path; | 
| -    path.arcTo(oval, | 
| -               SkFloatToScalar(start_pos), | 
| -               SkFloatToScalar(sweep_angle), false); | 
| -    path.lineTo( | 
| -        SkIntToScalar(bounds.x() + DownloadShelf::kSmallProgressIconSize / 2), | 
| -        SkIntToScalar(bounds.y() + DownloadShelf::kSmallProgressIconSize / 2)); | 
| - | 
| -    // gfx::Canvas::ClipPath does not provide for anti-aliasing. | 
| -    canvas->sk_canvas()->clipPath(path, SkRegion::kIntersect_Op, true); | 
| -  } | 
| - | 
| -  canvas->DrawImageInt(*g_foreground_16, bounds.x(), bounds.y()); | 
| -  canvas->Restore(); | 
| +  // Draw progress. | 
| +  SkPath progress; | 
| +  progress.addArc(SkRect::MakeXYWH(7, 7, 25, 25), start_pos, sweep_angle); | 
| +  SkPaint progress_paint; | 
| +  progress_paint.setColor(SkColorSetRGB(0x41, 0x84, 0xF4)); | 
| +  progress_paint.setStyle(SkPaint::kStroke_Style); | 
| +  progress_paint.setStrokeWidth(1.7f); | 
| +  progress_paint.setAntiAlias(true); | 
| +  canvas->DrawPath(progress, progress_paint); | 
| } | 
|  | 
| // static | 
| void DownloadShelf::PaintDownloadComplete( | 
| gfx::Canvas* canvas, | 
| -    const BoundsAdjusterCallback& rtl_mirror, | 
| -    int origin_x, | 
| -    int origin_y, | 
| double animation_progress) { | 
| -  // Load up our common images. | 
| -  if (!g_foreground_16) { | 
| -    ui::ResourceBundle& rb = ui::ResourceBundle::GetSharedInstance(); | 
| -    g_foreground_16 = rb.GetImageSkiaNamed(IDR_DOWNLOAD_PROGRESS_FOREGROUND_16); | 
| -  } | 
| - | 
| -  gfx::Rect complete_bounds(origin_x, origin_y, g_foreground_16->width(), | 
| -                            g_foreground_16->height()); | 
| -  // Mirror the positions if necessary. | 
| -  rtl_mirror.Run(&complete_bounds); | 
| - | 
| // Start at full opacity, then loop back and forth five times before ending | 
| // at zero opacity. | 
| -  canvas->DrawImageInt(*g_foreground_16, complete_bounds.x(), | 
| -                       complete_bounds.y(), GetOpacity(animation_progress)); | 
| +  canvas->sk_canvas()->saveLayerAlpha(nullptr, GetOpacity(animation_progress)); | 
| +  PaintDownloadProgress(canvas, base::TimeTicks(), 100); | 
| +  canvas->sk_canvas()->restore(); | 
| } | 
|  | 
| // static | 
| void DownloadShelf::PaintDownloadInterrupted( | 
| gfx::Canvas* canvas, | 
| -    const BoundsAdjusterCallback& rtl_mirror, | 
| -    int origin_x, | 
| -    int origin_y, | 
| double animation_progress) { | 
| // Start at zero opacity, then loop back and forth five times before ending | 
| // at full opacity. | 
| -  PaintDownloadComplete(canvas, rtl_mirror, origin_x, origin_y, | 
| -                        1.0 - animation_progress); | 
| +  PaintDownloadComplete(canvas, 1.0 - animation_progress); | 
| } | 
|  | 
| void DownloadShelf::AddDownload(DownloadItem* download) { | 
|  |