Enable Enterprise enrollment on desktop builds.
[chromium-blink-merge.git] / chrome / browser / devtools / devtools_window.h
blob379b0bd6063f3899808366c0d9d8edc3fd9edcfa
1 // Copyright (c) 2012 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.
5 #ifndef CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_
6 #define CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_
8 #include "chrome/browser/devtools/devtools_contents_resizing_strategy.h"
9 #include "chrome/browser/devtools/devtools_toggle_action.h"
10 #include "chrome/browser/devtools/devtools_ui_bindings.h"
11 #include "content/public/browser/web_contents_delegate.h"
13 class Browser;
14 class BrowserWindow;
15 class DevToolsControllerTest;
16 class DevToolsEventForwarder;
18 namespace content {
19 class DevToolsAgentHost;
20 struct NativeWebKeyboardEvent;
21 class RenderViewHost;
24 namespace user_prefs {
25 class PrefRegistrySyncable;
28 class DevToolsWindow : public DevToolsUIBindings::Delegate,
29 public content::WebContentsDelegate {
30 public:
31 static const char kDevToolsApp[];
33 virtual ~DevToolsWindow();
35 static std::string GetDevToolsWindowPlacementPrefKey();
36 static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
38 // Return the DevToolsWindow for the given RenderViewHost if one exists,
39 // otherwise NULL.
40 static DevToolsWindow* GetInstanceForInspectedRenderViewHost(
41 content::RenderViewHost* inspected_rvh);
43 // Return the DevToolsWindow for the given WebContents if one exists,
44 // otherwise NULL.
45 static DevToolsWindow* GetInstanceForInspectedWebContents(
46 content::WebContents* inspected_web_contents);
48 // Return the DevToolsWindow for the given WebContents if one exists and is
49 // docked, otherwise NULL. This method will return only fully initialized
50 // window ready to be presented in UI.
51 // For immediately-ready-to-use but maybe not yet fully initialized DevTools
52 // use |GetInstanceForInspectedRenderViewHost| instead.
53 static DevToolsWindow* GetDockedInstanceForInspectedTab(
54 content::WebContents* inspected_tab);
56 static bool IsDevToolsWindow(content::RenderViewHost* window_rvh);
58 // Open or reveal DevTools window, and perform the specified action.
59 static DevToolsWindow* OpenDevToolsWindow(
60 content::RenderViewHost* inspected_rvh,
61 const DevToolsToggleAction& action);
63 // Open or reveal DevTools window, with no special action.
64 static DevToolsWindow* OpenDevToolsWindow(
65 content::RenderViewHost* inspected_rvh);
67 static DevToolsWindow* OpenDevToolsWindowForTest(
68 content::RenderViewHost* inspected_rvh, bool is_docked);
69 static DevToolsWindow* OpenDevToolsWindowForTest(
70 Browser* browser, bool is_docked);
72 // Perform specified action for current WebContents inside a |browser|.
73 // This may close currently open DevTools window.
74 static DevToolsWindow* ToggleDevToolsWindow(
75 Browser* browser,
76 const DevToolsToggleAction& action);
78 // External frontend is always undocked.
79 static void OpenExternalFrontend(
80 Profile* profile,
81 const std::string& frontend_uri,
82 content::DevToolsAgentHost* agent_host);
84 // Worker frontend is always undocked.
85 static DevToolsWindow* OpenDevToolsWindowForWorker(
86 Profile* profile,
87 content::DevToolsAgentHost* worker_agent);
89 static void InspectElement(
90 content::RenderViewHost* inspected_rvh, int x, int y);
92 content::WebContents* web_contents() { return web_contents_; }
94 Browser* browser() { return browser_; } // For tests.
96 // Inspected WebContents is placed over DevTools WebContents in docked mode.
97 // The following method returns the resizing strategy of inspected
98 // WebContents relative to DevTools WebContents.
99 const DevToolsContentsResizingStrategy& GetContentsResizingStrategy() const;
101 // Minimum size of the docked DevTools WebContents. This includes
102 // the overlaying inspected WebContents size.
103 gfx::Size GetMinimumSize() const;
105 // Sets closure to be called after load is done. If already loaded, calls
106 // closure immediately.
107 void SetLoadCompletedCallback(const base::Closure& closure);
109 // Forwards an unhandled keyboard event to the DevTools frontend.
110 bool ForwardKeyboardEvent(const content::NativeWebKeyboardEvent& event);
112 // BeforeUnload interception ////////////////////////////////////////////////
114 // In order to preserve any edits the user may have made in devtools, the
115 // beforeunload event of the inspected page is hooked - devtools gets the
116 // first shot at handling beforeunload and presents a dialog to the user. If
117 // the user accepts the dialog then the script is given a chance to handle
118 // it. This way 2 dialogs may be displayed: one from the devtools asking the
119 // user to confirm that they're ok with their devtools edits going away and
120 // another from the webpage as the result of its beforeunload handler.
121 // The following set of methods handle beforeunload event flow through
122 // devtools window. When the |contents| with devtools opened on them are
123 // getting closed, the following sequence of calls takes place:
124 // 1. |DevToolsWindow::InterceptPageBeforeUnload| is called and indicates
125 // whether devtools intercept the beforeunload event.
126 // If InterceptPageBeforeUnload() returns true then the following steps
127 // will take place; otherwise only step 4 will be reached and none of the
128 // corresponding functions in steps 2 & 3 will get called.
129 // 2. |DevToolsWindow::InterceptPageBeforeUnload| fires beforeunload event
130 // for devtools frontend, which will asynchronously call
131 // |WebContentsDelegate::BeforeUnloadFired| method.
132 // In case of docked devtools window, devtools are set as a delegate for
133 // its frontend, so method |DevToolsWindow::BeforeUnloadFired| will be
134 // called directly.
135 // If devtools window is undocked it's not set as the delegate so the call
136 // to BeforeUnloadFired is proxied through HandleBeforeUnload() rather
137 // than getting called directly.
138 // 3a. If |DevToolsWindow::BeforeUnloadFired| is called with |proceed|=false
139 // it calls throught to the content's BeforeUnloadFired(), which from the
140 // WebContents perspective looks the same as the |content|'s own
141 // beforeunload dialog having had it's 'stay on this page' button clicked.
142 // 3b. If |proceed| = true, then it fires beforeunload event on |contents|
143 // and everything proceeds as it normally would without the Devtools
144 // interception.
145 // 4. If the user cancels the dialog put up by either the WebContents or
146 // devtools frontend, then |contents|'s |BeforeUnloadFired| callback is
147 // called with the proceed argument set to false, this causes
148 // |DevToolsWindow::OnPageCloseCancelled| to be called.
150 // Devtools window in undocked state is not set as a delegate of
151 // its frontend. Instead, an instance of browser is set as the delegate, and
152 // thus beforeunload event callback from devtools frontend is not delivered
153 // to the instance of devtools window, which is solely responsible for
154 // managing custom beforeunload event flow.
155 // This is a helper method to route callback from
156 // |Browser::BeforeUnloadFired| back to |DevToolsWindow::BeforeUnloadFired|.
157 // * |proceed| - true if the user clicked 'ok' in the beforeunload dialog,
158 // false otherwise.
159 // * |proceed_to_fire_unload| - output parameter, whether we should continue
160 // to fire the unload event or stop things here.
161 // Returns true if devtools window is in a state of intercepting beforeunload
162 // event and if it will manage unload process on its own.
163 static bool HandleBeforeUnload(content::WebContents* contents,
164 bool proceed,
165 bool* proceed_to_fire_unload);
167 // Returns true if this contents beforeunload event was intercepted by
168 // devtools and false otherwise. If the event was intercepted, caller should
169 // not fire beforeunlaod event on |contents| itself as devtools window will
170 // take care of it, otherwise caller should continue handling the event as
171 // usual.
172 static bool InterceptPageBeforeUnload(content::WebContents* contents);
174 // Returns true if devtools browser has already fired its beforeunload event
175 // as a result of beforeunload event interception.
176 static bool HasFiredBeforeUnloadEventForDevToolsBrowser(Browser* browser);
178 // Returns true if devtools window would like to hook beforeunload event
179 // of this |contents|.
180 static bool NeedsToInterceptBeforeUnload(content::WebContents* contents);
182 // Notify devtools window that closing of |contents| was cancelled
183 // by user.
184 static void OnPageCloseCanceled(content::WebContents* contents);
186 private:
187 friend class DevToolsControllerTest;
188 friend class DevToolsSanityTest;
189 friend class BrowserWindowControllerTest;
191 // DevTools initialization typically follows this way:
192 // - Toggle/Open: client call;
193 // - Create;
194 // - ScheduleShow: setup window to be functional, but not yet show;
195 // - DocumentOnLoadCompletedInMainFrame: frontend loaded;
196 // - SetIsDocked: frontend decided on docking state;
197 // - OnLoadCompleted: ready to present frontend;
198 // - Show: actually placing frontend WebContents to a Browser or docked place;
199 // - DoAction: perform action passed in Toggle/Open.
200 enum LoadState {
201 kNotLoaded,
202 kOnLoadFired, // Implies SetIsDocked was not yet called.
203 kIsDockedSet, // Implies DocumentOnLoadCompleted was not yet called.
204 kLoadCompleted
207 DevToolsWindow(Profile* profile,
208 const GURL& frontend_url,
209 content::RenderViewHost* inspected_rvh,
210 bool can_dock);
212 static DevToolsWindow* Create(Profile* profile,
213 const GURL& frontend_url,
214 content::RenderViewHost* inspected_rvh,
215 bool shared_worker_frontend,
216 bool external_frontend,
217 bool can_dock);
218 static GURL GetDevToolsURL(Profile* profile,
219 const GURL& base_url,
220 bool shared_worker_frontend,
221 bool external_frontend,
222 bool can_dock);
223 static DevToolsWindow* FindDevToolsWindow(content::DevToolsAgentHost*);
224 static DevToolsWindow* AsDevToolsWindow(content::RenderViewHost*);
225 static DevToolsWindow* CreateDevToolsWindowForWorker(Profile* profile);
226 static bool FindInspectedBrowserAndTabIndex(
227 content::WebContents* inspected_web_contents, Browser**, int* tab);
228 static DevToolsWindow* ToggleDevToolsWindow(
229 content::RenderViewHost* inspected_rvh,
230 bool force_open,
231 const DevToolsToggleAction& action);
233 // content::WebContentsDelegate:
234 virtual content::WebContents* OpenURLFromTab(
235 content::WebContents* source,
236 const content::OpenURLParams& params) OVERRIDE;
237 virtual void ActivateContents(content::WebContents* contents) OVERRIDE;
238 virtual void AddNewContents(content::WebContents* source,
239 content::WebContents* new_contents,
240 WindowOpenDisposition disposition,
241 const gfx::Rect& initial_pos,
242 bool user_gesture,
243 bool* was_blocked) OVERRIDE;
244 virtual void CloseContents(content::WebContents* source) OVERRIDE;
245 virtual void ContentsZoomChange(bool zoom_in) OVERRIDE;
246 virtual void BeforeUnloadFired(content::WebContents* tab,
247 bool proceed,
248 bool* proceed_to_fire_unload) OVERRIDE;
249 virtual bool PreHandleKeyboardEvent(
250 content::WebContents* source,
251 const content::NativeWebKeyboardEvent& event,
252 bool* is_keyboard_shortcut) OVERRIDE;
253 virtual void HandleKeyboardEvent(
254 content::WebContents* source,
255 const content::NativeWebKeyboardEvent& event) OVERRIDE;
256 virtual content::JavaScriptDialogManager*
257 GetJavaScriptDialogManager() OVERRIDE;
258 virtual content::ColorChooser* OpenColorChooser(
259 content::WebContents* web_contents,
260 SkColor color,
261 const std::vector<content::ColorSuggestion>& suggestions) OVERRIDE;
262 virtual void RunFileChooser(
263 content::WebContents* web_contents,
264 const content::FileChooserParams& params) OVERRIDE;
265 virtual void WebContentsFocused(content::WebContents* contents) OVERRIDE;
266 virtual bool PreHandleGestureEvent(
267 content::WebContents* source,
268 const blink::WebGestureEvent& event) OVERRIDE;
270 // content::DevToolsUIBindings::Delegate overrides
271 virtual void ActivateWindow() OVERRIDE;
272 virtual void CloseWindow() OVERRIDE;
273 virtual void SetContentsInsets(
274 int left, int top, int right, int bottom) OVERRIDE;
275 virtual void SetContentsResizingStrategy(
276 const gfx::Insets& insets, const gfx::Size& min_size) OVERRIDE;
277 virtual void InspectElementCompleted() OVERRIDE;
278 virtual void MoveWindow(int x, int y) OVERRIDE;
279 virtual void SetIsDocked(bool is_docked) OVERRIDE;
280 virtual void OpenInNewTab(const std::string& url) OVERRIDE;
281 virtual void SetWhitelistedShortcuts(const std::string& message) OVERRIDE;
282 virtual void InspectedContentsClosing() OVERRIDE;
283 virtual void OnLoadCompleted() OVERRIDE;
285 void CreateDevToolsBrowser();
286 BrowserWindow* GetInspectedBrowserWindow();
287 void ScheduleShow(const DevToolsToggleAction& action);
288 void Show(const DevToolsToggleAction& action);
289 void DoAction(const DevToolsToggleAction& action);
290 void LoadCompleted();
291 void SetIsDockedAndShowImmediatelyForTest(bool is_docked);
292 void UpdateBrowserToolbar();
293 content::WebContents* GetInspectedWebContents();
295 class InspectedWebContentsObserver;
296 scoped_ptr<InspectedWebContentsObserver> inspected_contents_observer_;
298 Profile* profile_;
299 content::WebContents* web_contents_;
300 DevToolsUIBindings* bindings_;
301 Browser* browser_;
302 bool is_docked_;
303 const bool can_dock_;
304 LoadState load_state_;
305 DevToolsToggleAction action_on_load_;
306 bool ignore_set_is_docked_;
307 DevToolsContentsResizingStrategy contents_resizing_strategy_;
308 // True if we're in the process of handling a beforeunload event originating
309 // from the inspected webcontents, see InterceptPageBeforeUnload for details.
310 bool intercepted_page_beforeunload_;
311 base::Closure load_completed_callback_;
313 base::TimeTicks inspect_element_start_time_;
314 scoped_ptr<DevToolsEventForwarder> event_forwarder_;
316 friend class DevToolsEventForwarder;
317 DISALLOW_COPY_AND_ASSIGN(DevToolsWindow);
320 #endif // CHROME_BROWSER_DEVTOOLS_DEVTOOLS_WINDOW_H_