blob: bba5e8e4599531b71a1288851ea56928e3a844ec [file] [log] [blame]
[email protected]9e790bd2011-01-10 23:48:541// Copyright (c) 2011 The Chromium Authors. All rights reserved.
license.botbf09a502008-08-24 00:55:552// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
initial.commit09911bf2008-07-26 23:55:294
[email protected]4bdde602010-06-16 03:17:355#include "chrome/browser/external_tab_container_win.h"
initial.commit09911bf2008-07-26 23:55:296
[email protected]4c540ee2009-07-07 17:15:557#include <string>
8
[email protected]58580352010-10-26 04:07:509#include "base/debug/trace_event.h"
[email protected]7cf1b6ce2010-03-20 06:37:0110#include "base/i18n/rtl.h"
initial.commit09911bf2008-07-26 23:55:2911#include "base/logging.h"
[email protected]944b4212010-12-14 00:00:3312#include "base/utf_string_conversions.h"
[email protected]a8e20582010-12-31 17:18:5013#include "base/win/win_util.h"
[email protected]1a3aba82010-11-08 23:52:5414#include "chrome/app/chrome_command_ids.h"
[email protected]0f8df8672010-11-09 00:36:3215#include "chrome/app/chrome_dll_resource.h"
[email protected]b3841c502011-03-09 01:21:3116#include "chrome/browser/automation/automation_provider.h"
[email protected]52933842009-09-29 03:44:0617#include "chrome/browser/debugger/devtools_manager.h"
[email protected]2a8a98122010-07-16 11:58:4818#include "chrome/browser/debugger/devtools_toggle_action.h"
[email protected]91a79232010-11-10 18:15:0819#include "chrome/browser/google/google_util.h"
[email protected]ec0b6c42010-08-26 03:16:5820#include "chrome/browser/history/history_types.h"
[email protected]33ee8da2009-04-16 17:45:3721#include "chrome/browser/load_notification_details.h"
[email protected]21e302e2009-09-12 23:10:4122#include "chrome/browser/page_info_window.h"
[email protected]8ecad5e2010-12-02 21:18:3323#include "chrome/browser/profiles/profile.h"
[email protected]a8c229cc2011-01-13 22:31:5824#include "chrome/browser/ui/browser.h"
[email protected]00070c732011-04-09 15:31:3325#include "chrome/browser/ui/browser_window.h"
[email protected]7b8d4a22011-02-10 20:57:5426#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9e790bd2011-01-10 23:48:5427#include "chrome/browser/ui/views/browser_dialogs.h"
[email protected]6c6614f12011-03-31 18:51:4228#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
[email protected]9e790bd2011-01-10 23:48:5429#include "chrome/browser/ui/views/page_info_bubble_view.h"
30#include "chrome/browser/ui/views/tab_contents/render_view_context_menu_views.h"
31#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h"
[email protected]a8ba6362010-11-10 20:02:2532#include "chrome/common/automation_messages.h"
initial.commit09911bf2008-07-26 23:55:2933#include "chrome/common/chrome_constants.h"
[email protected]91a79232010-11-10 18:15:0834#include "chrome/common/url_constants.h"
[email protected]5de634712011-03-02 00:20:1935#include "content/browser/renderer_host/render_process_host.h"
36#include "content/browser/renderer_host/render_view_host.h"
37#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
[email protected]299425b2011-03-02 07:45:2038#include "content/browser/tab_contents/provisional_load_details.h"
[email protected]9966325b2011-04-18 05:00:1039#include "content/common/bindings_policy.h"
[email protected]4dd57932011-03-17 06:06:1240#include "content/common/native_web_keyboard_event.h"
[email protected]b3841c502011-03-09 01:21:3141#include "content/common/notification_service.h"
[email protected]4dd57932011-03-17 06:06:1242#include "content/common/page_transition_types.h"
[email protected]0aed2f52011-03-23 18:06:3643#include "content/common/view_messages.h"
[email protected]e943d6662009-06-12 03:50:3944#include "grit/generated_resources.h"
[email protected]0b7a012d2010-10-19 23:49:2645#include "grit/locale_settings.h"
[email protected]c051a1b2011-01-21 23:30:1746#include "ui/base/l10n/l10n_util.h"
[email protected]9ac174e92011-04-16 00:58:5647#include "ui/base/resource/resource_bundle.h"
[email protected]9dd7e3d72011-01-20 18:27:0648#include "ui/base/view_prop.h"
[email protected]9ef7d4b2011-01-27 02:17:2149#include "views/layout/grid_layout.h"
[email protected]ab861b42010-02-05 19:13:4450#include "views/widget/root_view.h"
[email protected]21e302e2009-09-12 23:10:4151#include "views/window/window.h"
[email protected]e943d6662009-06-12 03:50:3952
[email protected]9dd7e3d72011-01-20 18:27:0653using ui::ViewProp;
[email protected]3b8a7f8e2010-11-21 22:44:2154
55static const char kWindowObjectKey[] = "ChromeWindowObject";
initial.commit09911bf2008-07-26 23:55:2956
[email protected]5168c72c2011-04-25 17:30:2357// This class overrides the LinkClicked function in the PageInfoBubbleView
[email protected]0b7a012d2010-10-19 23:49:2658// class and routes the help center link navigation to the host browser.
59class ExternalTabPageInfoBubbleView : public PageInfoBubbleView {
60 public:
61 ExternalTabPageInfoBubbleView(ExternalTabContainer* container,
62 gfx::NativeWindow parent_window,
63 Profile* profile,
64 const GURL& url,
65 const NavigationEntry::SSLStatus& ssl,
66 bool show_history)
67 : PageInfoBubbleView(parent_window, profile, url, ssl, show_history),
68 container_(container) {
[email protected]5044da82010-10-27 01:09:1669 DVLOG(1) << __FUNCTION__;
[email protected]0b7a012d2010-10-19 23:49:2670 }
71 virtual ~ExternalTabPageInfoBubbleView() {
[email protected]5044da82010-10-27 01:09:1672 DVLOG(1) << __FUNCTION__;
[email protected]0b7a012d2010-10-19 23:49:2673 }
[email protected]5168c72c2011-04-25 17:30:2374 // LinkListener methods:
75 virtual void LinkClicked(views::Link* source, int event_flags) OVERRIDE {
[email protected]91a79232010-11-10 18:15:0876 GURL url = google_util::AppendGoogleLocaleParam(
77 GURL(chrome::kPageInfoHelpCenterURL));
[email protected]0b7a012d2010-10-19 23:49:2678 container_->OpenURLFromTab(container_->tab_contents(), url, GURL(),
79 NEW_FOREGROUND_TAB, PageTransition::LINK);
80 }
81 private:
82 scoped_refptr<ExternalTabContainer> container_;
83};
84
[email protected]d0ed50d2010-06-22 01:01:3285base::LazyInstance<ExternalTabContainer::PendingTabs>
86 ExternalTabContainer::pending_tabs_(base::LINKER_INITIALIZED);
87
initial.commit09911bf2008-07-26 23:55:2988ExternalTabContainer::ExternalTabContainer(
[email protected]2e4633c2009-07-09 16:58:0689 AutomationProvider* automation, AutomationResourceMessageFilter* filter)
initial.commit09911bf2008-07-26 23:55:2990 : automation_(automation),
[email protected]2e39d2e2009-02-19 18:41:3191 tab_contents_container_(NULL),
[email protected]eac83f02009-05-08 18:44:4492 tab_handle_(0),
[email protected]2e4633c2009-07-09 16:58:0693 ignore_next_load_notification_(false),
94 automation_resource_message_filter_(filter),
[email protected]a50a4902009-08-14 22:39:0195 load_requests_via_automation_(false),
[email protected]24f98bba2009-10-14 18:47:4996 handle_top_level_requests_(false),
[email protected]4cfc1d922009-11-08 14:02:5897 external_method_factory_(this),
[email protected]f7019302010-03-26 19:58:3298 pending_(false),
[email protected]93685472010-04-23 00:57:5099 infobars_enabled_(true),
[email protected]ba67fd82010-07-09 18:30:31100 focus_manager_(NULL),
[email protected]1f71d5882010-07-15 20:39:07101 external_tab_view_(NULL),
[email protected]9eeb35e2010-09-30 21:38:50102 unload_reply_message_(NULL),
[email protected]326d3b72011-03-29 20:38:24103 route_all_top_level_navigations_(false),
104 is_popup_window_(false) {
initial.commit09911bf2008-07-26 23:55:29105}
106
107ExternalTabContainer::~ExternalTabContainer() {
[email protected]632fbb12009-09-06 15:27:14108 Uninitialize();
initial.commit09911bf2008-07-26 23:55:29109}
110
[email protected]7b8d4a22011-02-10 20:57:54111TabContents* ExternalTabContainer::tab_contents() const {
112 return tab_contents_.get() ? tab_contents_->tab_contents() : NULL;
113}
114
[email protected]9095e982009-05-27 17:28:24115bool ExternalTabContainer::Init(Profile* profile,
116 HWND parent,
117 const gfx::Rect& bounds,
[email protected]95c3c592009-07-14 22:09:03118 DWORD style,
[email protected]5f450e52009-07-28 13:28:11119 bool load_requests_via_automation,
[email protected]a50a4902009-08-14 22:39:01120 bool handle_top_level_requests,
[email protected]7b8d4a22011-02-10 20:57:54121 TabContentsWrapper* existing_contents,
[email protected]7de487c2009-12-18 21:07:53122 const GURL& initial_url,
[email protected]f7019302010-03-26 19:58:32123 const GURL& referrer,
[email protected]9eeb35e2010-09-30 21:38:50124 bool infobars_enabled,
125 bool route_all_top_level_navigations) {
initial.commit09911bf2008-07-26 23:55:29126 if (IsWindow()) {
127 NOTREACHED();
128 return false;
129 }
[email protected]0498f7f82009-02-24 03:04:12130
[email protected]95c3c592009-07-14 22:09:03131 load_requests_via_automation_ = load_requests_via_automation;
[email protected]a50a4902009-08-14 22:39:01132 handle_top_level_requests_ = handle_top_level_requests;
[email protected]f7019302010-03-26 19:58:32133 infobars_enabled_ = infobars_enabled;
[email protected]9eeb35e2010-09-30 21:38:50134 route_all_top_level_navigations_ = route_all_top_level_navigations;
[email protected]95c3c592009-07-14 22:09:03135
[email protected]6603fe92009-08-05 17:05:57136 set_window_style(WS_POPUP | WS_CLIPCHILDREN);
[email protected]f258bbe02011-02-14 20:38:10137 views::WidgetWin::Init(NULL, bounds);
[email protected]08ed00a2009-05-28 20:48:14138 if (!IsWindow()) {
139 NOTREACHED();
140 return false;
141 }
[email protected]f5cde2b2009-09-11 22:33:58142
[email protected]82166b62009-06-30 18:48:00143 // TODO(jcampan): limit focus traversal to contents.
initial.commit09911bf2008-07-26 23:55:29144
[email protected]3b8a7f8e2010-11-21 22:44:21145 prop_.reset(new ViewProp(GetNativeView(), kWindowObjectKey, this));
initial.commit09911bf2008-07-26 23:55:29146
[email protected]632fbb12009-09-06 15:27:14147 if (existing_contents) {
[email protected]7b8d4a22011-02-10 20:57:54148 tab_contents_.reset(existing_contents);
[email protected]632fbb12009-09-06 15:27:14149 tab_contents_->controller().set_profile(profile);
150 } else {
[email protected]7b8d4a22011-02-10 20:57:54151 TabContents* new_contents = new TabContents(profile, NULL, MSG_ROUTING_NONE,
152 NULL, NULL);
153 tab_contents_.reset(new TabContentsWrapper(new_contents));
[email protected]632fbb12009-09-06 15:27:14154 }
[email protected]a50a4902009-08-14 22:39:01155
[email protected]7b8d4a22011-02-10 20:57:54156 tab_contents_->tab_contents()->set_delegate(this);
[email protected]632fbb12009-09-06 15:27:14157
[email protected]7b8d4a22011-02-10 20:57:54158 tab_contents_->tab_contents()->
159 GetMutableRendererPrefs()->browser_handles_top_level_requests =
160 handle_top_level_requests;
[email protected]a50a4902009-08-14 22:39:01161
162 if (!existing_contents) {
163 tab_contents_->render_view_host()->AllowBindings(
164 BindingsPolicy::EXTERNAL_HOST);
165 }
[email protected]18cb2572008-08-21 20:34:45166
[email protected]ce3fa3c2009-04-20 19:55:57167 NavigationController* controller = &tab_contents_->controller();
[email protected]bfd04a62009-02-01 18:16:56168 registrar_.Add(this, NotificationType::NAV_ENTRY_COMMITTED,
[email protected]0e8db942008-09-24 21:21:48169 Source<NavigationController>(controller));
[email protected]2e39d2e2009-02-19 18:41:31170 registrar_.Add(this, NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR,
171 Source<NavigationController>(controller));
[email protected]33ee8da2009-04-16 17:45:37172 registrar_.Add(this, NotificationType::LOAD_STOP,
173 Source<NavigationController>(controller));
[email protected]2e4633c2009-07-09 16:58:06174 registrar_.Add(this, NotificationType::RENDER_VIEW_HOST_CREATED_FOR_TAB,
[email protected]7b8d4a22011-02-10 20:57:54175 Source<TabContents>(tab_contents_->tab_contents()));
[email protected]2e4633c2009-07-09 16:58:06176 registrar_.Add(this, NotificationType::RENDER_VIEW_HOST_DELETED,
[email protected]6b5b0cd2011-03-31 21:11:41177 NotificationService::AllSources());
[email protected]2e4633c2009-07-09 16:58:06178
[email protected]bfd04a62009-02-01 18:16:56179 NotificationService::current()->Notify(
180 NotificationType::EXTERNAL_TAB_CREATED,
181 Source<NavigationController>(controller),
182 NotificationService::NoDetails());
[email protected]31fb110522009-01-28 21:50:39183
[email protected]f5cde2b2009-09-11 22:33:58184 // Start loading initial URL
185 if (!initial_url.is_empty()) {
186 // Navigate out of context since we don't have a 'tab_handle_' yet.
[email protected]24f98bba2009-10-14 18:47:49187 MessageLoop::current()->PostTask(
188 FROM_HERE,
189 external_method_factory_.NewRunnableMethod(
[email protected]7de487c2009-12-18 21:07:53190 &ExternalTabContainer::Navigate, initial_url, referrer));
[email protected]f5cde2b2009-09-11 22:33:58191 }
192
[email protected]0498f7f82009-02-24 03:04:12193 // We need WS_POPUP to be on the window during initialization, but
194 // once initialized we apply the requested style which may or may not
195 // include the popup bit.
196 // Note that it's important to do this before we call SetParent since
197 // during the SetParent call we will otherwise get a WA_ACTIVATE call
198 // that causes us to steal the current focus.
[email protected]9095e982009-05-27 17:28:24199 SetWindowLong(GWL_STYLE, (GetWindowLong(GWL_STYLE) & ~WS_POPUP) | style);
[email protected]0498f7f82009-02-24 03:04:12200
[email protected]31fb110522009-01-28 21:50:39201 // Now apply the parenting and style
202 if (parent)
[email protected]9095e982009-05-27 17:28:24203 SetParent(GetNativeView(), parent);
[email protected]7e503122009-02-04 21:52:48204
[email protected]7b8d4a22011-02-10 20:57:54205 ::ShowWindow(tab_contents_->tab_contents()->GetNativeView(), SW_SHOWNA);
[email protected]e943d6662009-06-12 03:50:39206
[email protected]3f70c1e12010-01-12 20:38:49207 LoadAccelerators();
[email protected]ab861b42010-02-05 19:13:44208 SetupExternalTabView();
initial.commit09911bf2008-07-26 23:55:29209 return true;
210}
211
[email protected]632fbb12009-09-06 15:27:14212void ExternalTabContainer::Uninitialize() {
213 registrar_.RemoveAll();
[email protected]7b8d4a22011-02-10 20:57:54214 if (tab_contents_.get()) {
[email protected]39ec12f2011-03-25 23:02:28215 UnregisterRenderViewHost(tab_contents_->render_view_host());
[email protected]52933842009-09-29 03:44:06216
[email protected]482a2d92011-02-10 00:34:28217 if (GetRootView()) {
218 GetRootView()->RemoveAllChildViews(true);
219 }
220
[email protected]632fbb12009-09-06 15:27:14221 NotificationService::current()->Notify(
222 NotificationType::EXTERNAL_TAB_CLOSED,
223 Source<NavigationController>(&tab_contents_->controller()),
224 Details<ExternalTabContainer>(this));
225
[email protected]7b8d4a22011-02-10 20:57:54226 tab_contents_.reset(NULL);
[email protected]632fbb12009-09-06 15:27:14227 }
[email protected]1a98a932009-11-17 00:12:52228
[email protected]93685472010-04-23 00:57:50229 if (focus_manager_) {
230 focus_manager_->UnregisterAccelerators(this);
[email protected]f1c74ec2010-05-21 22:20:37231 focus_manager_ = NULL;
[email protected]3f70c1e12010-01-12 20:38:49232 }
233
[email protected]ba67fd82010-07-09 18:30:31234 external_tab_view_ = NULL;
[email protected]13c30922009-11-19 03:43:19235 request_context_ = NULL;
[email protected]ab861b42010-02-05 19:13:44236 tab_contents_container_ = NULL;
[email protected]632fbb12009-09-06 15:27:14237}
238
239bool ExternalTabContainer::Reinitialize(
240 AutomationProvider* automation_provider,
[email protected]6e47f2f2010-07-12 17:30:58241 AutomationResourceMessageFilter* filter,
242 gfx::NativeWindow parent_window) {
[email protected]632fbb12009-09-06 15:27:14243 if (!automation_provider || !filter) {
244 NOTREACHED();
245 return false;
246 }
247
248 automation_ = automation_provider;
249 automation_resource_message_filter_ = filter;
[email protected]6c2e45b2010-05-07 00:55:25250 // Wait for the automation channel to be initialized before resuming pending
251 // render views and sending in the navigation state.
[email protected]24f98bba2009-10-14 18:47:49252 MessageLoop::current()->PostTask(
253 FROM_HERE,
254 external_method_factory_.NewRunnableMethod(
[email protected]18290eb2010-01-30 00:47:06255 &ExternalTabContainer::OnReinitialize));
[email protected]6e47f2f2010-07-12 17:30:58256
257 if (parent_window)
258 SetParent(GetNativeView(), parent_window);
[email protected]632fbb12009-09-06 15:27:14259 return true;
260}
261
[email protected]1a98a932009-11-17 00:12:52262void ExternalTabContainer::SetTabHandle(int handle) {
263 tab_handle_ = handle;
[email protected]1a98a932009-11-17 00:12:52264}
265
[email protected]9095e982009-05-27 17:28:24266void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) {
[email protected]3f70c1e12010-01-12 20:38:49267 NativeWebKeyboardEvent keyboard_event(msg.hwnd, msg.message, msg.wParam,
268 msg.lParam);
269 unhandled_keyboard_event_handler_.HandleKeyboardEvent(keyboard_event,
[email protected]93685472010-04-23 00:57:50270 focus_manager_);
[email protected]9095e982009-05-27 17:28:24271}
272
[email protected]1fd45692010-04-19 21:01:18273void ExternalTabContainer::FocusThroughTabTraversal(
274 bool reverse, bool restore_focus_to_view) {
[email protected]7b8d4a22011-02-10 20:57:54275 DCHECK(tab_contents_.get());
276 if (tab_contents_.get())
277 tab_contents_->tab_contents()->Focus();
[email protected]6331e0b2010-02-23 19:36:10278
279 // The tab_contents_ member can get destroyed in the context of the call to
[email protected]7e2cef52011-04-11 21:47:23280 // TabContentsViewViews::Focus() above. This method eventually calls SetFocus
[email protected]6331e0b2010-02-23 19:36:10281 // on the native window, which could end up dispatching messages like
282 // WM_DESTROY for the external tab.
[email protected]7b8d4a22011-02-10 20:57:54283 if (tab_contents_.get() && restore_focus_to_view)
284 tab_contents_->tab_contents()->FocusThroughTabTraversal(reverse);
initial.commit09911bf2008-07-26 23:55:29285}
286
[email protected]9095e982009-05-27 17:28:24287// static
288bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
[email protected]3b8a7f8e2010-11-21 22:44:21289 return ViewProp::GetValue(window, kWindowObjectKey) != NULL;
initial.commit09911bf2008-07-26 23:55:29290}
291
[email protected]9095e982009-05-27 17:28:24292// static
293ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
294 HWND tab_window) {
295 HWND parent_window = ::GetParent(tab_window);
296 if (!::IsWindow(parent_window)) {
297 return NULL;
initial.commit09911bf2008-07-26 23:55:29298 }
[email protected]9095e982009-05-27 17:28:24299 if (!IsExternalTabContainer(parent_window)) {
300 return NULL;
301 }
302 ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>(
[email protected]3b8a7f8e2010-11-21 22:44:21303 ViewProp::GetValue(parent_window, kWindowObjectKey));
[email protected]9095e982009-05-27 17:28:24304 return container;
initial.commit09911bf2008-07-26 23:55:29305}
306
[email protected]2b19e2fe2010-02-16 02:24:18307// static
308ExternalTabContainer*
309 ExternalTabContainer::GetExternalContainerFromNativeWindow(
310 gfx::NativeView native_window) {
311 ExternalTabContainer* tab_container = NULL;
312 if (native_window) {
[email protected]3b8a7f8e2010-11-21 22:44:21313 tab_container = reinterpret_cast<ExternalTabContainer*>(
314 ViewProp::GetValue(native_window, kWindowObjectKey));
[email protected]2b19e2fe2010-02-16 02:24:18315 }
316 return tab_container;
317}
[email protected]9095e982009-05-27 17:28:24318////////////////////////////////////////////////////////////////////////////////
319// ExternalTabContainer, TabContentsDelegate implementation:
[email protected]72baf6762009-05-06 18:45:33320
[email protected]e38f40152008-09-12 23:08:30321void ExternalTabContainer::OpenURLFromTab(TabContents* source,
[email protected]ec0b6c42010-08-26 03:16:58322 const GURL& url,
323 const GURL& referrer,
324 WindowOpenDisposition disposition,
325 PageTransition::Type transition) {
[email protected]18290eb2010-01-30 00:47:06326 if (pending()) {
327 PendingTopLevelNavigation url_request;
328 url_request.disposition = disposition;
329 url_request.transition = transition;
330 url_request.url = url;
331 url_request.referrer = referrer;
332
333 pending_open_url_requests_.push_back(url_request);
334 return;
335 }
336
initial.commit09911bf2008-07-26 23:55:29337 switch (disposition) {
338 case CURRENT_TAB:
[email protected]fba16f52009-04-02 22:30:35339 case SINGLETON_TAB:
initial.commit09911bf2008-07-26 23:55:29340 case NEW_FOREGROUND_TAB:
341 case NEW_BACKGROUND_TAB:
[email protected]5f450e52009-07-28 13:28:11342 case NEW_POPUP:
initial.commit09911bf2008-07-26 23:55:29343 case NEW_WINDOW:
[email protected]5f450e52009-07-28 13:28:11344 case SAVE_TO_DISK:
initial.commit09911bf2008-07-26 23:55:29345 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34346 automation_->Send(new AutomationMsg_OpenURL(tab_handle_,
[email protected]b36a9f92009-10-19 17:34:57347 url, referrer,
348 disposition));
[email protected]898f59212010-07-22 00:35:26349 // TODO(ananta)
350 // We should populate other fields in the
351 // ViewHostMsg_FrameNavigate_Params structure. Another option could be
352 // to refactor the UpdateHistoryForNavigation function in TabContents.
353 ViewHostMsg_FrameNavigate_Params params;
354 params.referrer = referrer;
355 params.url = url;
356 params.page_id = -1;
357 params.transition = PageTransition::LINK;
358
359 NavigationController::LoadCommittedDetails details;
360 details.did_replace_entry = false;
361
[email protected]ec0b6c42010-08-26 03:16:58362 scoped_refptr<history::HistoryAddPageArgs> add_page_args(
[email protected]7b8d4a22011-02-10 20:57:54363 tab_contents_->tab_contents()->
364 CreateHistoryAddPageArgs(url, details, params));
365 tab_contents_->tab_contents()->
366 UpdateHistoryForNavigation(add_page_args);
initial.commit09911bf2008-07-26 23:55:29367 }
368 break;
369 default:
[email protected]5f450e52009-07-28 13:28:11370 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29371 break;
[email protected]6dfed102009-04-28 03:09:53372 }
initial.commit09911bf2008-07-26 23:55:29373}
374
375void ExternalTabContainer::NavigationStateChanged(const TabContents* source,
[email protected]b9d227492009-02-10 15:20:27376 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:29377 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34378 NavigationInfo nav_info;
[email protected]6c908bb2009-08-21 19:03:50379 if (InitNavigationInfo(&nav_info, NavigationType::NAV_IGNORE, 0))
380 automation_->Send(new AutomationMsg_NavigationStateChanged(
[email protected]f5494d42010-12-23 22:15:34381 tab_handle_, changed_flags, nav_info));
initial.commit09911bf2008-07-26 23:55:29382 }
383}
384
initial.commit09911bf2008-07-26 23:55:29385void ExternalTabContainer::AddNewContents(TabContents* source,
386 TabContents* new_contents,
387 WindowOpenDisposition disposition,
388 const gfx::Rect& initial_pos,
389 bool user_gesture) {
[email protected]e478e212010-07-17 00:31:29390 if (!automation_) {
391 DCHECK(pending_);
392 LOG(ERROR) << "Invalid automation provider. Dropping new contents notify";
393 delete new_contents;
394 return;
395 }
[email protected]a50a4902009-08-14 22:39:01396
[email protected]9eeb35e2010-09-30 21:38:50397 scoped_refptr<ExternalTabContainer> new_container;
398 // If the host is a browser like IE8, then the URL being navigated to in the
399 // new tab contents could potentially navigate back to Chrome from a new
400 // IE process. We support full tab mode only for IE and hence we use that as
401 // a determining factor in whether the new ExternalTabContainer instance is
402 // created as pending or not.
403 if (!route_all_top_level_navigations_) {
404 new_container = new ExternalTabContainer(NULL, NULL);
405 } else {
406 // Reuse the same tab handle here as the new container instance is a dummy
407 // instance which does not have an automation client connected at the other
408 // end.
409 new_container = new TemporaryPopupExternalTabContainer(
410 automation_, automation_resource_message_filter_.get());
411 new_container->SetTabHandle(tab_handle_);
412 }
[email protected]a50a4902009-08-14 22:39:01413
[email protected]6f526082010-01-28 19:36:58414 // Make sure that ExternalTabContainer instance is initialized with
415 // an unwrapped Profile.
[email protected]7b8d4a22011-02-10 20:57:54416 scoped_ptr<TabContentsWrapper> wrapper(new TabContentsWrapper(new_contents));
[email protected]6f526082010-01-28 19:36:58417 bool result = new_container->Init(
418 new_contents->profile()->GetOriginalProfile(),
419 NULL,
420 initial_pos,
421 WS_CHILD,
422 load_requests_via_automation_,
423 handle_top_level_requests_,
[email protected]7b8d4a22011-02-10 20:57:54424 wrapper.get(),
[email protected]6f526082010-01-28 19:36:58425 GURL(),
[email protected]f7019302010-03-26 19:58:32426 GURL(),
[email protected]9eeb35e2010-09-30 21:38:50427 true,
428 route_all_top_level_navigations_);
[email protected]a50a4902009-08-14 22:39:01429
[email protected]6f526082010-01-28 19:36:58430 if (result) {
[email protected]7b8d4a22011-02-10 20:57:54431 wrapper.release(); // Ownership has been transferred.
[email protected]9eeb35e2010-09-30 21:38:50432 if (route_all_top_level_navigations_) {
433 return;
434 }
[email protected]b1c55638612010-03-08 16:26:11435 uintptr_t cookie = reinterpret_cast<uintptr_t>(new_container.get());
[email protected]d0ed50d2010-06-22 01:01:32436 pending_tabs_.Get()[cookie] = new_container;
[email protected]18290eb2010-01-30 00:47:06437 new_container->set_pending(true);
[email protected]326d3b72011-03-29 20:38:24438 new_container->set_is_popup_window(disposition == NEW_POPUP);
[email protected]f5494d42010-12-23 22:15:34439 AttachExternalTabParams attach_params_;
[email protected]b1c55638612010-03-08 16:26:11440 attach_params_.cookie = static_cast<uint64>(cookie);
441 attach_params_.dimensions = initial_pos;
442 attach_params_.user_gesture = user_gesture;
443 attach_params_.disposition = disposition;
[email protected]8103c7f2010-09-08 22:36:09444 attach_params_.profile_name = WideToUTF8(
445 tab_contents()->profile()->GetPath().DirName().BaseName().value());
[email protected]f5494d42010-12-23 22:15:34446 automation_->Send(new AutomationMsg_AttachExternalTab(
[email protected]b1c55638612010-03-08 16:26:11447 tab_handle_, attach_params_));
[email protected]6f526082010-01-28 19:36:58448 } else {
449 NOTREACHED();
[email protected]9f5b80a2009-04-08 01:26:07450 }
initial.commit09911bf2008-07-26 23:55:29451}
452
[email protected]5951b5c12010-02-22 18:15:34453void ExternalTabContainer::TabContentsCreated(TabContents* new_contents) {
454 RenderViewHost* rvh = new_contents->render_view_host();
455 DCHECK(rvh != NULL);
[email protected]fd571bb2010-03-19 01:23:54456
457 // Register this render view as a pending render view, i.e. any network
458 // requests initiated by this render view would be serviced when the
459 // external host connects to the new external tab instance.
460 RegisterRenderViewHostForAutomation(rvh, true);
[email protected]5951b5c12010-02-22 18:15:34461}
462
[email protected]f7019302010-03-26 19:58:32463bool ExternalTabContainer::infobars_enabled() {
464 return infobars_enabled_;
465}
466
initial.commit09911bf2008-07-26 23:55:29467void ExternalTabContainer::ActivateContents(TabContents* contents) {
468}
469
[email protected]ea42e7782010-08-23 23:58:12470void ExternalTabContainer::DeactivateContents(TabContents* contents) {
471}
472
initial.commit09911bf2008-07-26 23:55:29473void ExternalTabContainer::LoadingStateChanged(TabContents* source) {
474}
475
476void ExternalTabContainer::CloseContents(TabContents* source) {
[email protected]d9d8f0c2010-09-17 21:47:16477 if (!automation_)
478 return;
[email protected]e56e96f82010-02-03 21:38:08479
[email protected]d9d8f0c2010-09-17 21:47:16480 if (unload_reply_message_) {
481 AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_,
482 true);
483 automation_->Send(unload_reply_message_);
484 unload_reply_message_ = NULL;
[email protected]e16dd1672010-06-07 21:40:29485 } else {
[email protected]f5494d42010-12-23 22:15:34486 automation_->Send(new AutomationMsg_CloseExternalTab(tab_handle_));
[email protected]085d9cf2010-01-27 01:11:02487 }
initial.commit09911bf2008-07-26 23:55:29488}
489
[email protected]b9d227492009-02-10 15:20:27490void ExternalTabContainer::MoveContents(TabContents* source,
491 const gfx::Rect& pos) {
[email protected]326d3b72011-03-29 20:38:24492 if (automation_ && is_popup_window_)
493 automation_->Send(new AutomationMsg_MoveWindow(tab_handle_, pos));
494}
495
496bool ExternalTabContainer::IsPopup(const TabContents* source) const {
497 return is_popup_window_;
initial.commit09911bf2008-07-26 23:55:29498}
499
initial.commit09911bf2008-07-26 23:55:29500void ExternalTabContainer::UpdateTargetURL(TabContents* source,
501 const GURL& url) {
502 if (automation_) {
503 std::wstring url_string = CA2W(url.spec().c_str());
504 automation_->Send(
[email protected]f5494d42010-12-23 22:15:34505 new AutomationMsg_UpdateTargetUrl(tab_handle_, url_string));
initial.commit09911bf2008-07-26 23:55:29506 }
507}
508
509void ExternalTabContainer::ContentsZoomChange(bool zoom_in) {
510}
511
[email protected]18cb2572008-08-21 20:34:45512void ExternalTabContainer::ForwardMessageToExternalHost(
[email protected]28790922009-03-09 19:48:37513 const std::string& message, const std::string& origin,
514 const std::string& target) {
[email protected]4c540ee2009-07-07 17:15:55515 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34516 automation_->Send(new AutomationMsg_ForwardMessageToExternalHost(
517 tab_handle_, message, origin, target));
[email protected]5e40e262008-08-15 20:33:28518 }
519}
520
[email protected]dec76e802010-09-23 22:43:53521bool ExternalTabContainer::IsExternalTabContainer() const {
522 return true;
523}
524
[email protected]a95631cb2009-12-10 01:59:11525gfx::NativeWindow ExternalTabContainer::GetFrameNativeWindow() {
526 return hwnd();
527}
528
[email protected]1e0a02d62009-04-23 22:55:56529bool ExternalTabContainer::TakeFocus(bool reverse) {
530 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34531 automation_->Send(new AutomationMsg_TabbedOut(tab_handle_,
[email protected]a8e20582010-12-31 17:18:50532 base::win::IsShiftPressed()));
[email protected]1e0a02d62009-04-23 22:55:56533 }
534
535 return true;
536}
537
[email protected]fc6fb7fb2009-11-07 02:35:04538bool ExternalTabContainer::CanDownload(int request_id) {
539 if (load_requests_via_automation_) {
540 if (automation_) {
[email protected]62bb18dc12009-11-25 01:34:08541 // In case the host needs to show UI that needs to take the focus.
542 ::AllowSetForegroundWindow(ASFW_ANY);
543
[email protected]d04e7662010-10-10 22:24:48544 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
[email protected]37b76dc2009-12-02 00:48:55545 NewRunnableMethod(automation_resource_message_filter_.get(),
[email protected]dda7d9c2009-11-11 23:01:47546 &AutomationResourceMessageFilter::SendDownloadRequestToHost,
547 0, tab_handle_, request_id));
[email protected]fc6fb7fb2009-11-07 02:35:04548 }
549 } else {
550 DLOG(WARNING) << "Downloads are only supported with host browser network "
551 "stack enabled.";
552 }
553
554 // Never allow downloads.
555 return false;
556}
557
[email protected]21e302e2009-09-12 23:10:41558void ExternalTabContainer::ShowPageInfo(Profile* profile,
559 const GURL& url,
560 const NavigationEntry::SSLStatus& ssl,
561 bool show_history) {
[email protected]0b7a012d2010-10-19 23:49:26562 POINT cursor_pos = {0};
563 GetCursorPos(&cursor_pos);
564
565 gfx::Rect bounds;
566 bounds.set_origin(gfx::Point(cursor_pos));
567
568 PageInfoBubbleView* page_info_bubble =
569 new ExternalTabPageInfoBubbleView(this, NULL, profile, url,
570 ssl, show_history);
[email protected]cb7f12f2011-04-14 15:10:23571 Bubble* bubble = Bubble::Show(this, bounds, BubbleBorder::TOP_LEFT,
572 page_info_bubble, page_info_bubble);
573 page_info_bubble->set_bubble(bubble);
[email protected]21e302e2009-09-12 23:10:41574}
575
[email protected]fd571bb2010-03-19 01:23:54576void ExternalTabContainer::RegisterRenderViewHostForAutomation(
577 RenderViewHost* render_view_host, bool pending_view) {
578 if (render_view_host) {
579 AutomationResourceMessageFilter::RegisterRenderView(
580 render_view_host->process()->id(),
581 render_view_host->routing_id(),
582 tab_handle(),
583 automation_resource_message_filter_,
584 pending_view);
585 }
586}
587
[email protected]fd571bb2010-03-19 01:23:54588void ExternalTabContainer::RegisterRenderViewHost(
589 RenderViewHost* render_view_host) {
590 // RenderViewHost instances that are to be associated with this
591 // ExternalTabContainer should share the same resource request automation
592 // settings.
593 RegisterRenderViewHostForAutomation(
594 render_view_host,
595 false); // Network requests should not be handled later.
596}
597
598void ExternalTabContainer::UnregisterRenderViewHost(
599 RenderViewHost* render_view_host) {
600 // Undo the resource automation registration performed in
601 // ExternalTabContainer::RegisterRenderViewHost.
602 if (render_view_host) {
603 AutomationResourceMessageFilter::UnRegisterRenderView(
604 render_view_host->process()->id(),
605 render_view_host->routing_id());
606 }
607}
608
[email protected]e943d6662009-06-12 03:50:39609bool ExternalTabContainer::HandleContextMenu(const ContextMenuParams& params) {
610 if (!automation_) {
611 NOTREACHED();
612 return false;
613 }
[email protected]e943d6662009-06-12 03:50:39614 external_context_menu_.reset(
[email protected]14831ef2010-05-11 23:51:20615 new RenderViewContextMenuViews(tab_contents(), params));
616 external_context_menu_->SetExternal();
[email protected]e943d6662009-06-12 03:50:39617 external_context_menu_->Init();
[email protected]a5e04ea2010-06-08 13:37:08618 external_context_menu_->UpdateMenuItemStates();
[email protected]e943d6662009-06-12 03:50:39619
620 POINT screen_pt = { params.x, params.y };
621 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1);
622
[email protected]f5494d42010-12-23 22:15:34623 MiniContextMenuParams ipc_params(
[email protected]0f1afed2010-12-15 17:22:28624 screen_pt.x,
625 screen_pt.y,
626 params.link_url,
627 params.unfiltered_link_url,
628 params.src_url,
629 params.page_url,
630 params.frame_url);
[email protected]35f13ab2009-12-16 23:59:17631
[email protected]7cf1b6ce2010-03-20 06:37:01632 bool rtl = base::i18n::IsRTL();
[email protected]e943d6662009-06-12 03:50:39633 automation_->Send(
[email protected]f5494d42010-12-23 22:15:34634 new AutomationMsg_ForwardContextMenuToExternalHost(tab_handle_,
[email protected]35f13ab2009-12-16 23:59:17635 external_context_menu_->GetMenuHandle(),
636 rtl ? TPM_RIGHTALIGN : TPM_LEFTALIGN, ipc_params));
[email protected]e943d6662009-06-12 03:50:39637
638 return true;
639}
640
641bool ExternalTabContainer::ExecuteContextMenuCommand(int command) {
642 if (!external_context_menu_.get()) {
643 NOTREACHED();
644 return false;
645 }
646
[email protected]35f13ab2009-12-16 23:59:17647 switch (command) {
648 case IDS_CONTENT_CONTEXT_SAVEAUDIOAS:
649 case IDS_CONTENT_CONTEXT_SAVEVIDEOAS:
650 case IDS_CONTENT_CONTEXT_SAVEIMAGEAS:
651 case IDS_CONTENT_CONTEXT_SAVELINKAS: {
652 NOTREACHED(); // Should be handled in host.
653 break;
654 }
655 }
656
[email protected]e943d6662009-06-12 03:50:39657 external_context_menu_->ExecuteCommand(command);
658 return true;
659}
660
[email protected]867125a02009-12-10 06:01:48661bool ExternalTabContainer::PreHandleKeyboardEvent(
662 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
663 return false;
664}
665
666void ExternalTabContainer::HandleKeyboardEvent(
[email protected]334a105b2009-07-14 03:42:55667 const NativeWebKeyboardEvent& event) {
[email protected]867125a02009-12-10 06:01:48668 ProcessUnhandledKeyStroke(event.os_event.hwnd, event.os_event.message,
669 event.os_event.wParam, event.os_event.lParam);
[email protected]334a105b2009-07-14 03:42:55670}
671
[email protected]36cf19b92009-07-22 18:07:51672void ExternalTabContainer::ShowHtmlDialog(HtmlDialogUIDelegate* delegate,
673 gfx::NativeWindow parent_window) {
674 if (!browser_.get()) {
[email protected]1b74d2122010-10-06 16:49:16675 browser_.reset(Browser::CreateForType(Browser::TYPE_POPUP,
676 tab_contents_->profile()));
[email protected]36cf19b92009-07-22 18:07:51677 }
678
[email protected]2d48ee842011-03-08 23:27:29679 gfx::NativeWindow parent = parent_window ? parent_window : GetParent();
[email protected]36cf19b92009-07-22 18:07:51680 browser_->window()->ShowHTMLDialog(delegate, parent);
681}
682
[email protected]d9d8f0c2010-09-17 21:47:16683void ExternalTabContainer::BeforeUnloadFired(TabContents* tab,
684 bool proceed,
685 bool* proceed_to_fire_unload) {
[email protected]d9d8f0c2010-09-17 21:47:16686 *proceed_to_fire_unload = true;
687
688 if (!automation_) {
689 delete unload_reply_message_;
690 unload_reply_message_ = NULL;
691 return;
692 }
693
[email protected]b5e0a192011-03-22 19:15:32694 if (!unload_reply_message_) {
695 NOTREACHED() << "**** NULL unload reply message pointer.";
696 return;
697 }
698
[email protected]d9d8f0c2010-09-17 21:47:16699 if (!proceed) {
700 AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_,
701 false);
702 automation_->Send(unload_reply_message_);
703 unload_reply_message_ = NULL;
704 *proceed_to_fire_unload = false;
705 }
706}
707
[email protected]2fc22d12010-12-02 23:08:16708void ExternalTabContainer::ShowRepostFormWarningDialog(
709 TabContents* tab_contents) {
710 browser::ShowRepostFormWarningDialog(GetNativeView(), tab_contents);
711}
712
[email protected]9095e982009-05-27 17:28:24713////////////////////////////////////////////////////////////////////////////////
714// ExternalTabContainer, NotificationObserver implementation:
715
initial.commit09911bf2008-07-26 23:55:29716void ExternalTabContainer::Observe(NotificationType type,
717 const NotificationSource& source,
718 const NotificationDetails& details) {
[email protected]33ee8da2009-04-16 17:45:37719 if (!automation_)
720 return;
721
[email protected]2e39d2e2009-02-19 18:41:31722 static const int kHttpClientErrorStart = 400;
723 static const int kHttpServerErrorEnd = 510;
724
[email protected]bfd04a62009-02-01 18:16:56725 switch (type.value) {
[email protected]33ee8da2009-04-16 17:45:37726 case NotificationType::LOAD_STOP: {
727 const LoadNotificationDetails* load =
728 Details<LoadNotificationDetails>(details).ptr();
[email protected]d86153f2009-05-18 21:10:52729 if (load != NULL && PageTransition::IsMainFrame(load->origin())) {
[email protected]a872ea1f2010-08-11 04:45:33730 TRACE_EVENT_END("ExternalTabContainer::Navigate", 0,
731 load->url().spec());
[email protected]f5494d42010-12-23 22:15:34732 automation_->Send(new AutomationMsg_TabLoaded(tab_handle_,
[email protected]eac83f02009-05-08 18:44:44733 load->url()));
[email protected]33ee8da2009-04-16 17:45:37734 }
735 break;
[email protected]2e39d2e2009-02-19 18:41:31736 }
[email protected]33ee8da2009-04-16 17:45:37737 case NotificationType::NAV_ENTRY_COMMITTED: {
738 if (ignore_next_load_notification_) {
739 ignore_next_load_notification_ = false;
740 return;
741 }
[email protected]2e39d2e2009-02-19 18:41:31742
[email protected]0e8db942008-09-24 21:21:48743 const NavigationController::LoadCommittedDetails* commit =
744 Details<NavigationController::LoadCommittedDetails>(details).ptr();
745
[email protected]f0a51fb52009-03-05 12:46:38746 if (commit->http_status_code >= kHttpClientErrorStart &&
[email protected]2e39d2e2009-02-19 18:41:31747 commit->http_status_code <= kHttpServerErrorEnd) {
748 automation_->Send(new AutomationMsg_NavigationFailed(
[email protected]f5494d42010-12-23 22:15:34749 tab_handle_, commit->http_status_code, commit->entry->url()));
[email protected]2e39d2e2009-02-19 18:41:31750
751 ignore_next_load_notification_ = true;
752 } else {
[email protected]f5494d42010-12-23 22:15:34753 NavigationInfo navigation_info;
[email protected]2e39d2e2009-02-19 18:41:31754 // When the previous entry index is invalid, it will be -1, which
755 // will still make the computation come out right (navigating to the
756 // 0th entry will be +1).
[email protected]6c908bb2009-08-21 19:03:50757 if (InitNavigationInfo(&navigation_info, commit->type,
758 commit->previous_entry_index -
759 tab_contents_->controller().last_committed_entry_index()))
[email protected]f5494d42010-12-23 22:15:34760 automation_->Send(new AutomationMsg_DidNavigate(tab_handle_,
[email protected]6c908bb2009-08-21 19:03:50761 navigation_info));
[email protected]2e39d2e2009-02-19 18:41:31762 }
[email protected]33ee8da2009-04-16 17:45:37763 break;
[email protected]0e8db942008-09-24 21:21:48764 }
[email protected]2e39d2e2009-02-19 18:41:31765 case NotificationType::FAIL_PROVISIONAL_LOAD_WITH_ERROR: {
[email protected]33ee8da2009-04-16 17:45:37766 const ProvisionalLoadDetails* load_details =
767 Details<ProvisionalLoadDetails>(details).ptr();
768 automation_->Send(new AutomationMsg_NavigationFailed(
[email protected]f5494d42010-12-23 22:15:34769 tab_handle_, load_details->error_code(), load_details->url()));
[email protected]2e39d2e2009-02-19 18:41:31770
[email protected]33ee8da2009-04-16 17:45:37771 ignore_next_load_notification_ = true;
[email protected]2e39d2e2009-02-19 18:41:31772 break;
773 }
[email protected]2e4633c2009-07-09 16:58:06774 case NotificationType::RENDER_VIEW_HOST_CREATED_FOR_TAB: {
775 if (load_requests_via_automation_) {
776 RenderViewHost* rvh = Details<RenderViewHost>(details).ptr();
[email protected]fd571bb2010-03-19 01:23:54777 RegisterRenderViewHostForAutomation(rvh, false);
[email protected]2e4633c2009-07-09 16:58:06778 }
779 break;
780 }
781 case NotificationType::RENDER_VIEW_HOST_DELETED: {
782 if (load_requests_via_automation_) {
[email protected]6b5b0cd2011-03-31 21:11:41783 RenderViewHost* rvh = Source<RenderViewHost>(source).ptr();
[email protected]fd571bb2010-03-19 01:23:54784 UnregisterRenderViewHost(rvh);
[email protected]2e4633c2009-07-09 16:58:06785 }
786 break;
787 }
[email protected]0e8db942008-09-24 21:21:48788 default:
789 NOTREACHED();
790 }
initial.commit09911bf2008-07-26 23:55:29791}
792
[email protected]9095e982009-05-27 17:28:24793////////////////////////////////////////////////////////////////////////////////
[email protected]f258bbe02011-02-14 20:38:10794// ExternalTabContainer, views::WidgetWin overrides:
[email protected]9095e982009-05-27 17:28:24795
[email protected]632fbb12009-09-06 15:27:14796LRESULT ExternalTabContainer::OnCreate(LPCREATESTRUCT create_struct) {
[email protected]f258bbe02011-02-14 20:38:10797 LRESULT result = views::WidgetWin::OnCreate(create_struct);
[email protected]632fbb12009-09-06 15:27:14798 if (result == 0) {
799 // Grab a reference here which will be released in OnFinalMessage
800 AddRef();
801 }
802 return result;
803}
804
[email protected]9095e982009-05-27 17:28:24805void ExternalTabContainer::OnDestroy() {
[email protected]7c9d8292010-11-01 16:57:13806 prop_.reset();
[email protected]632fbb12009-09-06 15:27:14807 Uninitialize();
[email protected]f258bbe02011-02-14 20:38:10808 WidgetWin::OnDestroy();
[email protected]36cf19b92009-07-22 18:07:51809 if (browser_.get()) {
810 ::DestroyWindow(browser_->window()->GetNativeHandle());
811 }
initial.commit09911bf2008-07-26 23:55:29812}
813
[email protected]632fbb12009-09-06 15:27:14814void ExternalTabContainer::OnFinalMessage(HWND window) {
815 // Release the reference which we grabbed in WM_CREATE.
816 Release();
[email protected]334a105b2009-07-14 03:42:55817}
818
[email protected]d9d8f0c2010-09-17 21:47:16819void ExternalTabContainer::RunUnloadHandlers(IPC::Message* reply_message) {
820 if (!automation_) {
821 delete reply_message;
822 return;
[email protected]1f71d5882010-07-15 20:39:07823 }
[email protected]d9d8f0c2010-09-17 21:47:16824
825 // If we have a pending unload message, then just respond back to this
826 // request and continue processing the previous unload message.
827 if (unload_reply_message_) {
828 AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true);
829 automation_->Send(reply_message);
830 return;
831 }
[email protected]b5e0a192011-03-22 19:15:32832
833 unload_reply_message_ = reply_message;
834 bool wait_for_unload_handlers =
835 tab_contents_.get() &&
836 Browser::RunUnloadEventsHelper(tab_contents_->tab_contents());
837 if (!wait_for_unload_handlers) {
[email protected]d9d8f0c2010-09-17 21:47:16838 AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true);
839 automation_->Send(reply_message);
[email protected]b5e0a192011-03-22 19:15:32840 unload_reply_message_ = NULL;
[email protected]1f71d5882010-07-15 20:39:07841 }
842}
843
[email protected]632fbb12009-09-06 15:27:14844////////////////////////////////////////////////////////////////////////////////
845// ExternalTabContainer, private:
[email protected]334a105b2009-07-14 03:42:55846bool ExternalTabContainer::ProcessUnhandledKeyStroke(HWND window,
847 UINT message,
848 WPARAM wparam,
849 LPARAM lparam) {
initial.commit09911bf2008-07-26 23:55:29850 if (!automation_) {
851 return false;
852 }
[email protected]a8e20582010-12-31 17:18:50853 if ((wparam == VK_TAB) && !base::win::IsCtrlPressed()) {
initial.commit09911bf2008-07-26 23:55:29854 // Tabs are handled separately (except if this is Ctrl-Tab or
855 // Ctrl-Shift-Tab)
856 return false;
857 }
[email protected]060254c2009-05-02 16:45:27858
[email protected]01dba672010-02-12 21:55:48859 // Send this keystroke to the external host as it could be processed as an
860 // accelerator there. If the host does not handle this accelerator, it will
861 // reflect the accelerator back to us via the ProcessUnhandledAccelerator
862 // method.
863 MSG msg = {0};
864 msg.hwnd = window;
865 msg.message = message;
866 msg.wParam = wparam;
867 msg.lParam = lparam;
[email protected]f5494d42010-12-23 22:15:34868 automation_->Send(new AutomationMsg_HandleAccelerator(tab_handle_, msg));
[email protected]01dba672010-02-12 21:55:48869 return true;
initial.commit09911bf2008-07-26 23:55:29870}
[email protected]4150ef02009-08-19 23:14:26871
[email protected]f5494d42010-12-23 22:15:34872bool ExternalTabContainer::InitNavigationInfo(NavigationInfo* nav_info,
[email protected]4150ef02009-08-19 23:14:26873 NavigationType::Type nav_type,
874 int relative_offset) {
[email protected]4150ef02009-08-19 23:14:26875 DCHECK(nav_info);
[email protected]6c908bb2009-08-21 19:03:50876 NavigationEntry* entry = tab_contents_->controller().GetActiveEntry();
877 // If this is very early in the game then we may not have an entry.
878 if (!entry)
879 return false;
[email protected]4150ef02009-08-19 23:14:26880
881 nav_info->navigation_type = nav_type;
882 nav_info->relative_offset = relative_offset;
883 nav_info->navigation_index =
884 tab_contents_->controller().GetCurrentEntryIndex();
[email protected]4150ef02009-08-19 23:14:26885 nav_info->url = entry->url();
[email protected]a1955adf2010-08-02 17:59:39886 nav_info->referrer = entry->referrer();
[email protected]40ead7b62011-04-23 03:17:28887 // TODO(evan): use directionality of title.
888 // http://code.google.com/p/chromium/issues/detail?id=27094
889 nav_info->title = UTF16ToWideHack(entry->title().string());
[email protected]24f98bba2009-10-14 18:47:49890 if (nav_info->title.empty())
891 nav_info->title = UTF8ToWide(nav_info->url.spec());
892
[email protected]f5cde2b2009-09-11 22:33:58893 nav_info->security_style = entry->ssl().security_style();
[email protected]b4e75c12010-05-18 18:28:48894 nav_info->displayed_insecure_content =
895 entry->ssl().displayed_insecure_content();
896 nav_info->ran_insecure_content = entry->ssl().ran_insecure_content();
[email protected]6c908bb2009-08-21 19:03:50897 return true;
[email protected]4150ef02009-08-19 23:14:26898}
899
[email protected]cd0dec62010-02-11 02:33:18900scoped_refptr<ExternalTabContainer> ExternalTabContainer::RemovePendingTab(
[email protected]b1c55638612010-03-08 16:26:11901 uintptr_t cookie) {
[email protected]d0ed50d2010-06-22 01:01:32902 ExternalTabContainer::PendingTabs& pending_tabs = pending_tabs_.Get();
903 PendingTabs::iterator index = pending_tabs.find(cookie);
904 if (index != pending_tabs.end()) {
[email protected]632fbb12009-09-06 15:27:14905 scoped_refptr<ExternalTabContainer> container = (*index).second;
[email protected]d0ed50d2010-06-22 01:01:32906 pending_tabs.erase(index);
[email protected]cd0dec62010-02-11 02:33:18907 return container;
[email protected]632fbb12009-09-06 15:27:14908 }
909
910 NOTREACHED() << "Failed to find ExternalTabContainer for cookie: "
911 << cookie;
912 return NULL;
913}
914
[email protected]9ac174e92011-04-16 00:58:56915SkColor ExternalTabContainer::GetInfoBarSeparatorColor() const {
916 return ResourceBundle::toolbar_separator_color;
917}
918
[email protected]1c89c2902011-04-02 22:47:36919void ExternalTabContainer::InfoBarContainerHeightChanged(bool is_animating) {
[email protected]f4f50ef2011-01-21 19:01:19920 if (external_tab_view_)
[email protected]ba67fd82010-07-09 18:30:31921 external_tab_view_->Layout();
[email protected]ab861b42010-02-05 19:13:44922}
923
[email protected]ee120872011-04-15 01:37:06924bool ExternalTabContainer::DrawInfoBarArrows(int* x) const {
925 return false;
926}
927
[email protected]a95631cb2009-12-10 01:59:11928// ExternalTabContainer instances do not have a window.
929views::Window* ExternalTabContainer::GetWindow() {
930 return NULL;
931}
932
[email protected]3f70c1e12010-01-12 20:38:49933bool ExternalTabContainer::AcceleratorPressed(
934 const views::Accelerator& accelerator) {
935 std::map<views::Accelerator, int>::const_iterator iter =
936 accelerator_table_.find(accelerator);
937 DCHECK(iter != accelerator_table_.end());
938
[email protected]7b8d4a22011-02-10 20:57:54939 if (!tab_contents_.get() || !tab_contents_->render_view_host()) {
[email protected]3f70c1e12010-01-12 20:38:49940 NOTREACHED();
941 return false;
942 }
943
944 int command_id = iter->second;
945 switch (command_id) {
946 case IDC_ZOOM_PLUS:
947 tab_contents_->render_view_host()->Zoom(PageZoom::ZOOM_IN);
948 break;
949 case IDC_ZOOM_NORMAL:
950 tab_contents_->render_view_host()->Zoom(PageZoom::RESET);
951 break;
952 case IDC_ZOOM_MINUS:
953 tab_contents_->render_view_host()->Zoom(PageZoom::ZOOM_OUT);
954 break;
955 case IDC_DEV_TOOLS:
956 DevToolsManager::GetInstance()->ToggleDevToolsWindow(
[email protected]2a8a98122010-07-16 11:58:48957 tab_contents_->render_view_host(), DEVTOOLS_TOGGLE_ACTION_NONE);
[email protected]3f70c1e12010-01-12 20:38:49958 break;
959 case IDC_DEV_TOOLS_CONSOLE:
960 DevToolsManager::GetInstance()->ToggleDevToolsWindow(
[email protected]2a8a98122010-07-16 11:58:48961 tab_contents_->render_view_host(),
962 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
963 break;
964 case IDC_DEV_TOOLS_INSPECT:
965 DevToolsManager::GetInstance()->ToggleDevToolsWindow(
966 tab_contents_->render_view_host(),
967 DEVTOOLS_TOGGLE_ACTION_INSPECT);
[email protected]3f70c1e12010-01-12 20:38:49968 break;
969 default:
970 NOTREACHED() << "Unsupported accelerator: " << command_id;
971 return false;
972 }
973 return true;
974}
975
[email protected]f5cde2b2009-09-11 22:33:58976void ExternalTabContainer::Navigate(const GURL& url, const GURL& referrer) {
[email protected]7b8d4a22011-02-10 20:57:54977 if (!tab_contents_.get()) {
[email protected]f5cde2b2009-09-11 22:33:58978 NOTREACHED();
979 return;
980 }
981
[email protected]a872ea1f2010-08-11 04:45:33982 TRACE_EVENT_BEGIN("ExternalTabContainer::Navigate", 0, url.spec());
983
[email protected]f5cde2b2009-09-11 22:33:58984 tab_contents_->controller().LoadURL(url, referrer,
985 PageTransition::START_PAGE);
986}
[email protected]f9cc4c452009-10-13 14:56:38987
988bool ExternalTabContainer::OnGoToEntryOffset(int offset) {
989 if (load_requests_via_automation_) {
990 automation_->Send(new AutomationMsg_RequestGoToHistoryEntryOffset(
[email protected]f5494d42010-12-23 22:15:34991 tab_handle_, offset));
[email protected]f9cc4c452009-10-13 14:56:38992 return false;
993 }
994
995 return true;
996}
[email protected]1a98a932009-11-17 00:12:52997
[email protected]3f70c1e12010-01-12 20:38:49998void ExternalTabContainer::LoadAccelerators() {
999 HACCEL accelerator_table = AtlLoadAccelerators(IDR_CHROMEFRAME);
1000 DCHECK(accelerator_table);
1001
1002 // We have to copy the table to access its contents.
1003 int count = CopyAcceleratorTable(accelerator_table, 0, 0);
1004 if (count == 0) {
1005 // Nothing to do in that case.
1006 return;
1007 }
1008
1009 scoped_ptr<ACCEL> scoped_accelerators(new ACCEL[count]);
1010 ACCEL* accelerators = scoped_accelerators.get();
1011 DCHECK(accelerators != NULL);
1012
1013 CopyAcceleratorTable(accelerator_table, accelerators, count);
1014
[email protected]93685472010-04-23 00:57:501015 focus_manager_ = GetFocusManager();
1016 DCHECK(focus_manager_);
[email protected]3f70c1e12010-01-12 20:38:491017
1018 // Let's fill our own accelerator table.
1019 for (int i = 0; i < count; ++i) {
1020 bool alt_down = (accelerators[i].fVirt & FALT) == FALT;
1021 bool ctrl_down = (accelerators[i].fVirt & FCONTROL) == FCONTROL;
1022 bool shift_down = (accelerators[i].fVirt & FSHIFT) == FSHIFT;
1023 views::Accelerator accelerator(
[email protected]b6d81262011-01-13 17:36:091024 static_cast<ui::KeyboardCode>(accelerators[i].key),
[email protected]3f70c1e12010-01-12 20:38:491025 shift_down, ctrl_down, alt_down);
1026 accelerator_table_[accelerator] = accelerators[i].cmd;
1027
1028 // Also register with the focus manager.
[email protected]93685472010-04-23 00:57:501029 if (focus_manager_)
1030 focus_manager_->RegisterAccelerator(accelerator, this);
[email protected]3f70c1e12010-01-12 20:38:491031 }
1032}
[email protected]18290eb2010-01-30 00:47:061033
1034void ExternalTabContainer::OnReinitialize() {
[email protected]6c2e45b2010-05-07 00:55:251035 if (load_requests_via_automation_) {
[email protected]6c2e45b2010-05-07 00:55:251036 RenderViewHost* rvh = tab_contents_->render_view_host();
1037 if (rvh) {
1038 AutomationResourceMessageFilter::ResumePendingRenderView(
1039 rvh->process()->id(), rvh->routing_id(),
1040 tab_handle_, automation_resource_message_filter_);
1041 }
1042 }
1043
[email protected]7b8d4a22011-02-10 20:57:541044 NavigationStateChanged(tab_contents(), 0);
[email protected]18290eb2010-01-30 00:47:061045 ServicePendingOpenURLRequests();
1046}
1047
1048void ExternalTabContainer::ServicePendingOpenURLRequests() {
1049 DCHECK(pending());
1050
1051 set_pending(false);
1052
1053 for (size_t index = 0; index < pending_open_url_requests_.size();
[email protected]7b8d4a22011-02-10 20:57:541054 ++index) {
[email protected]18290eb2010-01-30 00:47:061055 const PendingTopLevelNavigation& url_request =
1056 pending_open_url_requests_[index];
[email protected]7b8d4a22011-02-10 20:57:541057 OpenURLFromTab(tab_contents(), url_request.url, url_request.referrer,
[email protected]18290eb2010-01-30 00:47:061058 url_request.disposition, url_request.transition);
1059 }
1060 pending_open_url_requests_.clear();
1061}
1062
[email protected]ab861b42010-02-05 19:13:441063void ExternalTabContainer::SetupExternalTabView() {
1064 // Create a TabContentsContainer to handle focus cycling using Tab and
1065 // Shift-Tab.
1066 tab_contents_container_ = new TabContentsContainer;
1067
1068 // The views created here will be destroyed when the ExternalTabContainer
1069 // widget is torn down.
[email protected]ba67fd82010-07-09 18:30:311070 external_tab_view_ = new views::View();
[email protected]ab861b42010-02-05 19:13:441071
[email protected]6c6614f12011-03-31 18:51:421072 InfoBarContainerView* info_bar_container = new InfoBarContainerView(this);
[email protected]7b8d4a22011-02-10 20:57:541073 info_bar_container->ChangeTabContents(tab_contents());
[email protected]ab861b42010-02-05 19:13:441074
[email protected]ba67fd82010-07-09 18:30:311075 views::GridLayout* layout = new views::GridLayout(external_tab_view_);
1076 // Give this column an identifier of 0.
1077 views::ColumnSet* columns = layout->AddColumnSet(0);
[email protected]ab861b42010-02-05 19:13:441078 columns->AddColumn(views::GridLayout::FILL,
1079 views::GridLayout::FILL,
1080 1,
1081 views::GridLayout::USE_PREF,
1082 0,
1083 0);
1084
[email protected]ba67fd82010-07-09 18:30:311085 external_tab_view_->SetLayoutManager(layout);
[email protected]ab861b42010-02-05 19:13:441086
1087 layout->StartRow(0, 0);
1088 layout->AddView(info_bar_container);
1089 layout->StartRow(1, 0);
1090 layout->AddView(tab_contents_container_);
[email protected]ba67fd82010-07-09 18:30:311091 SetContentsView(external_tab_view_);
[email protected]ab861b42010-02-05 19:13:441092 // Note that SetTabContents must be called after AddChildView is called
[email protected]7b8d4a22011-02-10 20:57:541093 tab_contents_container_->ChangeTabContents(tab_contents());
[email protected]ab861b42010-02-05 19:13:441094}
[email protected]9eeb35e2010-09-30 21:38:501095
1096TemporaryPopupExternalTabContainer::TemporaryPopupExternalTabContainer(
1097 AutomationProvider* automation,
1098 AutomationResourceMessageFilter* filter)
1099 : ExternalTabContainer(automation, filter) {
1100}
1101
1102TemporaryPopupExternalTabContainer::~TemporaryPopupExternalTabContainer() {
[email protected]8e96e502010-10-21 20:57:121103 DVLOG(1) << __FUNCTION__;
[email protected]9eeb35e2010-09-30 21:38:501104}
1105
1106void TemporaryPopupExternalTabContainer::OpenURLFromTab(
1107 TabContents* source, const GURL& url, const GURL& referrer,
1108 WindowOpenDisposition disposition, PageTransition::Type transition) {
1109 if (!automation_)
1110 return;
1111
1112 if (disposition == CURRENT_TAB) {
1113 DCHECK(route_all_top_level_navigations_);
1114 disposition = NEW_FOREGROUND_TAB;
1115 }
1116 ExternalTabContainer::OpenURLFromTab(source, url, referrer, disposition,
1117 transition);
1118 // support only one navigation for a dummy tab before it is killed.
1119 ::DestroyWindow(GetNativeView());
1120}