[go: up one dir, main page]

Revert "Change throbber (spinner) on tab strip to comply with material design"

> The previous model was to rotate a static image resource. We are replacing
> it by a new model where the head revolves around the center while the tail
> catches the head once in a while in an accelerated manner.
>
> Instead of decoding throbber.svg file, we are calling paint_throbber.cc to
> avoid file access. Caching was considered, but as you can see in
> paint_throbber.cc, it would take quite a long time to get to the origin
> because of its graphical nature, so caching would not be very efficient.
>
> One visual caveat is that the current frame rate is limited to ~16 FPS
> inside StripLayoutHelper, so the motion will stutter a bit when the user
> is not taking any action. However, increasing FPS may have an adverse
> effect on power consumption and performance, and some say it is hardly
> noticeable, so I'll take care of it in a separate CL if many point it out.
>
> BUG=489488
> Committed: https://crrev.com/876f67c762ce45e8f2bc9741e61b2b344d511073
> Cr-Commit-Position: refs/heads/master@{#332168}

BUG=489488,513387

Review URL: https://codereview.chromium.org/1298093004 .

Cr-Commit-Position: refs/branch-heads/2454@{#427}
Cr-Branched-From: 12bfc3360892ec53cd00fc239a47e5298beb063b-refs/heads/master@{#338390}
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
index a4bfc875..2eac99d 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/overlays/strip/StripLayoutTab.java
@@ -84,6 +84,8 @@
     // Content Animations
     private ChromeAnimation<Animatable<?>> mContentAnimations;
 
+    private float mLoadingSpinnerRotationDegrees;
+
     // Preallocated
     private final RectF mClosePlacement = new RectF();
 
@@ -204,6 +206,21 @@
     }
 
     /**
+     * @return The rotation of the loading spinner in degrees.
+     */
+    public float getLoadingSpinnerRotation() {
+        return mLoadingSpinnerRotationDegrees;
+    }
+
+    /**
+     * Additive spinner rotation update.
+     * @param rotation The amount to rotate the spinner by in degrees.
+     */
+    public void addLoadingSpinnerRotation(float rotation) {
+        mLoadingSpinnerRotationDegrees = (mLoadingSpinnerRotationDegrees + rotation) % 1080;
+    }
+
+    /**
      * Called when this tab has started loading.
      */
     public void pageLoadingStarted() {
diff --git a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
index 01f4461..d4228efb 100644
--- a/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
+++ b/chrome/android/java/src/org/chromium/chrome/browser/compositor/scene_layer/TabStripSceneLayer.java
@@ -98,8 +98,8 @@
                     layoutHelper.getWidth() * mDpToPx, st.getDrawX() * mDpToPx,
                     st.getDrawY() * mDpToPx, st.getWidth() * mDpToPx, st.getHeight() * mDpToPx,
                     st.getContentOffsetX() * mDpToPx, st.getCloseButton().getOpacity(),
-                    st.isLoading(), layoutHelper.getBorderOpacity(), layerTitleCache,
-                    resourceManager);
+                    st.isLoading(), st.getLoadingSpinnerRotation(), layoutHelper.getBorderOpacity(),
+                    layerTitleCache, resourceManager);
         }
     }
 
@@ -123,7 +123,7 @@
     private native void nativePutStripTabLayer(long nativeTabStripSceneLayer, int id,
             int closeResourceId, int handleResourceId, boolean foreground, boolean closePressed,
             float toolbarWidth, float x, float y, float width, float height, float contentOffsetX,
-            float closeButtonAlpha, boolean isLoading, float borderOpacity,
+            float closeButtonAlpha, boolean isLoading, float spinnerRotation, float borderOpacity,
             LayerTitleCache layerTitleCache, ResourceManager resourceManager);
     private native void nativeSetContentTree(long nativeTabStripSceneLayer, SceneLayer contentTree);
 }
diff --git a/chrome/browser/android/compositor/decoration_title.cc b/chrome/browser/android/compositor/decoration_title.cc
index f58d10a..0169c65 100644
--- a/chrome/browser/android/compositor/decoration_title.cc
+++ b/chrome/browser/android/compositor/decoration_title.cc
@@ -10,24 +10,14 @@
 #include "base/logging.h"
 #include "cc/layers/layer.h"
 #include "cc/layers/ui_resource_layer.h"
-#include "chrome/browser/android/compositor/layer/throbber_layer.h"
 #include "chrome/browser/android/compositor/layer_title_cache.h"
 #include "content/public/browser/android/compositor.h"
-#include "third_party/skia/include/core/SkColor.h"
 #include "ui/android/resources/resource_manager.h"
 #include "ui/android/resources/ui_resource_android.h"
 #include "ui/base/l10n/l10n_util_android.h"
 #include "ui/gfx/android/java_bitmap.h"
 #include "ui/gfx/geometry/vector3d_f.h"
 
-namespace {
-
-SkColor GetThrobberColor(bool is_incognito) {
-  // Blue-ish color for normal mode.
-  return is_incognito ? SK_ColorWHITE : SkColorSetRGB(0x42, 0x85, 0xf4);
-}
-}
-
 namespace chrome {
 namespace android {
 
@@ -49,12 +39,12 @@
           cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
       layer_favicon_(
           cc::UIResourceLayer::Create(content::Compositor::LayerSettings())),
-      throbber_layer_(ThrobberLayer::Create(GetThrobberColor(is_incognito))),
       title_resource_id_(title_resource_id),
       favicon_resource_id_(favicon_resource_id),
       spinner_resource_id_(spinner_resource_id),
       spinner_incognito_resource_id_(spinner_resource_id),
       fade_width_(fade_width),
+      spinner_rotation_(0),
       favicon_start_padding_(favicon_start_padding),
       favicon_end_padding_(favicon_end_padding),
       is_incognito_(is_incognito),
@@ -63,7 +53,6 @@
       transform_(new gfx::Transform()),
       resource_manager_(resource_manager),
       layer_title_cache_(layer_title_cache) {
-  layer_->AddChild(throbber_layer_->layer());
   layer_->AddChild(layer_favicon_);
   layer_->AddChild(layer_opaque_);
   layer_->AddChild(layer_fade_);
@@ -78,17 +67,16 @@
   resource_manager_ = resource_manager;
 }
 
-void DecorationTitle::PushPropertiesTo(int title_resource_id,
-                                       int favicon_resource_id,
-                                       int fade_width,
-                                       int favicon_start_padding,
-                                       int favicon_end_padding,
-                                       bool is_incognito,
-                                       bool is_rtl) {
+void DecorationTitle::Update(int title_resource_id,
+                             int favicon_resource_id,
+                             int fade_width,
+                             int favicon_start_padding,
+                             int favicon_end_padding,
+                             bool is_incognito,
+                             bool is_rtl) {
   title_resource_id_ = title_resource_id;
   favicon_resource_id_ = favicon_resource_id;
   is_incognito_ = is_incognito;
-  throbber_layer_->SetColor(GetThrobberColor(is_incognito));
   is_rtl_ = is_rtl;
   favicon_start_padding_ = favicon_start_padding;
   favicon_end_padding_ = favicon_end_padding;
@@ -116,11 +104,20 @@
       layer_favicon_->SetUIResourceId(0);
     }
     layer_favicon_->SetTransform(gfx::Transform());
-    layer_favicon_->SetHideLayerAndSubtree(false);
-    throbber_layer_->Hide();
   } else {
-    layer_favicon_->SetHideLayerAndSubtree(true);
-    throbber_layer_->Show(base::Time::Now());
+    int resource_id =
+        is_incognito_ ? spinner_incognito_resource_id_ : spinner_resource_id_;
+
+    ui::ResourceManager::Resource* spinner_resource =
+        resource_manager_->GetResource(ui::ANDROID_RESOURCE_TYPE_STATIC,
+                                       resource_id);
+
+    if (spinner_resource)
+      layer_favicon_->SetUIResourceId(spinner_resource->ui_resource->id());
+
+    // Rotate about the center of the layer.
+    layer_favicon_->SetTransformOrigin(
+        gfx::Point3F(favicon_size_.width() / 2, favicon_size_.height() / 2, 0));
   }
 
   size_ = gfx::Size(title_size_.width() + favicon_size_.width(),
@@ -134,17 +131,21 @@
   }
 }
 
-void DecorationTitle::UpdateThrobber() {
+void DecorationTitle::SetSpinnerRotation(float rotation) {
   if (!is_loading_)
     return;
-  throbber_layer_->UpdateThrobber(base::Time::Now());
+  float diff = rotation - spinner_rotation_;
+  spinner_rotation_ = rotation;
+  if (diff != 0) {
+    transform_->RotateAboutZAxis(diff);
+  }
+  layer_favicon_->SetTransform(*transform_.get());
 }
 
 void DecorationTitle::setOpacity(float opacity) {
   layer_opaque_->SetOpacity(opacity);
   layer_favicon_->SetOpacity(opacity);
   layer_fade_->SetOpacity(opacity);
-  throbber_layer_->layer()->SetOpacity(opacity);
 }
 
 void DecorationTitle::setBounds(const gfx::Size& bounds) {
@@ -187,10 +188,6 @@
   layer_favicon_->SetIsDrawable(true);
   layer_favicon_->SetBounds(favicon_size_);
   layer_favicon_->SetPosition(gfx::PointF(favicon_x, favicon_offset_y));
-  throbber_layer_->layer()->SetIsDrawable(true);
-  throbber_layer_->layer()->SetBounds(favicon_size_);
-  throbber_layer_->layer()->SetPosition(
-      gfx::PointF(favicon_x, favicon_offset_y));
 
   // Step 2. Place the opaque title component.
   if (title_space > 0.f) {
diff --git a/chrome/browser/android/compositor/decoration_title.h b/chrome/browser/android/compositor/decoration_title.h
index 7c9beb8..f5c46e9 100644
--- a/chrome/browser/android/compositor/decoration_title.h
+++ b/chrome/browser/android/compositor/decoration_title.h
@@ -9,7 +9,6 @@
 
 #include "base/macros.h"
 #include "base/memory/ref_counted.h"
-#include "base/time/time.h"
 #include "cc/resources/ui_resource_client.h"
 #include "third_party/skia/include/core/SkBitmap.h"
 #include "ui/gfx/geometry/size.h"
@@ -28,7 +27,6 @@
 namespace android {
 
 class LayerTitleCache;
-class ThrobberLayer;
 
 class DecorationTitle {
  public:
@@ -47,16 +45,16 @@
 
   void SetResourceManager(ui::ResourceManager* resource_manager);
 
-  void PushPropertiesTo(int title_resource_id,
-                        int favicon_resource_id,
-                        int fade_width,
-                        int favicon_start_padding,
-                        int favicon_end_padding,
-                        bool is_incognito,
-                        bool is_rtl);
+  void Update(int title_resource_id,
+              int favicon_resource_id,
+              int fade_width,
+              int favicon_start_padding,
+              int favicon_end_padding,
+              bool is_incognito,
+              bool is_rtl);
   void SetUIResourceIds();
   void SetIsLoading(bool is_loading);
-  void UpdateThrobber();
+  void SetSpinnerRotation(float rotation);
   void setBounds(const gfx::Size& bounds);
   void setOpacity(float opacity);
 
@@ -68,7 +66,6 @@
   scoped_refptr<cc::UIResourceLayer> layer_opaque_;
   scoped_refptr<cc::UIResourceLayer> layer_fade_;
   scoped_refptr<cc::UIResourceLayer> layer_favicon_;
-  scoped_refptr<ThrobberLayer> throbber_layer_;
 
   int title_resource_id_;
   int favicon_resource_id_;
@@ -79,6 +76,7 @@
   gfx::Size favicon_size_;
   gfx::Size size_;
   int fade_width_;
+  float spinner_rotation_;
   int favicon_start_padding_;
   int favicon_end_padding_;
   bool is_incognito_;
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.cc b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
index 47cc794..965e054 100644
--- a/chrome/browser/android/compositor/layer/tab_handle_layer.cc
+++ b/chrome/browser/android/compositor/layer/tab_handle_layer.cc
@@ -37,6 +37,7 @@
     float content_offset_x,
     float close_button_alpha,
     bool is_loading,
+    float spinner_rotation,
     float brightness,
     float border_opacity) {
   if (brightness != brightness_ || foreground != foreground_) {
@@ -146,7 +147,7 @@
     title_layer->layer()->SetPosition(gfx::Point(title_x, title_y));
     if (is_loading) {
       title_layer->SetIsLoading(true);
-      title_layer->UpdateThrobber();
+      title_layer->SetSpinnerRotation(spinner_rotation);
     } else {
       title_layer->SetIsLoading(false);
     }
diff --git a/chrome/browser/android/compositor/layer/tab_handle_layer.h b/chrome/browser/android/compositor/layer/tab_handle_layer.h
index 009652b..10ad48c 100644
--- a/chrome/browser/android/compositor/layer/tab_handle_layer.h
+++ b/chrome/browser/android/compositor/layer/tab_handle_layer.h
@@ -45,6 +45,7 @@
                      float content_offset_x,
                      float close_button_alpha,
                      bool is_loading,
+                     float spinner_rotation,
                      float brightness,
                      float border_opacity);
   scoped_refptr<cc::Layer> layer() override;
diff --git a/chrome/browser/android/compositor/layer/throbber_layer.cc b/chrome/browser/android/compositor/layer/throbber_layer.cc
deleted file mode 100644
index 04a8c408..0000000
--- a/chrome/browser/android/compositor/layer/throbber_layer.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "chrome/browser/android/compositor/layer/throbber_layer.h"
-
-#include "cc/layers/layer.h"
-#include "cc/layers/solid_color_layer.h"
-#include "cc/layers/ui_resource_layer.h"
-#include "content/public/browser/android/compositor.h"
-#include "third_party/skia/include/core/SkBitmap.h"
-#include "third_party/skia/include/core/SkCanvas.h"
-#include "ui/gfx/canvas.h"
-#include "ui/gfx/paint_throbber.h"
-#include "ui/gfx/skia_util.h"
-
-namespace chrome {
-namespace android {
-
-// static
-scoped_refptr<ThrobberLayer> ThrobberLayer::Create(SkColor color) {
-  return make_scoped_refptr(new ThrobberLayer(color));
-}
-
-void ThrobberLayer::Show(const base::Time& now) {
-  if (!layer_->hide_layer_and_subtree())
-    return;
-  start_time_ = now;
-  layer_->SetHideLayerAndSubtree(false);
-}
-
-void ThrobberLayer::Hide() {
-  layer_->SetHideLayerAndSubtree(true);
-}
-
-void ThrobberLayer::SetColor(SkColor color) {
-  color_ = color;
-}
-
-void ThrobberLayer::UpdateThrobber(const base::Time& now) {
-  if (layer_->hide_layer_and_subtree())
-    return;
-
-  SkBitmap skbitmap;
-  skbitmap.allocN32Pixels(layer_->bounds().width(), layer_->bounds().height());
-  SkCanvas skcanvas(skbitmap);
-  gfx::Canvas canvas(&skcanvas, 1.0f);
-  gfx::Rect rect(0, 0, layer_->bounds().width(), layer_->bounds().height());
-  SkPaint paint;
-  paint.setAntiAlias(false);
-  paint.setXfermodeMode(SkXfermode::kClear_Mode);
-  SkRect skrect = RectToSkRect(rect);
-  skcanvas.drawRect(skrect, paint);
-  skcanvas.clipRect(skrect);
-  gfx::PaintThrobberSpinning(&canvas, rect, color_, now - start_time_);
-  skbitmap.setImmutable();
-  layer_->SetBitmap(skbitmap);
-}
-
-scoped_refptr<cc::Layer> ThrobberLayer::layer() {
-  return layer_;
-}
-
-ThrobberLayer::ThrobberLayer(SkColor color)
-    : color_(color),
-      start_time_(base::Time::Now()),
-      layer_(
-          cc::UIResourceLayer::Create(content::Compositor::LayerSettings())) {
-  layer_->SetIsDrawable(true);
-}
-
-ThrobberLayer::~ThrobberLayer() {
-}
-
-}  //  namespace android
-}  //  namespace chrome
diff --git a/chrome/browser/android/compositor/layer/throbber_layer.h b/chrome/browser/android/compositor/layer/throbber_layer.h
deleted file mode 100644
index 82bbce9..0000000
--- a/chrome/browser/android/compositor/layer/throbber_layer.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CHROME_BROWSER_ANDROID_COMPOSITOR_LAYER_THROBBER_LAYER_H_
-#define CHROME_BROWSER_ANDROID_COMPOSITOR_LAYER_THROBBER_LAYER_H_
-
-#include "base/basictypes.h"
-#include "base/memory/scoped_ptr.h"
-#include "base/time/time.h"
-#include "chrome/browser/android/compositor/layer/layer.h"
-#include "third_party/skia/include/core/SkColor.h"
-
-namespace cc {
-class Layer;
-class UIResourceLayer;
-}
-
-namespace chrome {
-namespace android {
-
-// A layer representing throbber which we use as a reloading spinner on the
-// tab strip for tablets.
-// TODO(changwan): implement WAITING state for which we should spin
-// counterclockwise until connection to the server is made.
-class ThrobberLayer : public Layer {
- public:
-  static scoped_refptr<ThrobberLayer> Create(SkColor color);
-
-  void Show(const base::Time& time);
-  void Hide();
-  void SetColor(SkColor color);
-  void UpdateThrobber(const base::Time& time);
-
-  // Layer:
-  scoped_refptr<cc::Layer> layer() override;
-
- protected:
-  explicit ThrobberLayer(unsigned int color);
-  ~ThrobberLayer() override;
-
- private:
-  SkColor color_;
-  base::Time start_time_;
-  scoped_refptr<cc::UIResourceLayer> layer_;
-  scoped_refptr<cc::Layer> debug_layer_;
-
-  DISALLOW_COPY_AND_ASSIGN(ThrobberLayer);
-};
-
-}  //  namespace android
-}  //  namespace chrome
-
-#endif  // CHROME_BROWSER_ANDROID_COMPOSITOR_LAYER_THROBBER_LAYER_H_
diff --git a/chrome/browser/android/compositor/layer_title_cache.cc b/chrome/browser/android/compositor/layer_title_cache.cc
index 992458e..3db241b 100644
--- a/chrome/browser/android/compositor/layer_title_cache.cc
+++ b/chrome/browser/android/compositor/layer_title_cache.cc
@@ -65,9 +65,9 @@
         tab_id);
   } else {
     if (title_resource_id != -1 && favicon_resource_id != -1) {
-      title_layer->PushPropertiesTo(title_resource_id, favicon_resource_id,
-                                    fade_width_, favicon_start_padding_,
-                                    favicon_end_padding_, is_incognito, is_rtl);
+      title_layer->Update(title_resource_id, favicon_resource_id, fade_width_,
+                          favicon_start_padding_, favicon_end_padding_,
+                          is_incognito, is_rtl);
     } else {
       layer_cache_.Remove(tab_id);
     }
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
index 67dfb72..be0c944 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.cc
@@ -148,6 +148,7 @@
                                           jfloat content_offset_x,
                                           jfloat close_button_alpha,
                                           jboolean is_loading,
+                                          jfloat spinner_rotation,
                                           jfloat border_opacity,
                                           jobject jlayer_title_cache,
                                           jobject jresource_manager) {
@@ -165,7 +166,7 @@
   layer->SetProperties(id, close_button_resource, tab_handle_resource,
                        foreground, close_pressed, toolbar_width, x, y, width,
                        height, content_offset_x, close_button_alpha, is_loading,
-                       strip_brightness_, border_opacity);
+                       spinner_rotation, strip_brightness_, border_opacity);
 }
 
 scoped_refptr<TabHandleLayer> TabStripSceneLayer::GetNextLayer(
diff --git a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
index c28deb6..bef95c6d 100644
--- a/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
+++ b/chrome/browser/android/compositor/scene_layer/tab_strip_scene_layer.h
@@ -76,6 +76,7 @@
                         jfloat content_offset_x,
                         jfloat close_button_alpha,
                         jboolean is_loading,
+                        jfloat spinner_rotation,
                         jfloat border_opacity,
                         jobject jlayer_title_cache,
                         jobject jresource_manager);
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 6300411..58639ea 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -72,8 +72,6 @@
       'browser/android/compositor/layer/tab_handle_layer.h',
       'browser/android/compositor/layer/tab_layer.cc',
       'browser/android/compositor/layer/tab_layer.h',
-      'browser/android/compositor/layer/throbber_layer.cc',
-      'browser/android/compositor/layer/throbber_layer.h',
       'browser/android/compositor/layer/thumbnail_layer.cc',
       'browser/android/compositor/layer/thumbnail_layer.h',
       'browser/android/compositor/layer/toolbar_layer.cc',