// Copyright (c) 2012 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 "ui/views/focus/focus_manager.h"

#include <utility>
#include <vector>

#include "base/command_line.h"
#include "base/strings/utf_string_conversions.h"
#include "ui/aura/client/focus_client.h"
#include "ui/aura/window.h"
#include "ui/base/accelerators/accelerator.h"
#include "ui/base/ime/dummy_text_input_client.h"
#include "ui/base/ime/text_input_focus_manager.h"
#include "ui/base/ui_base_switches.h"
#include "ui/events/keycodes/keyboard_codes.h"
#include "ui/views/accessible_pane_view.h"
#include "ui/views/controls/button/label_button.h"
#include "ui/views/focus/focus_manager_factory.h"
#include "ui/views/focus/focus_manager_test.h"
#include "ui/views/focus/widget_focus_manager.h"
#include "ui/views/widget/widget.h"

namespace views {

enum FocusTestEventType {
  ON_FOCUS = 0,
  ON_BLUR
};

struct FocusTestEvent {
  FocusTestEvent(FocusTestEventType type, int view_id)
      : type(type),
        view_id(view_id) {
  }

  FocusTestEventType type;
  int view_id;
};

class SimpleTestView : public View {
 public:
  SimpleTestView(std::vector<FocusTestEvent>* event_list, int view_id)
      : event_list_(event_list) {
    SetFocusable(true);
    set_id(view_id);
  }

  virtual void OnFocus() OVERRIDE {
    event_list_->push_back(FocusTestEvent(ON_FOCUS, id()));
  }

  virtual void OnBlur() OVERRIDE {
    event_list_->push_back(FocusTestEvent(ON_BLUR, id()));
  }

 private:
  std::vector<FocusTestEvent>* event_list_;

  DISALLOW_COPY_AND_ASSIGN(SimpleTestView);
};

// Tests that the appropriate Focus related methods are called when a View
// gets/loses focus.
TEST_F(FocusManagerTest, ViewFocusCallbacks) {
  std::vector<FocusTestEvent> event_list;
  const int kView1ID = 1;
  const int kView2ID = 2;

  SimpleTestView* view1 = new SimpleTestView(&event_list, kView1ID);
  SimpleTestView* view2 = new SimpleTestView(&event_list, kView2ID);
  GetContentsView()->AddChildView(view1);
  GetContentsView()->AddChildView(view2);

  view1->RequestFocus();
  ASSERT_EQ(1, static_cast<int>(event_list.size()));
  EXPECT_EQ(ON_FOCUS, event_list[0].type);
  EXPECT_EQ(kView1ID, event_list[0].view_id);

  event_list.clear();
  view2->RequestFocus();
  ASSERT_EQ(2, static_cast<int>(event_list.size()));
  EXPECT_EQ(ON_BLUR, event_list[0].type);
  EXPECT_EQ(kView1ID, event_list[0].view_id);
  EXPECT_EQ(ON_FOCUS, event_list[1].type);
  EXPECT_EQ(kView2ID, event_list[1].view_id);

  event_list.clear();
  GetFocusManager()->ClearFocus();
  ASSERT_EQ(1, static_cast<int>(event_list.size()));
  EXPECT_EQ(ON_BLUR, event_list[0].type);
  EXPECT_EQ(kView2ID, event_list[0].view_id);
}

TEST_F(FocusManagerTest, FocusChangeListener) {
  View* view1 = new View();
  view1->SetFocusable(true);
  View* view2 = new View();
  view2->SetFocusable(true);
  GetContentsView()->AddChildView(view1);
  GetContentsView()->AddChildView(view2);

  TestFocusChangeListener listener;
  AddFocusChangeListener(&listener);

  // Required for VS2010: http://connect.microsoft.com/VisualStudio/feedback/details/520043/error-converting-from-null-to-a-pointer-type-in-std-pair
  views::View* null_view = NULL;

  view1->RequestFocus();
  ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
  EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(null_view, view1));
  listener.ClearFocusChanges();

  view2->RequestFocus();
  ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
  EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view1, view2));
  listener.ClearFocusChanges();

  GetFocusManager()->ClearFocus();
  ASSERT_EQ(1, static_cast<int>(listener.focus_changes().size()));
  EXPECT_TRUE(listener.focus_changes()[0] == ViewPair(view2, null_view));
}

TEST_F(FocusManagerTest, WidgetFocusChangeListener) {
  TestWidgetFocusChangeListener widget_listener;
  AddWidgetFocusChangeListener(&widget_listener);

  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.bounds = gfx::Rect(10, 10, 100, 100);
  params.parent = GetWidget()->GetNativeView();

  scoped_ptr<Widget> widget1(new Widget);
  widget1->Init(params);
  widget1->Show();

  scoped_ptr<Widget> widget2(new Widget);
  widget2->Init(params);
  widget2->Show();

  widget_listener.ClearFocusChanges();
  gfx::NativeView native_view1 = widget1->GetNativeView();
  aura::client::GetFocusClient(native_view1)->FocusWindow(native_view1);
  ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size()));
  EXPECT_EQ(native_view1, widget_listener.focus_changes()[0].second);
  EXPECT_EQ(native_view1, widget_listener.focus_changes()[1].second);

  widget_listener.ClearFocusChanges();
  gfx::NativeView native_view2 = widget2->GetNativeView();
  aura::client::GetFocusClient(native_view2)->FocusWindow(native_view2);
  ASSERT_EQ(2, static_cast<int>(widget_listener.focus_changes().size()));
  EXPECT_EQ(NativeViewPair(native_view1, native_view2),
            widget_listener.focus_changes()[0]);
  EXPECT_EQ(NativeViewPair(native_view1, native_view2),
            widget_listener.focus_changes()[1]);
}

// Counts accelerator calls.
class TestAcceleratorTarget : public ui::AcceleratorTarget {
 public:
  explicit TestAcceleratorTarget(bool process_accelerator)
      : accelerator_count_(0),
        process_accelerator_(process_accelerator),
        can_handle_accelerators_(true) {}

  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
    ++accelerator_count_;
    return process_accelerator_;
  }

  virtual bool CanHandleAccelerators() const OVERRIDE {
    return can_handle_accelerators_;
  }

  int accelerator_count() const { return accelerator_count_; }

  void set_can_handle_accelerators(bool can_handle_accelerators) {
    can_handle_accelerators_ = can_handle_accelerators;
  }

 private:
  int accelerator_count_;  // number of times that the accelerator is activated
  bool process_accelerator_;  // return value of AcceleratorPressed
  bool can_handle_accelerators_;  // return value of CanHandleAccelerators

  DISALLOW_COPY_AND_ASSIGN(TestAcceleratorTarget);
};

TEST_F(FocusManagerTest, CallsNormalAcceleratorTarget) {
  FocusManager* focus_manager = GetFocusManager();
  ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
  ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);

  TestAcceleratorTarget return_target(true);
  TestAcceleratorTarget escape_target(true);
  EXPECT_EQ(return_target.accelerator_count(), 0);
  EXPECT_EQ(escape_target.accelerator_count(), 0);
  EXPECT_EQ(NULL,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
  EXPECT_EQ(NULL,
            focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));

  // Register targets.
  focus_manager->RegisterAccelerator(return_accelerator,
                                     ui::AcceleratorManager::kNormalPriority,
                                     &return_target);
  focus_manager->RegisterAccelerator(escape_accelerator,
                                     ui::AcceleratorManager::kNormalPriority,
                                     &escape_target);

  // Checks if the correct target is registered.
  EXPECT_EQ(&return_target,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
  EXPECT_EQ(&escape_target,
            focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));

  // Hitting the return key.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(return_target.accelerator_count(), 1);
  EXPECT_EQ(escape_target.accelerator_count(), 0);

  // Hitting the escape key.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
  EXPECT_EQ(return_target.accelerator_count(), 1);
  EXPECT_EQ(escape_target.accelerator_count(), 1);

  // Register another target for the return key.
  TestAcceleratorTarget return_target2(true);
  EXPECT_EQ(return_target2.accelerator_count(), 0);
  focus_manager->RegisterAccelerator(return_accelerator,
                                     ui::AcceleratorManager::kNormalPriority,
                                     &return_target2);
  EXPECT_EQ(&return_target2,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));

  // Hitting the return key; return_target2 has the priority.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(return_target.accelerator_count(), 1);
  EXPECT_EQ(return_target2.accelerator_count(), 1);

  // Register a target that does not process the accelerator event.
  TestAcceleratorTarget return_target3(false);
  EXPECT_EQ(return_target3.accelerator_count(), 0);
  focus_manager->RegisterAccelerator(return_accelerator,
                                     ui::AcceleratorManager::kNormalPriority,
                                     &return_target3);
  EXPECT_EQ(&return_target3,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));

  // Hitting the return key.
  // Since the event handler of return_target3 returns false, return_target2
  // should be called too.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(return_target.accelerator_count(), 1);
  EXPECT_EQ(return_target2.accelerator_count(), 2);
  EXPECT_EQ(return_target3.accelerator_count(), 1);

  // Unregister return_target2.
  focus_manager->UnregisterAccelerator(return_accelerator, &return_target2);
  EXPECT_EQ(&return_target3,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));

  // Hitting the return key. return_target3 and return_target should be called.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(return_target.accelerator_count(), 2);
  EXPECT_EQ(return_target2.accelerator_count(), 2);
  EXPECT_EQ(return_target3.accelerator_count(), 2);

  // Unregister targets.
  focus_manager->UnregisterAccelerator(return_accelerator, &return_target);
  focus_manager->UnregisterAccelerator(return_accelerator, &return_target3);
  focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target);

  // Now there is no target registered.
  EXPECT_EQ(NULL,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));
  EXPECT_EQ(NULL,
            focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));

  // Hitting the return key and the escape key. Nothing should happen.
  EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(return_target.accelerator_count(), 2);
  EXPECT_EQ(return_target2.accelerator_count(), 2);
  EXPECT_EQ(return_target3.accelerator_count(), 2);
  EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
  EXPECT_EQ(escape_target.accelerator_count(), 1);
}

TEST_F(FocusManagerTest, HighPriorityHandlers) {
  FocusManager* focus_manager = GetFocusManager();
  ui::Accelerator escape_accelerator(ui::VKEY_ESCAPE, ui::EF_NONE);

  TestAcceleratorTarget escape_target_high(true);
  TestAcceleratorTarget escape_target_normal(true);
  EXPECT_EQ(escape_target_high.accelerator_count(), 0);
  EXPECT_EQ(escape_target_normal.accelerator_count(), 0);
  EXPECT_EQ(NULL,
      focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
  EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));

  // Register high priority target.
  focus_manager->RegisterAccelerator(escape_accelerator,
                                     ui::AcceleratorManager::kHighPriority,
                                     &escape_target_high);
  EXPECT_EQ(&escape_target_high,
     focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
  EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));

  // Hit the escape key.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
  EXPECT_EQ(escape_target_high.accelerator_count(), 1);
  EXPECT_EQ(escape_target_normal.accelerator_count(), 0);

  // Add a normal priority target and make sure it doesn't see the key.
  focus_manager->RegisterAccelerator(escape_accelerator,
                                     ui::AcceleratorManager::kNormalPriority,
                                     &escape_target_normal);

  // Checks if the correct target is registered (same as before, the high
  // priority one).
  EXPECT_EQ(&escape_target_high,
      focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
  EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));

  // Hit the escape key.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
  EXPECT_EQ(escape_target_high.accelerator_count(), 2);
  EXPECT_EQ(escape_target_normal.accelerator_count(), 0);

  // Unregister the high priority accelerator.
  focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
  EXPECT_EQ(&escape_target_normal,
      focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
  EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));

  // Hit the escape key.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
  EXPECT_EQ(escape_target_high.accelerator_count(), 2);
  EXPECT_EQ(escape_target_normal.accelerator_count(), 1);

  // Add the high priority target back and make sure it starts seeing the key.
  focus_manager->RegisterAccelerator(escape_accelerator,
                                     ui::AcceleratorManager::kHighPriority,
                                     &escape_target_high);
  EXPECT_EQ(&escape_target_high,
      focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
  EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));

  // Hit the escape key.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
  EXPECT_EQ(escape_target_high.accelerator_count(), 3);
  EXPECT_EQ(escape_target_normal.accelerator_count(), 1);

  // Unregister the normal priority accelerator.
  focus_manager->UnregisterAccelerator(
      escape_accelerator, &escape_target_normal);
  EXPECT_EQ(&escape_target_high,
      focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
  EXPECT_TRUE(focus_manager->HasPriorityHandler(escape_accelerator));

  // Hit the escape key.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(escape_accelerator));
  EXPECT_EQ(escape_target_high.accelerator_count(), 4);
  EXPECT_EQ(escape_target_normal.accelerator_count(), 1);

  // Unregister the high priority accelerator.
  focus_manager->UnregisterAccelerator(escape_accelerator, &escape_target_high);
  EXPECT_EQ(NULL,
      focus_manager->GetCurrentTargetForAccelerator(escape_accelerator));
  EXPECT_FALSE(focus_manager->HasPriorityHandler(escape_accelerator));

  // Hit the escape key (no change, no targets registered).
  EXPECT_FALSE(focus_manager->ProcessAccelerator(escape_accelerator));
  EXPECT_EQ(escape_target_high.accelerator_count(), 4);
  EXPECT_EQ(escape_target_normal.accelerator_count(), 1);
}

TEST_F(FocusManagerTest, CallsEnabledAcceleratorTargetsOnly) {
  FocusManager* focus_manager = GetFocusManager();
  ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);

  TestAcceleratorTarget return_target1(true);
  TestAcceleratorTarget return_target2(true);

  focus_manager->RegisterAccelerator(return_accelerator,
                                     ui::AcceleratorManager::kNormalPriority,
                                     &return_target1);
  focus_manager->RegisterAccelerator(return_accelerator,
                                     ui::AcceleratorManager::kNormalPriority,
                                     &return_target2);
  EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(0, return_target1.accelerator_count());
  EXPECT_EQ(1, return_target2.accelerator_count());

  // If CanHandleAccelerators() return false, FocusManager shouldn't call
  // AcceleratorPressed().
  return_target2.set_can_handle_accelerators(false);
  EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(1, return_target1.accelerator_count());
  EXPECT_EQ(1, return_target2.accelerator_count());

  // If no accelerator targets are enabled, ProcessAccelerator() should fail.
  return_target1.set_can_handle_accelerators(false);
  EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(1, return_target1.accelerator_count());
  EXPECT_EQ(1, return_target2.accelerator_count());

  // Enabling the target again causes the accelerators to be processed again.
  return_target1.set_can_handle_accelerators(true);
  return_target2.set_can_handle_accelerators(true);
  EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(1, return_target1.accelerator_count());
  EXPECT_EQ(2, return_target2.accelerator_count());
}

// Unregisters itself when its accelerator is invoked.
class SelfUnregisteringAcceleratorTarget : public ui::AcceleratorTarget {
 public:
  SelfUnregisteringAcceleratorTarget(ui::Accelerator accelerator,
                                     FocusManager* focus_manager)
      : accelerator_(accelerator),
        focus_manager_(focus_manager),
        accelerator_count_(0) {
  }

  virtual bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE {
    ++accelerator_count_;
    focus_manager_->UnregisterAccelerator(accelerator, this);
    return true;
  }

  virtual bool CanHandleAccelerators() const OVERRIDE {
    return true;
  }

  int accelerator_count() const { return accelerator_count_; }

 private:
  ui::Accelerator accelerator_;
  FocusManager* focus_manager_;
  int accelerator_count_;

  DISALLOW_COPY_AND_ASSIGN(SelfUnregisteringAcceleratorTarget);
};

TEST_F(FocusManagerTest, CallsSelfDeletingAcceleratorTarget) {
  FocusManager* focus_manager = GetFocusManager();
  ui::Accelerator return_accelerator(ui::VKEY_RETURN, ui::EF_NONE);
  SelfUnregisteringAcceleratorTarget target(return_accelerator, focus_manager);
  EXPECT_EQ(target.accelerator_count(), 0);
  EXPECT_EQ(NULL,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));

  // Register the target.
  focus_manager->RegisterAccelerator(return_accelerator,
                                     ui::AcceleratorManager::kNormalPriority,
                                     &target);
  EXPECT_EQ(&target,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));

  // Hitting the return key. The target will be unregistered.
  EXPECT_TRUE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(target.accelerator_count(), 1);
  EXPECT_EQ(NULL,
            focus_manager->GetCurrentTargetForAccelerator(return_accelerator));

  // Hitting the return key again; nothing should happen.
  EXPECT_FALSE(focus_manager->ProcessAccelerator(return_accelerator));
  EXPECT_EQ(target.accelerator_count(), 1);
}

class FocusManagerDtorTest : public FocusManagerTest {
 protected:
  typedef std::vector<std::string> DtorTrackVector;

  class FocusManagerDtorTracked : public FocusManager {
   public:
    FocusManagerDtorTracked(Widget* widget, DtorTrackVector* dtor_tracker)
      : FocusManager(widget, NULL /* delegate */),
        dtor_tracker_(dtor_tracker) {
    }

    virtual ~FocusManagerDtorTracked() {
      dtor_tracker_->push_back("FocusManagerDtorTracked");
    }

    DtorTrackVector* dtor_tracker_;

   private:
    DISALLOW_COPY_AND_ASSIGN(FocusManagerDtorTracked);
  };

  class TestFocusManagerFactory : public FocusManagerFactory {
   public:
    explicit TestFocusManagerFactory(DtorTrackVector* dtor_tracker)
        : dtor_tracker_(dtor_tracker) {
    }

    virtual FocusManager* CreateFocusManager(Widget* widget,
                                             bool desktop_widget) OVERRIDE {
      return new FocusManagerDtorTracked(widget, dtor_tracker_);
    }

   private:
    DtorTrackVector* dtor_tracker_;
    DISALLOW_COPY_AND_ASSIGN(TestFocusManagerFactory);
  };

  class LabelButtonDtorTracked : public LabelButton {
   public:
    LabelButtonDtorTracked(const base::string16& text,
                           DtorTrackVector* dtor_tracker)
        : LabelButton(NULL, text),
          dtor_tracker_(dtor_tracker) {
      SetStyle(STYLE_BUTTON);
    };
    virtual ~LabelButtonDtorTracked() {
      dtor_tracker_->push_back("LabelButtonDtorTracked");
    }

    DtorTrackVector* dtor_tracker_;
  };

  class WindowDtorTracked : public Widget {
   public:
    explicit WindowDtorTracked(DtorTrackVector* dtor_tracker)
        : dtor_tracker_(dtor_tracker) {
    }

    virtual ~WindowDtorTracked() {
      dtor_tracker_->push_back("WindowDtorTracked");
    }

    DtorTrackVector* dtor_tracker_;
  };

  virtual void SetUp() {
    ViewsTestBase::SetUp();
    FocusManagerFactory::Install(new TestFocusManagerFactory(&dtor_tracker_));
    // Create WindowDtorTracked that uses FocusManagerDtorTracked.
    Widget* widget = new WindowDtorTracked(&dtor_tracker_);
    Widget::InitParams params;
    params.delegate = this;
    params.bounds = gfx::Rect(0, 0, 100, 100);
    widget->Init(params);

    tracked_focus_manager_ =
        static_cast<FocusManagerDtorTracked*>(GetFocusManager());
    widget->Show();
  }

  virtual void TearDown() {
    FocusManagerFactory::Install(NULL);
    ViewsTestBase::TearDown();
  }

  FocusManager* tracked_focus_manager_;
  DtorTrackVector dtor_tracker_;
};

namespace {

class FocusInAboutToRequestFocusFromTabTraversalView : public View {
 public:
  FocusInAboutToRequestFocusFromTabTraversalView() : view_to_focus_(NULL) {}

  void set_view_to_focus(View* view) { view_to_focus_ = view; }

  virtual void AboutToRequestFocusFromTabTraversal(bool reverse) OVERRIDE {
    view_to_focus_->RequestFocus();
  }

 private:
  views::View* view_to_focus_;

  DISALLOW_COPY_AND_ASSIGN(FocusInAboutToRequestFocusFromTabTraversalView);
};
}  // namespace

// Verifies a focus change done during a call to
// AboutToRequestFocusFromTabTraversal() is honored.
TEST_F(FocusManagerTest, FocusInAboutToRequestFocusFromTabTraversal) {
  // Create 3 views focuses the 3 and advances to the second. The 2nd views
  // implementation of AboutToRequestFocusFromTabTraversal() focuses the first.
  views::View* v1 = new View;
  v1->SetFocusable(true);
  GetContentsView()->AddChildView(v1);

  FocusInAboutToRequestFocusFromTabTraversalView* v2 =
      new FocusInAboutToRequestFocusFromTabTraversalView;
  v2->SetFocusable(true);
  v2->set_view_to_focus(v1);
  GetContentsView()->AddChildView(v2);

  views::View* v3 = new View;
  v3->SetFocusable(true);
  GetContentsView()->AddChildView(v3);

  v3->RequestFocus();
  GetWidget()->GetFocusManager()->AdvanceFocus(true);
  EXPECT_TRUE(v1->HasFocus());
}

TEST_F(FocusManagerTest, RotatePaneFocus) {
  views::AccessiblePaneView* pane1 = new AccessiblePaneView();
  GetContentsView()->AddChildView(pane1);

  views::View* v1 = new View;
  v1->SetFocusable(true);
  pane1->AddChildView(v1);

  views::View* v2 = new View;
  v2->SetFocusable(true);
  pane1->AddChildView(v2);

  views::AccessiblePaneView* pane2 = new AccessiblePaneView();
  GetContentsView()->AddChildView(pane2);

  views::View* v3 = new View;
  v3->SetFocusable(true);
  pane2->AddChildView(v3);

  views::View* v4 = new View;
  v4->SetFocusable(true);
  pane2->AddChildView(v4);

  std::vector<views::View*> panes;
  panes.push_back(pane1);
  panes.push_back(pane2);
  SetAccessiblePanes(panes);

  FocusManager* focus_manager = GetWidget()->GetFocusManager();

  // Advance forwards. Focus should stay trapped within each pane.
  EXPECT_TRUE(focus_manager->RotatePaneFocus(
      FocusManager::kForward, FocusManager::kWrap));
  EXPECT_EQ(v1, focus_manager->GetFocusedView());
  focus_manager->AdvanceFocus(false);
  EXPECT_EQ(v2, focus_manager->GetFocusedView());
  focus_manager->AdvanceFocus(false);
  EXPECT_EQ(v1, focus_manager->GetFocusedView());

  EXPECT_TRUE(focus_manager->RotatePaneFocus(
      FocusManager::kForward, FocusManager::kWrap));
  EXPECT_EQ(v3, focus_manager->GetFocusedView());
  focus_manager->AdvanceFocus(false);
  EXPECT_EQ(v4, focus_manager->GetFocusedView());
  focus_manager->AdvanceFocus(false);
  EXPECT_EQ(v3, focus_manager->GetFocusedView());

  EXPECT_TRUE(focus_manager->RotatePaneFocus(
      FocusManager::kForward, FocusManager::kWrap));
  EXPECT_EQ(v1, focus_manager->GetFocusedView());

  // Advance backwards.
  EXPECT_TRUE(focus_manager->RotatePaneFocus(
      FocusManager::kBackward, FocusManager::kWrap));
  EXPECT_EQ(v3, focus_manager->GetFocusedView());

  EXPECT_TRUE(focus_manager->RotatePaneFocus(
      FocusManager::kBackward, FocusManager::kWrap));
  EXPECT_EQ(v1, focus_manager->GetFocusedView());

  // Advance without wrap. When it gets to the end of the list of
  // panes, RotatePaneFocus should return false but the current
  // focused view shouldn't change.
  EXPECT_TRUE(focus_manager->RotatePaneFocus(
      FocusManager::kForward, FocusManager::kNoWrap));
  EXPECT_EQ(v3, focus_manager->GetFocusedView());

  EXPECT_FALSE(focus_manager->RotatePaneFocus(
      FocusManager::kForward, FocusManager::kNoWrap));
  EXPECT_EQ(v3, focus_manager->GetFocusedView());
}

// Verifies the stored focus view tracks the focused view.
TEST_F(FocusManagerTest, ImplicitlyStoresFocus) {
  views::View* v1 = new View;
  v1->SetFocusable(true);
  GetContentsView()->AddChildView(v1);

  views::View* v2 = new View;
  v2->SetFocusable(true);
  GetContentsView()->AddChildView(v2);

  // Verify a focus request on |v1| implicitly updates the stored focus view.
  v1->RequestFocus();
  EXPECT_TRUE(v1->HasFocus());
  EXPECT_EQ(v1, GetWidget()->GetFocusManager()->GetStoredFocusView());

  // Verify a focus request on |v2| implicitly updates the stored focus view.
  v2->RequestFocus();
  EXPECT_TRUE(v2->HasFocus());
  EXPECT_EQ(v2, GetWidget()->GetFocusManager()->GetStoredFocusView());
}

namespace  {

class FocusManagerArrowKeyTraversalTest : public FocusManagerTest {
 public:
  FocusManagerArrowKeyTraversalTest()
      : previous_arrow_key_traversal_enabled_(false) {
  }
  virtual ~FocusManagerArrowKeyTraversalTest() {}

  // FocusManagerTest overrides:
  virtual void SetUp() OVERRIDE {
    FocusManagerTest::SetUp();

    previous_arrow_key_traversal_enabled_ =
      FocusManager::arrow_key_traversal_enabled();
  }
  virtual void TearDown() OVERRIDE {
    FocusManager::set_arrow_key_traversal_enabled(
        previous_arrow_key_traversal_enabled_);
    FocusManagerTest::TearDown();
  }

 private:
  bool previous_arrow_key_traversal_enabled_;

  DISALLOW_COPY_AND_ASSIGN(FocusManagerArrowKeyTraversalTest);
};

}  // namespace

TEST_F(FocusManagerArrowKeyTraversalTest, ArrowKeyTraversal) {
  FocusManager* focus_manager = GetFocusManager();
  const ui::KeyEvent left_key(
      ui::ET_KEY_PRESSED, ui::VKEY_LEFT, ui::EF_NONE, false);
  const ui::KeyEvent right_key(
      ui::ET_KEY_PRESSED, ui::VKEY_RIGHT, ui::EF_NONE, false);
  const ui::KeyEvent up_key(
      ui::ET_KEY_PRESSED, ui::VKEY_UP, ui::EF_NONE, false);
  const ui::KeyEvent down_key(
      ui::ET_KEY_PRESSED, ui::VKEY_DOWN, ui::EF_NONE, false);

  std::vector<views::View*> v;
  for (size_t i = 0; i < 2; ++i) {
    views::View* view = new View;
    view->SetFocusable(true);
    GetContentsView()->AddChildView(view);
    v.push_back(view);
  }

  // Arrow key traversal is off and arrow key does not change focus.
  FocusManager::set_arrow_key_traversal_enabled(false);
  v[0]->RequestFocus();
  focus_manager->OnKeyEvent(right_key);
  EXPECT_EQ(v[0], focus_manager->GetFocusedView());
  focus_manager->OnKeyEvent(left_key);
  EXPECT_EQ(v[0], focus_manager->GetFocusedView());
  focus_manager->OnKeyEvent(down_key);
  EXPECT_EQ(v[0], focus_manager->GetFocusedView());
  focus_manager->OnKeyEvent(up_key);
  EXPECT_EQ(v[0], focus_manager->GetFocusedView());

  // Turn on arrow key traversal.
  FocusManager::set_arrow_key_traversal_enabled(true);
  v[0]->RequestFocus();
  focus_manager->OnKeyEvent(right_key);
  EXPECT_EQ(v[1], focus_manager->GetFocusedView());
  focus_manager->OnKeyEvent(left_key);
  EXPECT_EQ(v[0], focus_manager->GetFocusedView());
  focus_manager->OnKeyEvent(down_key);
  EXPECT_EQ(v[1], focus_manager->GetFocusedView());
  focus_manager->OnKeyEvent(up_key);
  EXPECT_EQ(v[0], focus_manager->GetFocusedView());
}

TEST_F(FocusManagerTest, StoreFocusedView) {
  View view;
  GetFocusManager()->SetFocusedView(&view);
  GetFocusManager()->StoreFocusedView(false);
  EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
  EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
  EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());

  // Repeat with |true|.
  GetFocusManager()->SetFocusedView(&view);
  GetFocusManager()->StoreFocusedView(true);
  EXPECT_EQ(NULL, GetFocusManager()->GetFocusedView());
  EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
  EXPECT_EQ(&view, GetFocusManager()->GetStoredFocusView());
}

class TextInputTestView : public View {
 public:
  TextInputTestView() {}

  virtual ui::TextInputClient* GetTextInputClient() OVERRIDE {
    return &text_input_client_;
  }

 private:
  ui::DummyTextInputClient text_input_client_;

  DISALLOW_COPY_AND_ASSIGN(TextInputTestView);
};

TEST_F(FocusManagerTest, TextInputClient) {
  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
  cmd_line->AppendSwitch(switches::kEnableTextInputFocusManager);

  View* view = new TextInputTestView;
  ui::TextInputClient* text_input_client = view->GetTextInputClient();
  view->SetFocusable(true);
  GetContentsView()->AddChildView(view);
  ui::TextInputFocusManager* text_input_focus_manager =
      ui::TextInputFocusManager::GetInstance();

  GetFocusManager()->SetFocusedView(view);
  EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
  EXPECT_EQ(text_input_client,
            text_input_focus_manager->GetFocusedTextInputClient());
  GetFocusManager()->StoreFocusedView(false);
  EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
  EXPECT_EQ(text_input_client,
            text_input_focus_manager->GetFocusedTextInputClient());

  // Repeat with |true|.
  GetFocusManager()->SetFocusedView(view);
  EXPECT_EQ(view, GetFocusManager()->GetFocusedView());
  EXPECT_EQ(text_input_client,
            text_input_focus_manager->GetFocusedTextInputClient());
  GetFocusManager()->StoreFocusedView(true);
  EXPECT_TRUE(GetFocusManager()->RestoreFocusedView());
  EXPECT_EQ(text_input_client,
            text_input_focus_manager->GetFocusedTextInputClient());

  // Focus the view twice in a row.
  GetFocusManager()->SetFocusedView(view);
  EXPECT_EQ(text_input_client,
            text_input_focus_manager->GetFocusedTextInputClient());
  ui::TextInputFocusManager::GetInstance()->FocusTextInputClient(NULL);
  GetFocusManager()->SetFocusedView(view);
  EXPECT_EQ(text_input_client,
            text_input_focus_manager->GetFocusedTextInputClient());
}

namespace {

// Trivial WidgetDelegate implementation that allows setting return value of
// ShouldAdvanceFocusToTopLevelWidget().
class AdvanceFocusWidgetDelegate : public WidgetDelegate {
 public:
  explicit AdvanceFocusWidgetDelegate(Widget* widget)
      : widget_(widget),
        should_advance_focus_to_parent_(false) {}
  virtual ~AdvanceFocusWidgetDelegate() {}

  void set_should_advance_focus_to_parent(bool value) {
    should_advance_focus_to_parent_ = value;
  }

  // WidgetDelegate overrides:
  virtual bool ShouldAdvanceFocusToTopLevelWidget() const OVERRIDE {
    return should_advance_focus_to_parent_;
  }
  virtual Widget* GetWidget() OVERRIDE { return widget_; }
  virtual const Widget* GetWidget() const OVERRIDE { return widget_; }

 private:
  Widget* widget_;
  bool should_advance_focus_to_parent_;

  DISALLOW_COPY_AND_ASSIGN(AdvanceFocusWidgetDelegate);
};

}  // namespace

// Verifies focus wrapping happens in the same widget.
TEST_F(FocusManagerTest, AdvanceFocusStaysInWidget) {
  // Add |widget_view| as a child of the Widget.
  View* widget_view = new View;
  widget_view->SetFocusable(true);
  widget_view->SetBounds(20, 0, 20, 20);
  GetContentsView()->AddChildView(widget_view);

  // Create a widget with two views, focus the second.
  scoped_ptr<AdvanceFocusWidgetDelegate> delegate;
  Widget::InitParams params = CreateParams(Widget::InitParams::TYPE_WINDOW);
  params.ownership = views::Widget::InitParams::WIDGET_OWNS_NATIVE_WIDGET;
  params.child = true;
  params.bounds = gfx::Rect(10, 10, 100, 100);
  params.parent = GetWidget()->GetNativeView();
  Widget child_widget;
  delegate.reset(new AdvanceFocusWidgetDelegate(&child_widget));
  params.delegate = delegate.get();
  child_widget.Init(params);
  View* view1 = new View;
  view1->SetFocusable(true);
  view1->SetBounds(0, 0, 20, 20);
  View* view2 = new View;
  view2->SetFocusable(true);
  view2->SetBounds(20, 0, 20, 20);
  child_widget.client_view()->AddChildView(view1);
  child_widget.client_view()->AddChildView(view2);
  child_widget.Show();
  view2->RequestFocus();
  EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());

  // Advance focus backwards, which should focus the first.
  GetFocusManager()->AdvanceFocus(false);
  EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());

  // Focus forward to |view2|.
  GetFocusManager()->AdvanceFocus(true);
  EXPECT_EQ(view2, GetFocusManager()->GetFocusedView());

  // And forward again, wrapping back to |view1|.
  GetFocusManager()->AdvanceFocus(true);
  EXPECT_EQ(view1, GetFocusManager()->GetFocusedView());

  // Allow focus to go to the parent, and focus backwards which should now move
  // up |widget_view| (in the parent).
  delegate->set_should_advance_focus_to_parent(true);
  GetFocusManager()->AdvanceFocus(true);
  EXPECT_EQ(widget_view, GetFocusManager()->GetFocusedView());
}

}  // namespace views
