1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/devtools/devtools_window_testing.h"
6
7#include "base/lazy_instance.h"
8#include "chrome/browser/devtools/devtools_window.h"
9#include "chrome/browser/ui/browser.h"
10#include "chrome/browser/ui/browser_window.h"
11#include "chrome/browser/ui/tabs/tab_strip_model.h"
12#include "content/public/browser/devtools_agent_host.h"
13#include "content/public/browser/render_view_host.h"
14#include "content/public/browser/web_contents.h"
15#include "content/public/test/test_utils.h"
16
17namespace {
18
19typedef std::vector<DevToolsWindowTesting*> DevToolsWindowTestings;
20base::LazyInstance<DevToolsWindowTestings>::Leaky g_instances =
21    LAZY_INSTANCE_INITIALIZER;
22
23}
24
25DevToolsWindowTesting::DevToolsWindowTesting(DevToolsWindow* window)
26    : devtools_window_(window) {
27  DCHECK(window);
28  window->close_callback_ =
29      base::Bind(&DevToolsWindowTesting::WindowClosed, window);
30  g_instances.Get().push_back(this);
31}
32
33DevToolsWindowTesting::~DevToolsWindowTesting() {
34  DevToolsWindowTestings* instances = g_instances.Pointer();
35  DevToolsWindowTestings::iterator it(
36      std::find(instances->begin(), instances->end(), this));
37  DCHECK(it != instances->end());
38  instances->erase(it);
39  if (!close_callback_.is_null()) {
40    close_callback_.Run();
41    close_callback_ = base::Closure();
42  }
43}
44
45// static
46DevToolsWindowTesting* DevToolsWindowTesting::Get(DevToolsWindow* window) {
47  DevToolsWindowTesting* testing = DevToolsWindowTesting::Find(window);
48  if (!testing)
49    testing = new DevToolsWindowTesting(window);
50  return testing;
51}
52
53// static
54DevToolsWindowTesting* DevToolsWindowTesting::Find(DevToolsWindow* window) {
55  if (g_instances == NULL)
56    return NULL;
57  DevToolsWindowTestings* instances = g_instances.Pointer();
58  for (DevToolsWindowTestings::iterator it(instances->begin());
59       it != instances->end();
60       ++it) {
61    if ((*it)->devtools_window_ == window)
62      return *it;
63  }
64  return NULL;
65}
66
67Browser* DevToolsWindowTesting::browser() {
68  return devtools_window_->browser_;
69}
70
71content::WebContents* DevToolsWindowTesting::main_web_contents() {
72  return devtools_window_->main_web_contents_;
73}
74
75content::WebContents* DevToolsWindowTesting::toolbox_web_contents() {
76  return devtools_window_->toolbox_web_contents_;
77}
78
79void DevToolsWindowTesting::SetInspectedPageBounds(const gfx::Rect& bounds) {
80  devtools_window_->SetInspectedPageBounds(bounds);
81}
82
83void DevToolsWindowTesting::SetCloseCallback(const base::Closure& closure) {
84  close_callback_ = closure;
85}
86
87// static
88void DevToolsWindowTesting::WindowClosed(DevToolsWindow* window) {
89  DevToolsWindowTesting* testing = DevToolsWindowTesting::Find(window);
90  if (testing)
91    delete testing;
92}
93
94// static
95void DevToolsWindowTesting::WaitForDevToolsWindowLoad(DevToolsWindow* window) {
96  scoped_refptr<content::MessageLoopRunner> runner =
97      new content::MessageLoopRunner;
98  window->SetLoadCompletedCallback(runner->QuitClosure());
99  runner->Run();
100}
101
102// static
103DevToolsWindow* DevToolsWindowTesting::OpenDevToolsWindowSync(
104    content::WebContents* inspected_web_contents,
105    bool is_docked) {
106  std::string settings = is_docked ?
107      "{\"currentDockState\":\"\\\"bottom\\\"\"}" :
108      "{\"currentDockState\":\"\\\"undocked\\\"\"}";
109  DevToolsWindow* window = DevToolsWindow::ToggleDevToolsWindow(
110      inspected_web_contents, true, DevToolsToggleAction::Show(), settings);
111  WaitForDevToolsWindowLoad(window);
112  return window;
113}
114
115// static
116DevToolsWindow* DevToolsWindowTesting::OpenDevToolsWindowSync(
117    Browser* browser,
118    bool is_docked) {
119  return OpenDevToolsWindowSync(
120      browser->tab_strip_model()->GetActiveWebContents(), is_docked);
121}
122
123// static
124DevToolsWindow* DevToolsWindowTesting::OpenDevToolsWindowForWorkerSync(
125    Profile* profile, content::DevToolsAgentHost* worker_agent) {
126  DevToolsWindow* window = DevToolsWindow::OpenDevToolsWindowForWorker(
127      profile, worker_agent);
128  WaitForDevToolsWindowLoad(window);
129  return window;
130}
131
132// static
133void DevToolsWindowTesting::CloseDevToolsWindow(
134    DevToolsWindow* window) {
135  if (window->is_docked_) {
136    window->CloseWindow();
137  } else {
138    window->browser_->window()->Close();
139  }
140}
141
142// static
143void DevToolsWindowTesting::CloseDevToolsWindowSync(
144    DevToolsWindow* window) {
145  scoped_refptr<content::MessageLoopRunner> runner =
146      new content::MessageLoopRunner;
147  DevToolsWindowTesting::Get(window)->SetCloseCallback(runner->QuitClosure());
148  CloseDevToolsWindow(window);
149  runner->Run();
150}
151