15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/views/tabs/tab_controller.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
8868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ui/base/models/list_selection_model.h"
11c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "ui/views/controls/button/image_button.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/test/views_test_base.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/views/widget/widget.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using views::Widget;
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FakeTabController : public TabController {
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeTabController() : immersive_style_(false) {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FakeTabController() {}
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  void set_immersive_style(bool value) { immersive_style_ = value; }
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual const ui::ListSelectionModel& GetSelectionModel() OVERRIDE {
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return selection_model_;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool SupportsMultipleSelection() OVERRIDE { return false; }
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void SelectTab(Tab* tab) OVERRIDE {}
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ExtendSelectionTo(Tab* tab) OVERRIDE {}
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ToggleSelected(Tab* tab) OVERRIDE {}
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void AddSelectionFromAnchorTo(Tab* tab) OVERRIDE {}
332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void CloseTab(Tab* tab, CloseTabSource source) OVERRIDE {}
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void ShowContextMenuForTab(Tab* tab,
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     const gfx::Point& p,
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                                     ui::MenuSourceType source_type) OVERRIDE {}
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool IsActiveTab(const Tab* tab) const OVERRIDE { return false; }
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool IsTabSelected(const Tab* tab) const OVERRIDE {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool IsTabPinned(const Tab* tab) const OVERRIDE { return false; }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void MaybeStartDrag(
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      Tab* tab,
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const ui::LocatedEvent& event,
452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const ui::ListSelectionModel& original_selection) OVERRIDE {}
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ContinueDrag(views::View* view,
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                            const ui::LocatedEvent& event) OVERRIDE {}
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual bool EndDrag(EndDragReason reason) OVERRIDE { return false; }
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual Tab* GetTabAt(Tab* tab,
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                        const gfx::Point& tab_in_tab_coordinates) OVERRIDE {
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return NULL;
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void OnMouseEventInTab(views::View* source,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 const ui::MouseEvent& event) OVERRIDE {}
552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool ShouldPaintTab(const Tab* tab, gfx::Rect* clip) OVERRIDE {
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual bool IsImmersiveStyle() const OVERRIDE { return immersive_style_; }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ui::ListSelectionModel selection_model_;
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bool immersive_style_;
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FakeTabController);
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class TabTest : public views::ViewsTestBase {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabTest() {}
702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual ~TabTest() {}
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  static bool IconAnimationInvariant(const Tab& tab) {
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool capture_invariant =
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tab.data().CaptureActive() == (tab.icon_animation_.get() != NULL);
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    bool audio_invariant =
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        !tab.data().AudioActive() || tab.tab_audio_indicator_->IsAnimating();
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return capture_invariant && audio_invariant;
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)};
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(TabTest, HitTestTopPixel) {
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Widget widget;
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Widget::InitParams params(CreateParams(Widget::InitParams::TYPE_WINDOW));
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.ownership = Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  params.bounds.SetRect(10, 20, 300, 400);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.Init(params);
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FakeTabController tab_controller;
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Tab tab(&tab_controller);
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.GetContentsView()->AddChildView(&tab);
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  tab.SetBoundsRect(gfx::Rect(gfx::Point(0, 0), Tab::GetStandardSize()));
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tabs have some shadow in the top, so by default we don't hit the tab there.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int middle_x = tab.width() / 2;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(tab.HitTestPoint(gfx::Point(middle_x, 0)));
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Tabs are slanted, so a click halfway down the left edge won't hit it.
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int middle_y = tab.height() / 2;
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, middle_y)));
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If the window is maximized, however, we want clicks in the top edge to
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // select the tab.
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  widget.Maximize();
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(tab.HitTestPoint(gfx::Point(middle_x, 0)));
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // But clicks in the area above the slanted sides should still miss.
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(tab.HitTestPoint(gfx::Point(0, 0)));
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(tab.HitTestPoint(gfx::Point(tab.width() - 1, 0)));
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Regression test for http://crbug.com/226253. Calling Layout() more than once
112c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// shouldn't change the insets of the close button.
113c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)TEST_F(TabTest, CloseButtonLayout) {
114c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  FakeTabController tab_controller;
115c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  Tab tab(&tab_controller);
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  tab.SetBounds(0, 0, 100, 50);
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  tab.Layout();
118c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Insets close_button_insets = tab.close_button_->GetInsets();
119c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  tab.Layout();
120c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  gfx::Insets close_button_insets_2 = tab.close_button_->GetInsets();
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(close_button_insets.top(), close_button_insets_2.top());
122c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(close_button_insets.left(), close_button_insets_2.left());
123c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(close_button_insets.bottom(), close_button_insets_2.bottom());
124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(close_button_insets.right(), close_button_insets_2.right());
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Also make sure the close button is sized as large as the tab.
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  EXPECT_EQ(50, tab.close_button_->bounds().height());
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(TabTest, ActivityIndicators) {
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  FakeTabController controller;
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Tab tab(&controller);
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SkBitmap bitmap;
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bitmap.setConfig(SkBitmap::kARGB_8888_Config, 16, 16);
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  bitmap.allocPixels();
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  TabRendererData data;
1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.favicon = gfx::ImageSkia::CreateFrom1xBitmap(bitmap);
1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Audio starts and stops.
1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.audio_state = TabRendererData::AUDIO_STATE_PLAYING;
1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::AUDIO_STATE_PLAYING, tab.data().audio_state);
1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.audio_state = TabRendererData::AUDIO_STATE_NONE;
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Capture starts and stops.
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.capture_state = TabRendererData::CAPTURE_STATE_RECORDING;
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_RECORDING, tab.data().capture_state);
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.capture_state = TabRendererData::CAPTURE_STATE_NONE;
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Audio starts then capture starts, then audio stops then capture stops.
1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.audio_state = TabRendererData::AUDIO_STATE_PLAYING;
1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.capture_state = TabRendererData::CAPTURE_STATE_RECORDING;
1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::AUDIO_STATE_PLAYING, tab.data().audio_state);
1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_RECORDING, tab.data().capture_state);
1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.title = ASCIIToUTF16("test X");
1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.audio_state = TabRendererData::AUDIO_STATE_NONE;
1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_RECORDING, tab.data().capture_state);
1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.capture_state = TabRendererData::CAPTURE_STATE_NONE;
1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Audio starts then capture starts, then capture stops then audio stops.
1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.audio_state = TabRendererData::AUDIO_STATE_PLAYING;
1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.capture_state = TabRendererData::CAPTURE_STATE_RECORDING;
1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::AUDIO_STATE_PLAYING, tab.data().audio_state);
1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_RECORDING, tab.data().capture_state);
1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.title = ASCIIToUTF16("test Y");
2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.capture_state = TabRendererData::CAPTURE_STATE_NONE;
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  data.audio_state = TabRendererData::AUDIO_STATE_NONE;
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  tab.SetData(data);
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::AUDIO_STATE_NONE, tab.data().audio_state);
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(TabRendererData::CAPTURE_STATE_NONE, tab.data().capture_state);
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_TRUE(IconAnimationInvariant(tab));
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
216