blob: f88e96ec017e6543e64baed61922f2a4a5e5d3e4 [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]1f1e7cb2011-10-07 22:55:4712#include "base/memory/scoped_ptr.h"
[email protected]944b4212010-12-14 00:00:3313#include "base/utf_string_conversions.h"
[email protected]a8e20582010-12-31 17:18:5014#include "base/win/win_util.h"
[email protected]1a3aba82010-11-08 23:52:5415#include "chrome/app/chrome_command_ids.h"
[email protected]0f8df8672010-11-09 00:36:3216#include "chrome/app/chrome_dll_resource.h"
[email protected]b3841c502011-03-09 01:21:3117#include "chrome/browser/automation/automation_provider.h"
[email protected]dce502762011-07-20 08:53:4918#include "chrome/browser/debugger/devtools_toggle_action.h"
19#include "chrome/browser/debugger/devtools_window.h"
[email protected]105bb0f2011-05-24 17:12:1420#include "chrome/browser/history/history_tab_helper.h"
[email protected]477ae052011-11-18 23:53:5721#include "chrome/browser/history/history_types.h"
[email protected]7e204122011-09-01 18:56:2122#include "chrome/browser/infobars/infobar_tab_helper.h"
[email protected]8ecad5e2010-12-02 21:18:3323#include "chrome/browser/profiles/profile.h"
[email protected]3ab9cb82011-06-03 18:02:0724#include "chrome/browser/ui/app_modal_dialogs/message_box_handler.h"
[email protected]7fbd1e92011-06-02 19:33:0025#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h"
[email protected]a8c229cc2011-01-13 22:31:5826#include "chrome/browser/ui/browser.h"
[email protected]00070c732011-04-09 15:31:3327#include "chrome/browser/ui/browser_window.h"
[email protected]7b8d4a22011-02-10 20:57:5428#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
[email protected]9e790bd2011-01-10 23:48:5429#include "chrome/browser/ui/views/browser_dialogs.h"
[email protected]6c6614f12011-03-31 18:51:4230#include "chrome/browser/ui/views/infobars/infobar_container_view.h"
[email protected]9e790bd2011-01-10 23:48:5431#include "chrome/browser/ui/views/tab_contents/render_view_context_menu_views.h"
32#include "chrome/browser/ui/views/tab_contents/tab_contents_container.h"
[email protected]a8ba6362010-11-10 20:02:2533#include "chrome/common/automation_messages.h"
initial.commit09911bf2008-07-26 23:55:2934#include "chrome/common/chrome_constants.h"
[email protected]432115822011-07-10 15:52:2735#include "chrome/common/chrome_notification_types.h"
[email protected]15b2c6a2011-05-16 23:54:4036#include "chrome/common/render_messages.h"
[email protected]91a79232010-11-10 18:15:0837#include "chrome/common/url_constants.h"
[email protected]35e251d2011-05-24 21:01:0438#include "content/browser/load_notification_details.h"
[email protected]5de634712011-03-02 00:20:1939#include "content/browser/renderer_host/render_view_host.h"
40#include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
[email protected]8286f51a2011-05-31 17:39:1341#include "content/browser/tab_contents/navigation_details.h"
[email protected]299425b2011-03-02 07:45:2042#include "content/browser/tab_contents/provisional_load_details.h"
[email protected]8bc38d22011-10-14 20:39:2043#include "content/public/browser/native_web_keyboard_event.h"
[email protected]477ae052011-11-18 23:53:5744#include "content/public/browser/notification_service.h"
[email protected]e091df82011-10-11 18:13:2145#include "content/public/common/bindings_policy.h"
[email protected]6766b172011-11-21 18:29:3646#include "content/public/common/frame_navigate_params.h"
[email protected]2905f742011-10-13 03:51:5847#include "content/public/common/page_transition_types.h"
[email protected]54087fe2011-10-28 22:02:4848#include "content/public/common/page_zoom.h"
[email protected]e943d6662009-06-12 03:50:3949#include "grit/generated_resources.h"
[email protected]0b7a012d2010-10-19 23:49:2650#include "grit/locale_settings.h"
[email protected]c051a1b2011-01-21 23:30:1751#include "ui/base/l10n/l10n_util.h"
[email protected]477ae052011-11-18 23:53:5752#include "ui/base/models/menu_model.h"
[email protected]9ac174e92011-04-16 00:58:5653#include "ui/base/resource/resource_bundle.h"
[email protected]9dd7e3d72011-01-20 18:27:0654#include "ui/base/view_prop.h"
[email protected]477ae052011-11-18 23:53:5755#include "ui/views/layout/grid_layout.h"
[email protected]e943d6662009-06-12 03:50:3956
[email protected]631bb742011-11-02 11:29:3957using content::BrowserThread;
[email protected]9dd7e3d72011-01-20 18:27:0658using ui::ViewProp;
[email protected]3b8a7f8e2010-11-21 22:44:2159
60static const char kWindowObjectKey[] = "ChromeWindowObject";
initial.commit09911bf2008-07-26 23:55:2961
[email protected]b516e2d2011-07-12 16:54:1262namespace {
63
64// Convert ui::MenuModel into a serializable form for Chrome Frame
65ContextMenuModel* ConvertMenuModel(const ui::MenuModel* ui_model) {
66 ContextMenuModel* new_model = new ContextMenuModel;
67
68 const int index_base = ui_model->GetFirstItemIndex(NULL);
69 const int item_count = ui_model->GetItemCount();
70 new_model->items.reserve(item_count);
71 for (int i = 0; i < item_count; ++i) {
72 const int index = index_base + i;
73 if (ui_model->IsVisibleAt(index)) {
74 ContextMenuModel::Item item;
75 item.type = ui_model->GetTypeAt(index);
76 item.item_id = ui_model->GetCommandIdAt(index);
77 item.label = ui_model->GetLabelAt(index);
78 item.checked = ui_model->IsItemCheckedAt(index);
79 item.enabled = ui_model->IsEnabledAt(index);
80 if (item.type == ui::MenuModel::TYPE_SUBMENU)
81 item.submenu = ConvertMenuModel(ui_model->GetSubmenuModelAt(index));
82
83 new_model->items.push_back(item);
84 }
85 }
86
87 return new_model;
88}
89
90} // namespace
91
[email protected]d0ed50d2010-06-22 01:01:3292base::LazyInstance<ExternalTabContainer::PendingTabs>
[email protected]6de0fd1d2011-11-15 13:31:4993 ExternalTabContainer::pending_tabs_ = LAZY_INSTANCE_INITIALIZER;
[email protected]d0ed50d2010-06-22 01:01:3294
initial.commit09911bf2008-07-26 23:55:2995ExternalTabContainer::ExternalTabContainer(
[email protected]2e4633c2009-07-09 16:58:0696 AutomationProvider* automation, AutomationResourceMessageFilter* filter)
[email protected]2fc66722011-05-19 14:43:1297 : views::NativeWidgetWin(new views::Widget),
[email protected]9a56a0d2011-05-13 19:03:3198 automation_(automation),
[email protected]2e39d2e2009-02-19 18:41:3199 tab_contents_container_(NULL),
[email protected]eac83f02009-05-08 18:44:44100 tab_handle_(0),
[email protected]2e4633c2009-07-09 16:58:06101 ignore_next_load_notification_(false),
102 automation_resource_message_filter_(filter),
[email protected]a50a4902009-08-14 22:39:01103 load_requests_via_automation_(false),
[email protected]24f98bba2009-10-14 18:47:49104 handle_top_level_requests_(false),
[email protected]4cfc1d922009-11-08 14:02:58105 external_method_factory_(this),
[email protected]f7019302010-03-26 19:58:32106 pending_(false),
[email protected]ba67fd82010-07-09 18:30:31107 focus_manager_(NULL),
[email protected]1f71d5882010-07-15 20:39:07108 external_tab_view_(NULL),
[email protected]9eeb35e2010-09-30 21:38:50109 unload_reply_message_(NULL),
[email protected]326d3b72011-03-29 20:38:24110 route_all_top_level_navigations_(false),
111 is_popup_window_(false) {
initial.commit09911bf2008-07-26 23:55:29112}
113
114ExternalTabContainer::~ExternalTabContainer() {
[email protected]632fbb12009-09-06 15:27:14115 Uninitialize();
initial.commit09911bf2008-07-26 23:55:29116}
117
[email protected]7b8d4a22011-02-10 20:57:54118TabContents* ExternalTabContainer::tab_contents() const {
119 return tab_contents_.get() ? tab_contents_->tab_contents() : NULL;
120}
121
[email protected]9095e982009-05-27 17:28:24122bool ExternalTabContainer::Init(Profile* profile,
123 HWND parent,
124 const gfx::Rect& bounds,
[email protected]95c3c592009-07-14 22:09:03125 DWORD style,
[email protected]5f450e52009-07-28 13:28:11126 bool load_requests_via_automation,
[email protected]a50a4902009-08-14 22:39:01127 bool handle_top_level_requests,
[email protected]7b8d4a22011-02-10 20:57:54128 TabContentsWrapper* existing_contents,
[email protected]7de487c2009-12-18 21:07:53129 const GURL& initial_url,
[email protected]f7019302010-03-26 19:58:32130 const GURL& referrer,
[email protected]9eeb35e2010-09-30 21:38:50131 bool infobars_enabled,
132 bool route_all_top_level_navigations) {
initial.commit09911bf2008-07-26 23:55:29133 if (IsWindow()) {
134 NOTREACHED();
135 return false;
136 }
[email protected]0498f7f82009-02-24 03:04:12137
[email protected]95c3c592009-07-14 22:09:03138 load_requests_via_automation_ = load_requests_via_automation;
[email protected]a50a4902009-08-14 22:39:01139 handle_top_level_requests_ = handle_top_level_requests;
[email protected]9eeb35e2010-09-30 21:38:50140 route_all_top_level_navigations_ = route_all_top_level_navigations;
[email protected]95c3c592009-07-14 22:09:03141
[email protected]6603fe92009-08-05 17:05:57142 set_window_style(WS_POPUP | WS_CLIPCHILDREN);
[email protected]af1fde02011-04-26 17:43:05143
[email protected]243d16c2011-04-26 19:31:24144 views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP);
[email protected]af1fde02011-04-26 17:43:05145 params.bounds = bounds;
[email protected]9a56a0d2011-05-13 19:03:31146 params.native_widget = this;
[email protected]af1fde02011-04-26 17:43:05147 GetWidget()->Init(params);
[email protected]08ed00a2009-05-28 20:48:14148 if (!IsWindow()) {
149 NOTREACHED();
150 return false;
151 }
[email protected]f5cde2b2009-09-11 22:33:58152
[email protected]82166b62009-06-30 18:48:00153 // TODO(jcampan): limit focus traversal to contents.
initial.commit09911bf2008-07-26 23:55:29154
[email protected]3b8a7f8e2010-11-21 22:44:21155 prop_.reset(new ViewProp(GetNativeView(), kWindowObjectKey, this));
initial.commit09911bf2008-07-26 23:55:29156
[email protected]632fbb12009-09-06 15:27:14157 if (existing_contents) {
[email protected]7b8d4a22011-02-10 20:57:54158 tab_contents_.reset(existing_contents);
[email protected]3d7474ff2011-07-27 17:47:37159 tab_contents_->controller().set_browser_context(profile);
[email protected]632fbb12009-09-06 15:27:14160 } else {
[email protected]7b8d4a22011-02-10 20:57:54161 TabContents* new_contents = new TabContents(profile, NULL, MSG_ROUTING_NONE,
162 NULL, NULL);
163 tab_contents_.reset(new TabContentsWrapper(new_contents));
[email protected]632fbb12009-09-06 15:27:14164 }
[email protected]a50a4902009-08-14 22:39:01165
[email protected]7abc95292011-05-18 00:18:09166 if (!infobars_enabled)
[email protected]7e204122011-09-01 18:56:21167 tab_contents_->infobar_tab_helper()->set_infobars_enabled(false);
[email protected]7abc95292011-05-18 00:18:09168
[email protected]7b8d4a22011-02-10 20:57:54169 tab_contents_->tab_contents()->set_delegate(this);
[email protected]632fbb12009-09-06 15:27:14170
[email protected]7b8d4a22011-02-10 20:57:54171 tab_contents_->tab_contents()->
172 GetMutableRendererPrefs()->browser_handles_top_level_requests =
173 handle_top_level_requests;
[email protected]a50a4902009-08-14 22:39:01174
175 if (!existing_contents) {
176 tab_contents_->render_view_host()->AllowBindings(
[email protected]e091df82011-10-11 18:13:21177 content::BINDINGS_POLICY_EXTERNAL_HOST);
[email protected]a50a4902009-08-14 22:39:01178 }
[email protected]18cb2572008-08-21 20:34:45179
[email protected]ce3fa3c2009-04-20 19:55:57180 NavigationController* controller = &tab_contents_->controller();
[email protected]432115822011-07-10 15:52:27181 registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED,
[email protected]6c2381d2011-10-19 02:52:53182 content::Source<NavigationController>(controller));
[email protected]432115822011-07-10 15:52:27183 registrar_.Add(this, content::NOTIFICATION_FAIL_PROVISIONAL_LOAD_WITH_ERROR,
[email protected]6c2381d2011-10-19 02:52:53184 content::Source<NavigationController>(controller));
[email protected]432115822011-07-10 15:52:27185 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
[email protected]6c2381d2011-10-19 02:52:53186 content::Source<NavigationController>(controller));
[email protected]432115822011-07-10 15:52:27187 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB,
[email protected]6c2381d2011-10-19 02:52:53188 content::Source<TabContents>(tab_contents_->tab_contents()));
[email protected]432115822011-07-10 15:52:27189 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_DELETED,
[email protected]ad50def52011-10-19 23:17:07190 content::NotificationService::AllSources());
[email protected]867ea802011-10-28 21:14:51191 registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED,
192 content::NotificationService::AllSources());
[email protected]2e4633c2009-07-09 16:58:06193
[email protected]23bf92962011-06-03 21:04:22194 TabContentsObserver::Observe(tab_contents_->tab_contents());
[email protected]15b2c6a2011-05-16 23:54:40195
[email protected]f5cde2b2009-09-11 22:33:58196 // Start loading initial URL
197 if (!initial_url.is_empty()) {
198 // Navigate out of context since we don't have a 'tab_handle_' yet.
[email protected]24f98bba2009-10-14 18:47:49199 MessageLoop::current()->PostTask(
200 FROM_HERE,
201 external_method_factory_.NewRunnableMethod(
[email protected]7de487c2009-12-18 21:07:53202 &ExternalTabContainer::Navigate, initial_url, referrer));
[email protected]f5cde2b2009-09-11 22:33:58203 }
204
[email protected]0498f7f82009-02-24 03:04:12205 // We need WS_POPUP to be on the window during initialization, but
206 // once initialized we apply the requested style which may or may not
207 // include the popup bit.
208 // Note that it's important to do this before we call SetParent since
209 // during the SetParent call we will otherwise get a WA_ACTIVATE call
210 // that causes us to steal the current focus.
[email protected]9095e982009-05-27 17:28:24211 SetWindowLong(GWL_STYLE, (GetWindowLong(GWL_STYLE) & ~WS_POPUP) | style);
[email protected]0498f7f82009-02-24 03:04:12212
[email protected]31fb110522009-01-28 21:50:39213 // Now apply the parenting and style
214 if (parent)
[email protected]9095e982009-05-27 17:28:24215 SetParent(GetNativeView(), parent);
[email protected]7e503122009-02-04 21:52:48216
[email protected]7b8d4a22011-02-10 20:57:54217 ::ShowWindow(tab_contents_->tab_contents()->GetNativeView(), SW_SHOWNA);
[email protected]e943d6662009-06-12 03:50:39218
[email protected]3f70c1e12010-01-12 20:38:49219 LoadAccelerators();
[email protected]ab861b42010-02-05 19:13:44220 SetupExternalTabView();
[email protected]7fbd1e92011-06-02 19:33:00221 tab_contents_->blocked_content_tab_helper()->set_delegate(this);
initial.commit09911bf2008-07-26 23:55:29222 return true;
223}
224
[email protected]632fbb12009-09-06 15:27:14225void ExternalTabContainer::Uninitialize() {
226 registrar_.RemoveAll();
[email protected]7b8d4a22011-02-10 20:57:54227 if (tab_contents_.get()) {
[email protected]39ec12f2011-03-25 23:02:28228 UnregisterRenderViewHost(tab_contents_->render_view_host());
[email protected]52933842009-09-29 03:44:06229
[email protected]9a56a0d2011-05-13 19:03:31230 if (GetWidget()->GetRootView())
231 GetWidget()->GetRootView()->RemoveAllChildViews(true);
[email protected]482a2d92011-02-10 00:34:28232
[email protected]ad50def52011-10-19 23:17:07233 content::NotificationService::current()->Notify(
[email protected]432115822011-07-10 15:52:27234 chrome::NOTIFICATION_EXTERNAL_TAB_CLOSED,
[email protected]6c2381d2011-10-19 02:52:53235 content::Source<NavigationController>(&tab_contents_->controller()),
236 content::Details<ExternalTabContainer>(this));
[email protected]632fbb12009-09-06 15:27:14237
[email protected]7b8d4a22011-02-10 20:57:54238 tab_contents_.reset(NULL);
[email protected]632fbb12009-09-06 15:27:14239 }
[email protected]1a98a932009-11-17 00:12:52240
[email protected]93685472010-04-23 00:57:50241 if (focus_manager_) {
242 focus_manager_->UnregisterAccelerators(this);
[email protected]f1c74ec2010-05-21 22:20:37243 focus_manager_ = NULL;
[email protected]3f70c1e12010-01-12 20:38:49244 }
245
[email protected]ba67fd82010-07-09 18:30:31246 external_tab_view_ = NULL;
[email protected]13c30922009-11-19 03:43:19247 request_context_ = NULL;
[email protected]ab861b42010-02-05 19:13:44248 tab_contents_container_ = NULL;
[email protected]632fbb12009-09-06 15:27:14249}
250
251bool ExternalTabContainer::Reinitialize(
252 AutomationProvider* automation_provider,
[email protected]6e47f2f2010-07-12 17:30:58253 AutomationResourceMessageFilter* filter,
254 gfx::NativeWindow parent_window) {
[email protected]632fbb12009-09-06 15:27:14255 if (!automation_provider || !filter) {
256 NOTREACHED();
257 return false;
258 }
259
260 automation_ = automation_provider;
261 automation_resource_message_filter_ = filter;
[email protected]6c2e45b2010-05-07 00:55:25262 // Wait for the automation channel to be initialized before resuming pending
263 // render views and sending in the navigation state.
[email protected]24f98bba2009-10-14 18:47:49264 MessageLoop::current()->PostTask(
265 FROM_HERE,
266 external_method_factory_.NewRunnableMethod(
[email protected]18290eb2010-01-30 00:47:06267 &ExternalTabContainer::OnReinitialize));
[email protected]6e47f2f2010-07-12 17:30:58268
269 if (parent_window)
270 SetParent(GetNativeView(), parent_window);
[email protected]632fbb12009-09-06 15:27:14271 return true;
272}
273
[email protected]1a98a932009-11-17 00:12:52274void ExternalTabContainer::SetTabHandle(int handle) {
275 tab_handle_ = handle;
[email protected]1a98a932009-11-17 00:12:52276}
277
[email protected]9095e982009-05-27 17:28:24278void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) {
[email protected]0b5781a2011-10-18 21:29:00279 NativeWebKeyboardEvent keyboard_event(msg);
[email protected]3f70c1e12010-01-12 20:38:49280 unhandled_keyboard_event_handler_.HandleKeyboardEvent(keyboard_event,
[email protected]93685472010-04-23 00:57:50281 focus_manager_);
[email protected]9095e982009-05-27 17:28:24282}
283
[email protected]1fd45692010-04-19 21:01:18284void ExternalTabContainer::FocusThroughTabTraversal(
285 bool reverse, bool restore_focus_to_view) {
[email protected]7b8d4a22011-02-10 20:57:54286 DCHECK(tab_contents_.get());
287 if (tab_contents_.get())
288 tab_contents_->tab_contents()->Focus();
[email protected]6331e0b2010-02-23 19:36:10289
290 // The tab_contents_ member can get destroyed in the context of the call to
[email protected]7e2cef52011-04-11 21:47:23291 // TabContentsViewViews::Focus() above. This method eventually calls SetFocus
[email protected]6331e0b2010-02-23 19:36:10292 // on the native window, which could end up dispatching messages like
293 // WM_DESTROY for the external tab.
[email protected]7b8d4a22011-02-10 20:57:54294 if (tab_contents_.get() && restore_focus_to_view)
295 tab_contents_->tab_contents()->FocusThroughTabTraversal(reverse);
initial.commit09911bf2008-07-26 23:55:29296}
297
[email protected]9095e982009-05-27 17:28:24298// static
299bool ExternalTabContainer::IsExternalTabContainer(HWND window) {
[email protected]3b8a7f8e2010-11-21 22:44:21300 return ViewProp::GetValue(window, kWindowObjectKey) != NULL;
initial.commit09911bf2008-07-26 23:55:29301}
302
[email protected]9095e982009-05-27 17:28:24303// static
304ExternalTabContainer* ExternalTabContainer::GetContainerForTab(
305 HWND tab_window) {
306 HWND parent_window = ::GetParent(tab_window);
307 if (!::IsWindow(parent_window)) {
308 return NULL;
initial.commit09911bf2008-07-26 23:55:29309 }
[email protected]9095e982009-05-27 17:28:24310 if (!IsExternalTabContainer(parent_window)) {
311 return NULL;
312 }
313 ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>(
[email protected]3b8a7f8e2010-11-21 22:44:21314 ViewProp::GetValue(parent_window, kWindowObjectKey));
[email protected]9095e982009-05-27 17:28:24315 return container;
initial.commit09911bf2008-07-26 23:55:29316}
317
[email protected]2b19e2fe2010-02-16 02:24:18318// static
319ExternalTabContainer*
320 ExternalTabContainer::GetExternalContainerFromNativeWindow(
321 gfx::NativeView native_window) {
322 ExternalTabContainer* tab_container = NULL;
323 if (native_window) {
[email protected]3b8a7f8e2010-11-21 22:44:21324 tab_container = reinterpret_cast<ExternalTabContainer*>(
325 ViewProp::GetValue(native_window, kWindowObjectKey));
[email protected]2b19e2fe2010-02-16 02:24:18326 }
327 return tab_container;
328}
[email protected]9095e982009-05-27 17:28:24329////////////////////////////////////////////////////////////////////////////////
330// ExternalTabContainer, TabContentsDelegate implementation:
[email protected]72baf6762009-05-06 18:45:33331
[email protected]00c37fc2011-08-02 00:22:50332// TODO(adriansc): Remove this method once refactoring changed all call sites.
[email protected]992e4542011-07-20 23:09:25333TabContents* ExternalTabContainer::OpenURLFromTab(
334 TabContents* source,
335 const GURL& url,
336 const GURL& referrer,
337 WindowOpenDisposition disposition,
[email protected]2905f742011-10-13 03:51:58338 content::PageTransition transition) {
[email protected]00c37fc2011-08-02 00:22:50339 return OpenURLFromTab(source,
[email protected]e47ae9472011-10-13 19:48:34340 OpenURLParams(url, referrer, disposition, transition,
341 false));
[email protected]00c37fc2011-08-02 00:22:50342}
[email protected]18290eb2010-01-30 00:47:06343
[email protected]00c37fc2011-08-02 00:22:50344TabContents* ExternalTabContainer::OpenURLFromTab(TabContents* source,
345 const OpenURLParams& params) {
346 if (pending()) {
347 pending_open_url_requests_.push_back(params);
[email protected]992e4542011-07-20 23:09:25348 return NULL;
[email protected]18290eb2010-01-30 00:47:06349 }
350
[email protected]00c37fc2011-08-02 00:22:50351 switch (params.disposition) {
initial.commit09911bf2008-07-26 23:55:29352 case CURRENT_TAB:
[email protected]fba16f52009-04-02 22:30:35353 case SINGLETON_TAB:
initial.commit09911bf2008-07-26 23:55:29354 case NEW_FOREGROUND_TAB:
355 case NEW_BACKGROUND_TAB:
[email protected]5f450e52009-07-28 13:28:11356 case NEW_POPUP:
initial.commit09911bf2008-07-26 23:55:29357 case NEW_WINDOW:
[email protected]5f450e52009-07-28 13:28:11358 case SAVE_TO_DISK:
initial.commit09911bf2008-07-26 23:55:29359 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34360 automation_->Send(new AutomationMsg_OpenURL(tab_handle_,
[email protected]00c37fc2011-08-02 00:22:50361 params.url,
362 params.referrer,
363 params.disposition));
[email protected]898f59212010-07-22 00:35:26364 // TODO(ananta)
365 // We should populate other fields in the
366 // ViewHostMsg_FrameNavigate_Params structure. Another option could be
367 // to refactor the UpdateHistoryForNavigation function in TabContents.
[email protected]6766b172011-11-21 18:29:36368 content::FrameNavigateParams nav_params;
[email protected]00c37fc2011-08-02 00:22:50369 nav_params.referrer = params.referrer;
370 nav_params.url = params.url;
371 nav_params.page_id = -1;
[email protected]2905f742011-10-13 03:51:58372 nav_params.transition = content::PAGE_TRANSITION_LINK;
[email protected]898f59212010-07-22 00:35:26373
[email protected]8286f51a2011-05-31 17:39:13374 content::LoadCommittedDetails details;
[email protected]898f59212010-07-22 00:35:26375 details.did_replace_entry = false;
376
[email protected]ec0b6c42010-08-26 03:16:58377 scoped_refptr<history::HistoryAddPageArgs> add_page_args(
[email protected]105bb0f2011-05-24 17:12:14378 tab_contents_->history_tab_helper()->
[email protected]00c37fc2011-08-02 00:22:50379 CreateHistoryAddPageArgs(params.url, details, nav_params));
[email protected]105bb0f2011-05-24 17:12:14380 tab_contents_->history_tab_helper()->
[email protected]7b8d4a22011-02-10 20:57:54381 UpdateHistoryForNavigation(add_page_args);
[email protected]992e4542011-07-20 23:09:25382
383 return tab_contents_->tab_contents();
initial.commit09911bf2008-07-26 23:55:29384 }
385 break;
386 default:
[email protected]5f450e52009-07-28 13:28:11387 NOTREACHED();
initial.commit09911bf2008-07-26 23:55:29388 break;
[email protected]6dfed102009-04-28 03:09:53389 }
[email protected]992e4542011-07-20 23:09:25390
391 return NULL;
initial.commit09911bf2008-07-26 23:55:29392}
393
394void ExternalTabContainer::NavigationStateChanged(const TabContents* source,
[email protected]b9d227492009-02-10 15:20:27395 unsigned changed_flags) {
initial.commit09911bf2008-07-26 23:55:29396 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34397 NavigationInfo nav_info;
[email protected]610cbb82011-10-18 16:35:08398 if (InitNavigationInfo(&nav_info, content::NAVIGATION_TYPE_NAV_IGNORE, 0))
[email protected]6c908bb2009-08-21 19:03:50399 automation_->Send(new AutomationMsg_NavigationStateChanged(
[email protected]f5494d42010-12-23 22:15:34400 tab_handle_, changed_flags, nav_info));
initial.commit09911bf2008-07-26 23:55:29401 }
402}
403
initial.commit09911bf2008-07-26 23:55:29404void ExternalTabContainer::AddNewContents(TabContents* source,
405 TabContents* new_contents,
406 WindowOpenDisposition disposition,
407 const gfx::Rect& initial_pos,
408 bool user_gesture) {
[email protected]e478e212010-07-17 00:31:29409 if (!automation_) {
410 DCHECK(pending_);
411 LOG(ERROR) << "Invalid automation provider. Dropping new contents notify";
412 delete new_contents;
413 return;
414 }
[email protected]a50a4902009-08-14 22:39:01415
[email protected]9eeb35e2010-09-30 21:38:50416 scoped_refptr<ExternalTabContainer> new_container;
417 // If the host is a browser like IE8, then the URL being navigated to in the
418 // new tab contents could potentially navigate back to Chrome from a new
419 // IE process. We support full tab mode only for IE and hence we use that as
420 // a determining factor in whether the new ExternalTabContainer instance is
421 // created as pending or not.
422 if (!route_all_top_level_navigations_) {
423 new_container = new ExternalTabContainer(NULL, NULL);
424 } else {
425 // Reuse the same tab handle here as the new container instance is a dummy
426 // instance which does not have an automation client connected at the other
427 // end.
428 new_container = new TemporaryPopupExternalTabContainer(
429 automation_, automation_resource_message_filter_.get());
430 new_container->SetTabHandle(tab_handle_);
431 }
[email protected]a50a4902009-08-14 22:39:01432
[email protected]6f526082010-01-28 19:36:58433 // Make sure that ExternalTabContainer instance is initialized with
434 // an unwrapped Profile.
[email protected]7b8d4a22011-02-10 20:57:54435 scoped_ptr<TabContentsWrapper> wrapper(new TabContentsWrapper(new_contents));
[email protected]6f526082010-01-28 19:36:58436 bool result = new_container->Init(
[email protected]e7013f4c2011-08-01 16:04:12437 wrapper->profile()->GetOriginalProfile(),
[email protected]6f526082010-01-28 19:36:58438 NULL,
439 initial_pos,
440 WS_CHILD,
441 load_requests_via_automation_,
442 handle_top_level_requests_,
[email protected]7b8d4a22011-02-10 20:57:54443 wrapper.get(),
[email protected]6f526082010-01-28 19:36:58444 GURL(),
[email protected]f7019302010-03-26 19:58:32445 GURL(),
[email protected]9eeb35e2010-09-30 21:38:50446 true,
447 route_all_top_level_navigations_);
[email protected]a50a4902009-08-14 22:39:01448
[email protected]6f526082010-01-28 19:36:58449 if (result) {
[email protected]e7013f4c2011-08-01 16:04:12450 Profile* profile = wrapper->profile();
[email protected]7b8d4a22011-02-10 20:57:54451 wrapper.release(); // Ownership has been transferred.
[email protected]9eeb35e2010-09-30 21:38:50452 if (route_all_top_level_navigations_) {
453 return;
454 }
[email protected]b1c55638612010-03-08 16:26:11455 uintptr_t cookie = reinterpret_cast<uintptr_t>(new_container.get());
[email protected]d0ed50d2010-06-22 01:01:32456 pending_tabs_.Get()[cookie] = new_container;
[email protected]18290eb2010-01-30 00:47:06457 new_container->set_pending(true);
[email protected]326d3b72011-03-29 20:38:24458 new_container->set_is_popup_window(disposition == NEW_POPUP);
[email protected]f5494d42010-12-23 22:15:34459 AttachExternalTabParams attach_params_;
[email protected]b1c55638612010-03-08 16:26:11460 attach_params_.cookie = static_cast<uint64>(cookie);
461 attach_params_.dimensions = initial_pos;
462 attach_params_.user_gesture = user_gesture;
463 attach_params_.disposition = disposition;
[email protected]8103c7f2010-09-08 22:36:09464 attach_params_.profile_name = WideToUTF8(
[email protected]e7013f4c2011-08-01 16:04:12465 profile->GetPath().DirName().BaseName().value());
[email protected]f5494d42010-12-23 22:15:34466 automation_->Send(new AutomationMsg_AttachExternalTab(
[email protected]b1c55638612010-03-08 16:26:11467 tab_handle_, attach_params_));
[email protected]6f526082010-01-28 19:36:58468 } else {
469 NOTREACHED();
[email protected]9f5b80a2009-04-08 01:26:07470 }
initial.commit09911bf2008-07-26 23:55:29471}
472
[email protected]5951b5c12010-02-22 18:15:34473void ExternalTabContainer::TabContentsCreated(TabContents* new_contents) {
474 RenderViewHost* rvh = new_contents->render_view_host();
475 DCHECK(rvh != NULL);
[email protected]fd571bb2010-03-19 01:23:54476
477 // Register this render view as a pending render view, i.e. any network
478 // requests initiated by this render view would be serviced when the
479 // external host connects to the new external tab instance.
480 RegisterRenderViewHostForAutomation(rvh, true);
[email protected]5951b5c12010-02-22 18:15:34481}
482
initial.commit09911bf2008-07-26 23:55:29483void ExternalTabContainer::CloseContents(TabContents* source) {
[email protected]d9d8f0c2010-09-17 21:47:16484 if (!automation_)
485 return;
[email protected]e56e96f82010-02-03 21:38:08486
[email protected]d9d8f0c2010-09-17 21:47:16487 if (unload_reply_message_) {
488 AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_,
489 true);
490 automation_->Send(unload_reply_message_);
491 unload_reply_message_ = NULL;
[email protected]e16dd1672010-06-07 21:40:29492 } else {
[email protected]f5494d42010-12-23 22:15:34493 automation_->Send(new AutomationMsg_CloseExternalTab(tab_handle_));
[email protected]085d9cf2010-01-27 01:11:02494 }
initial.commit09911bf2008-07-26 23:55:29495}
496
[email protected]b9d227492009-02-10 15:20:27497void ExternalTabContainer::MoveContents(TabContents* source,
498 const gfx::Rect& pos) {
[email protected]326d3b72011-03-29 20:38:24499 if (automation_ && is_popup_window_)
500 automation_->Send(new AutomationMsg_MoveWindow(tab_handle_, pos));
501}
502
[email protected]7fbd1e92011-06-02 19:33:00503TabContentsWrapper* ExternalTabContainer::GetConstrainingContentsWrapper(
504 TabContentsWrapper* source) {
505 return source;
506}
507
[email protected]5866acb2011-11-15 22:15:13508bool ExternalTabContainer::IsPopupOrPanel(const TabContents* source) const {
[email protected]326d3b72011-03-29 20:38:24509 return is_popup_window_;
initial.commit09911bf2008-07-26 23:55:29510}
511
initial.commit09911bf2008-07-26 23:55:29512void ExternalTabContainer::UpdateTargetURL(TabContents* source,
[email protected]d952a052011-09-06 18:42:45513 int32 page_id,
initial.commit09911bf2008-07-26 23:55:29514 const GURL& url) {
[email protected]d952a052011-09-06 18:42:45515 Browser::UpdateTargetURLHelper(source, page_id, url);
initial.commit09911bf2008-07-26 23:55:29516 if (automation_) {
517 std::wstring url_string = CA2W(url.spec().c_str());
518 automation_->Send(
[email protected]f5494d42010-12-23 22:15:34519 new AutomationMsg_UpdateTargetUrl(tab_handle_, url_string));
initial.commit09911bf2008-07-26 23:55:29520 }
521}
522
523void ExternalTabContainer::ContentsZoomChange(bool zoom_in) {
524}
525
[email protected]a95631cb2009-12-10 01:59:11526gfx::NativeWindow ExternalTabContainer::GetFrameNativeWindow() {
527 return hwnd();
528}
529
[email protected]1e0a02d62009-04-23 22:55:56530bool ExternalTabContainer::TakeFocus(bool reverse) {
531 if (automation_) {
[email protected]f5494d42010-12-23 22:15:34532 automation_->Send(new AutomationMsg_TabbedOut(tab_handle_,
[email protected]a8e20582010-12-31 17:18:50533 base::win::IsShiftPressed()));
[email protected]1e0a02d62009-04-23 22:55:56534 }
535
536 return true;
537}
538
[email protected]686493142011-07-15 21:47:22539bool ExternalTabContainer::CanDownload(TabContents* source, int request_id) {
540 if (load_requests_via_automation_) {
541 if (automation_) {
542 // In case the host needs to show UI that needs to take the focus.
543 ::AllowSetForegroundWindow(ASFW_ANY);
544
545 BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
546 NewRunnableMethod(automation_resource_message_filter_.get(),
547 &AutomationResourceMessageFilter::SendDownloadRequestToHost,
548 0, tab_handle_, request_id));
549 }
550 } else {
551 DLOG(WARNING) << "Downloads are only supported with host browser network "
552 "stack enabled.";
553 }
554
555 // Never allow downloads.
556 return false;
557}
558
[email protected]fd571bb2010-03-19 01:23:54559void ExternalTabContainer::RegisterRenderViewHostForAutomation(
560 RenderViewHost* render_view_host, bool pending_view) {
561 if (render_view_host) {
562 AutomationResourceMessageFilter::RegisterRenderView(
[email protected]f3b1a082011-11-18 00:34:30563 render_view_host->process()->GetID(),
[email protected]fd571bb2010-03-19 01:23:54564 render_view_host->routing_id(),
565 tab_handle(),
566 automation_resource_message_filter_,
567 pending_view);
568 }
569}
570
[email protected]fd571bb2010-03-19 01:23:54571void ExternalTabContainer::RegisterRenderViewHost(
572 RenderViewHost* render_view_host) {
573 // RenderViewHost instances that are to be associated with this
574 // ExternalTabContainer should share the same resource request automation
575 // settings.
576 RegisterRenderViewHostForAutomation(
577 render_view_host,
578 false); // Network requests should not be handled later.
579}
580
581void ExternalTabContainer::UnregisterRenderViewHost(
582 RenderViewHost* render_view_host) {
583 // Undo the resource automation registration performed in
584 // ExternalTabContainer::RegisterRenderViewHost.
585 if (render_view_host) {
586 AutomationResourceMessageFilter::UnRegisterRenderView(
[email protected]f3b1a082011-11-18 00:34:30587 render_view_host->process()->GetID(),
[email protected]fd571bb2010-03-19 01:23:54588 render_view_host->routing_id());
589 }
590}
591
[email protected]3ab9cb82011-06-03 18:02:07592content::JavaScriptDialogCreator*
593ExternalTabContainer::GetJavaScriptDialogCreator() {
594 return GetJavaScriptDialogCreatorInstance();
595}
596
[email protected]e943d6662009-06-12 03:50:39597bool ExternalTabContainer::HandleContextMenu(const ContextMenuParams& params) {
598 if (!automation_) {
599 NOTREACHED();
600 return false;
601 }
[email protected]e943d6662009-06-12 03:50:39602 external_context_menu_.reset(
[email protected]14831ef2010-05-11 23:51:20603 new RenderViewContextMenuViews(tab_contents(), params));
604 external_context_menu_->SetExternal();
[email protected]e943d6662009-06-12 03:50:39605 external_context_menu_->Init();
[email protected]a5e04ea2010-06-08 13:37:08606 external_context_menu_->UpdateMenuItemStates();
[email protected]e943d6662009-06-12 03:50:39607
[email protected]b516e2d2011-07-12 16:54:12608 scoped_ptr<ContextMenuModel> context_menu_model(
609 ConvertMenuModel(&external_context_menu_->menu_model()));
610
[email protected]e943d6662009-06-12 03:50:39611 POINT screen_pt = { params.x, params.y };
612 MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1);
613
[email protected]3b3ec7212011-10-21 17:35:08614 MiniContextMenuParams ipc_params;
615 ipc_params.screen_x = screen_pt.x;
616 ipc_params.screen_y = screen_pt.y;
617 ipc_params.link_url = params.link_url;
618 ipc_params.unfiltered_link_url = params.unfiltered_link_url;
619 ipc_params.src_url = params.src_url;
620 ipc_params.page_url = params.page_url;
621 ipc_params.keyword_url = params.keyword_url;
622 ipc_params.frame_url = params.frame_url;
[email protected]35f13ab2009-12-16 23:59:17623
[email protected]7cf1b6ce2010-03-20 06:37:01624 bool rtl = base::i18n::IsRTL();
[email protected]e943d6662009-06-12 03:50:39625 automation_->Send(
[email protected]f5494d42010-12-23 22:15:34626 new AutomationMsg_ForwardContextMenuToExternalHost(tab_handle_,
[email protected]b516e2d2011-07-12 16:54:12627 *context_menu_model,
[email protected]35f13ab2009-12-16 23:59:17628 rtl ? TPM_RIGHTALIGN : TPM_LEFTALIGN, ipc_params));
[email protected]e943d6662009-06-12 03:50:39629
630 return true;
631}
632
633bool ExternalTabContainer::ExecuteContextMenuCommand(int command) {
634 if (!external_context_menu_.get()) {
635 NOTREACHED();
636 return false;
637 }
638
[email protected]35f13ab2009-12-16 23:59:17639 switch (command) {
640 case IDS_CONTENT_CONTEXT_SAVEAUDIOAS:
641 case IDS_CONTENT_CONTEXT_SAVEVIDEOAS:
642 case IDS_CONTENT_CONTEXT_SAVEIMAGEAS:
643 case IDS_CONTENT_CONTEXT_SAVELINKAS: {
644 NOTREACHED(); // Should be handled in host.
645 break;
646 }
647 }
648
[email protected]e943d6662009-06-12 03:50:39649 external_context_menu_->ExecuteCommand(command);
650 return true;
651}
652
[email protected]867125a02009-12-10 06:01:48653bool ExternalTabContainer::PreHandleKeyboardEvent(
654 const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) {
655 return false;
656}
657
658void ExternalTabContainer::HandleKeyboardEvent(
[email protected]334a105b2009-07-14 03:42:55659 const NativeWebKeyboardEvent& event) {
[email protected]867125a02009-12-10 06:01:48660 ProcessUnhandledKeyStroke(event.os_event.hwnd, event.os_event.message,
661 event.os_event.wParam, event.os_event.lParam);
[email protected]334a105b2009-07-14 03:42:55662}
663
[email protected]d9d8f0c2010-09-17 21:47:16664void ExternalTabContainer::BeforeUnloadFired(TabContents* tab,
665 bool proceed,
666 bool* proceed_to_fire_unload) {
[email protected]d9d8f0c2010-09-17 21:47:16667 *proceed_to_fire_unload = true;
668
669 if (!automation_) {
670 delete unload_reply_message_;
671 unload_reply_message_ = NULL;
672 return;
673 }
674
[email protected]b5e0a192011-03-22 19:15:32675 if (!unload_reply_message_) {
676 NOTREACHED() << "**** NULL unload reply message pointer.";
677 return;
678 }
679
[email protected]d9d8f0c2010-09-17 21:47:16680 if (!proceed) {
681 AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_,
682 false);
683 automation_->Send(unload_reply_message_);
684 unload_reply_message_ = NULL;
685 *proceed_to_fire_unload = false;
686 }
687}
688
[email protected]2fc22d12010-12-02 23:08:16689void ExternalTabContainer::ShowRepostFormWarningDialog(
690 TabContents* tab_contents) {
691 browser::ShowRepostFormWarningDialog(GetNativeView(), tab_contents);
692}
693
[email protected]3a29a6e2011-08-24 18:26:21694void ExternalTabContainer::RunFileChooser(
695 TabContents* tab, const ViewHostMsg_RunFileChooser_Params& params) {
696 Browser::RunFileChooserHelper(tab, params);
697}
698
699void ExternalTabContainer::EnumerateDirectory(TabContents* tab, int request_id,
700 const FilePath& path) {
701 Browser::EnumerateDirectoryHelper(tab, request_id, path);
702}
703
[email protected]7d189022011-08-25 22:54:20704void ExternalTabContainer::JSOutOfMemory(TabContents* tab) {
705 Browser::JSOutOfMemoryHelper(tab);
706}
707
708void ExternalTabContainer::RegisterProtocolHandler(TabContents* tab,
709 const std::string& protocol,
710 const GURL& url,
711 const string16& title) {
712 Browser::RegisterProtocolHandlerHelper(tab, protocol, url, title);
713}
714
715void ExternalTabContainer::RegisterIntentHandler(TabContents* tab,
716 const string16& action,
717 const string16& type,
718 const string16& href,
[email protected]63c239322011-10-31 23:56:30719 const string16& title,
720 const string16& disposition) {
721 Browser::RegisterIntentHandlerHelper(
722 tab, action, type, href, title, disposition);
[email protected]7d189022011-08-25 22:54:20723}
724
[email protected]ce9751942011-09-21 01:57:24725void ExternalTabContainer::WebIntentDispatch(
726 TabContents* tab,
727 int routing_id,
728 const webkit_glue::WebIntentData& intent,
729 int intent_id) {
[email protected]828e61af2011-09-14 19:45:06730 // TODO(binji) How do we want to display the WebIntentPicker bubble if there
731 // is no BrowserWindow?
[email protected]7d189022011-08-25 22:54:20732}
733
[email protected]b888919c2011-09-02 00:32:16734void ExternalTabContainer::FindReply(TabContents* tab,
735 int request_id,
736 int number_of_matches,
737 const gfx::Rect& selection_rect,
738 int active_match_ordinal,
739 bool final_update) {
740 Browser::FindReplyHelper(tab, request_id, number_of_matches, selection_rect,
741 active_match_ordinal, final_update);
742}
743
[email protected]d952a052011-09-06 18:42:45744void ExternalTabContainer::CrashedPlugin(TabContents* tab,
745 const FilePath& plugin_path) {
746 Browser::CrashedPluginHelper(tab, plugin_path);
747}
748
[email protected]15b2c6a2011-05-16 23:54:40749bool ExternalTabContainer::OnMessageReceived(const IPC::Message& message) {
750 bool handled = true;
751 IPC_BEGIN_MESSAGE_MAP(ExternalTabContainer, message)
[email protected]2ccf45c2011-08-19 23:35:50752 IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ForwardMessageToExternalHost,
[email protected]15b2c6a2011-05-16 23:54:40753 OnForwardMessageToExternalHost)
754 IPC_MESSAGE_UNHANDLED(handled = false)
755 IPC_END_MESSAGE_MAP()
756 return handled;
757}
758
759void ExternalTabContainer::OnForwardMessageToExternalHost(
760 const std::string& message,
761 const std::string& origin,
762 const std::string& target) {
763 if (automation_) {
764 automation_->Send(new AutomationMsg_ForwardMessageToExternalHost(
765 tab_handle_, message, origin, target));
766 }
767}
768
[email protected]9095e982009-05-27 17:28:24769////////////////////////////////////////////////////////////////////////////////
770// ExternalTabContainer, NotificationObserver implementation:
771
[email protected]432115822011-07-10 15:52:27772void ExternalTabContainer::Observe(int type,
[email protected]6c2381d2011-10-19 02:52:53773 const content::NotificationSource& source,
774 const content::NotificationDetails& details) {
[email protected]33ee8da2009-04-16 17:45:37775 if (!automation_)
776 return;
777
[email protected]2e39d2e2009-02-19 18:41:31778 static const int kHttpClientErrorStart = 400;
779 static const int kHttpServerErrorEnd = 510;
780
[email protected]432115822011-07-10 15:52:27781 switch (type) {
782 case content::NOTIFICATION_LOAD_STOP: {
[email protected]33ee8da2009-04-16 17:45:37783 const LoadNotificationDetails* load =
[email protected]6c2381d2011-10-19 02:52:53784 content::Details<LoadNotificationDetails>(details).ptr();
[email protected]2905f742011-10-13 03:51:58785 if (load != NULL &&
786 content::PageTransitionIsMainFrame(load->origin())) {
[email protected]366ae242011-05-10 02:23:58787 TRACE_EVENT_END_ETW("ExternalTabContainer::Navigate", 0,
788 load->url().spec());
[email protected]f5494d42010-12-23 22:15:34789 automation_->Send(new AutomationMsg_TabLoaded(tab_handle_,
[email protected]eac83f02009-05-08 18:44:44790 load->url()));
[email protected]33ee8da2009-04-16 17:45:37791 }
792 break;
[email protected]2e39d2e2009-02-19 18:41:31793 }
[email protected]432115822011-07-10 15:52:27794 case content::NOTIFICATION_NAV_ENTRY_COMMITTED: {
[email protected]867ea802011-10-28 21:14:51795 if (ignore_next_load_notification_) {
796 ignore_next_load_notification_ = false;
797 return;
[email protected]0e8db942008-09-24 21:21:48798 }
[email protected]867ea802011-10-28 21:14:51799
800 const content::LoadCommittedDetails* commit =
801 content::Details<content::LoadCommittedDetails>(details).ptr();
802
803 if (commit->http_status_code >= kHttpClientErrorStart &&
804 commit->http_status_code <= kHttpServerErrorEnd) {
805 automation_->Send(new AutomationMsg_NavigationFailed(
806 tab_handle_, commit->http_status_code, commit->entry->url()));
807
808 ignore_next_load_notification_ = true;
809 } else {
810 NavigationInfo navigation_info;
811 // When the previous entry index is invalid, it will be -1, which
812 // will still make the computation come out right (navigating to the
813 // 0th entry will be +1).
814 if (InitNavigationInfo(&navigation_info, commit->type,
815 commit->previous_entry_index -
816 tab_contents_->controller().last_committed_entry_index()))
817 automation_->Send(new AutomationMsg_DidNavigate(tab_handle_,
818 navigation_info));
819 }
820 break;
821 }
[email protected]432115822011-07-10 15:52:27822 case content::NOTIFICATION_FAIL_PROVISIONAL_LOAD_WITH_ERROR: {
[email protected]33ee8da2009-04-16 17:45:37823 const ProvisionalLoadDetails* load_details =
[email protected]6c2381d2011-10-19 02:52:53824 content::Details<ProvisionalLoadDetails>(details).ptr();
[email protected]33ee8da2009-04-16 17:45:37825 automation_->Send(new AutomationMsg_NavigationFailed(
[email protected]f5494d42010-12-23 22:15:34826 tab_handle_, load_details->error_code(), load_details->url()));
[email protected]2e39d2e2009-02-19 18:41:31827
[email protected]33ee8da2009-04-16 17:45:37828 ignore_next_load_notification_ = true;
[email protected]2e39d2e2009-02-19 18:41:31829 break;
830 }
[email protected]432115822011-07-10 15:52:27831 case content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB: {
[email protected]2e4633c2009-07-09 16:58:06832 if (load_requests_via_automation_) {
[email protected]6c2381d2011-10-19 02:52:53833 RenderViewHost* rvh = content::Details<RenderViewHost>(details).ptr();
[email protected]fd571bb2010-03-19 01:23:54834 RegisterRenderViewHostForAutomation(rvh, false);
[email protected]2e4633c2009-07-09 16:58:06835 }
836 break;
837 }
[email protected]432115822011-07-10 15:52:27838 case content::NOTIFICATION_RENDER_VIEW_HOST_DELETED: {
[email protected]2e4633c2009-07-09 16:58:06839 if (load_requests_via_automation_) {
[email protected]6c2381d2011-10-19 02:52:53840 RenderViewHost* rvh = content::Source<RenderViewHost>(source).ptr();
[email protected]fd571bb2010-03-19 01:23:54841 UnregisterRenderViewHost(rvh);
[email protected]2e4633c2009-07-09 16:58:06842 }
843 break;
844 }
[email protected]867ea802011-10-28 21:14:51845 case content::NOTIFICATION_RENDER_VIEW_HOST_CREATED: {
846 if (load_requests_via_automation_) {
847 RenderViewHost* rvh = content::Source<RenderViewHost>(source).ptr();
848 RegisterRenderViewHostForAutomation(rvh, false);
849 }
850 break;
851 }
[email protected]0e8db942008-09-24 21:21:48852 default:
853 NOTREACHED();
854 }
initial.commit09911bf2008-07-26 23:55:29855}
856
[email protected]9095e982009-05-27 17:28:24857////////////////////////////////////////////////////////////////////////////////
[email protected]2fc66722011-05-19 14:43:12858// ExternalTabContainer, views::NativeWidgetWin overrides:
[email protected]9095e982009-05-27 17:28:24859
[email protected]632fbb12009-09-06 15:27:14860LRESULT ExternalTabContainer::OnCreate(LPCREATESTRUCT create_struct) {
[email protected]2fc66722011-05-19 14:43:12861 LRESULT result = views::NativeWidgetWin::OnCreate(create_struct);
[email protected]632fbb12009-09-06 15:27:14862 if (result == 0) {
863 // Grab a reference here which will be released in OnFinalMessage
864 AddRef();
865 }
866 return result;
867}
868
[email protected]9095e982009-05-27 17:28:24869void ExternalTabContainer::OnDestroy() {
[email protected]7c9d8292010-11-01 16:57:13870 prop_.reset();
[email protected]632fbb12009-09-06 15:27:14871 Uninitialize();
[email protected]2fc66722011-05-19 14:43:12872 NativeWidgetWin::OnDestroy();
initial.commit09911bf2008-07-26 23:55:29873}
874
[email protected]632fbb12009-09-06 15:27:14875void ExternalTabContainer::OnFinalMessage(HWND window) {
876 // Release the reference which we grabbed in WM_CREATE.
877 Release();
[email protected]334a105b2009-07-14 03:42:55878}
879
[email protected]d9d8f0c2010-09-17 21:47:16880void ExternalTabContainer::RunUnloadHandlers(IPC::Message* reply_message) {
881 if (!automation_) {
882 delete reply_message;
883 return;
[email protected]1f71d5882010-07-15 20:39:07884 }
[email protected]d9d8f0c2010-09-17 21:47:16885
886 // If we have a pending unload message, then just respond back to this
887 // request and continue processing the previous unload message.
888 if (unload_reply_message_) {
889 AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true);
890 automation_->Send(reply_message);
891 return;
892 }
[email protected]b5e0a192011-03-22 19:15:32893
894 unload_reply_message_ = reply_message;
895 bool wait_for_unload_handlers =
896 tab_contents_.get() &&
897 Browser::RunUnloadEventsHelper(tab_contents_->tab_contents());
898 if (!wait_for_unload_handlers) {
[email protected]d9d8f0c2010-09-17 21:47:16899 AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true);
900 automation_->Send(reply_message);
[email protected]b5e0a192011-03-22 19:15:32901 unload_reply_message_ = NULL;
[email protected]1f71d5882010-07-15 20:39:07902 }
903}
904
[email protected]632fbb12009-09-06 15:27:14905////////////////////////////////////////////////////////////////////////////////
906// ExternalTabContainer, private:
[email protected]334a105b2009-07-14 03:42:55907bool ExternalTabContainer::ProcessUnhandledKeyStroke(HWND window,
908 UINT message,
909 WPARAM wparam,
910 LPARAM lparam) {
initial.commit09911bf2008-07-26 23:55:29911 if (!automation_) {
912 return false;
913 }
[email protected]a8e20582010-12-31 17:18:50914 if ((wparam == VK_TAB) && !base::win::IsCtrlPressed()) {
initial.commit09911bf2008-07-26 23:55:29915 // Tabs are handled separately (except if this is Ctrl-Tab or
916 // Ctrl-Shift-Tab)
917 return false;
918 }
[email protected]060254c2009-05-02 16:45:27919
[email protected]01dba672010-02-12 21:55:48920 // Send this keystroke to the external host as it could be processed as an
921 // accelerator there. If the host does not handle this accelerator, it will
922 // reflect the accelerator back to us via the ProcessUnhandledAccelerator
923 // method.
924 MSG msg = {0};
925 msg.hwnd = window;
926 msg.message = message;
927 msg.wParam = wparam;
928 msg.lParam = lparam;
[email protected]f5494d42010-12-23 22:15:34929 automation_->Send(new AutomationMsg_HandleAccelerator(tab_handle_, msg));
[email protected]01dba672010-02-12 21:55:48930 return true;
initial.commit09911bf2008-07-26 23:55:29931}
[email protected]4150ef02009-08-19 23:14:26932
[email protected]f5494d42010-12-23 22:15:34933bool ExternalTabContainer::InitNavigationInfo(NavigationInfo* nav_info,
[email protected]610cbb82011-10-18 16:35:08934 content::NavigationType nav_type,
[email protected]4150ef02009-08-19 23:14:26935 int relative_offset) {
[email protected]4150ef02009-08-19 23:14:26936 DCHECK(nav_info);
[email protected]6c908bb2009-08-21 19:03:50937 NavigationEntry* entry = tab_contents_->controller().GetActiveEntry();
938 // If this is very early in the game then we may not have an entry.
939 if (!entry)
940 return false;
[email protected]4150ef02009-08-19 23:14:26941
942 nav_info->navigation_type = nav_type;
943 nav_info->relative_offset = relative_offset;
944 nav_info->navigation_index =
945 tab_contents_->controller().GetCurrentEntryIndex();
[email protected]4150ef02009-08-19 23:14:26946 nav_info->url = entry->url();
[email protected]a1955adf2010-08-02 17:59:39947 nav_info->referrer = entry->referrer();
[email protected]6b2f7a82011-04-25 19:30:51948 nav_info->title = UTF16ToWideHack(entry->title());
[email protected]24f98bba2009-10-14 18:47:49949 if (nav_info->title.empty())
950 nav_info->title = UTF8ToWide(nav_info->url.spec());
951
[email protected]f5cde2b2009-09-11 22:33:58952 nav_info->security_style = entry->ssl().security_style();
[email protected]b4e75c12010-05-18 18:28:48953 nav_info->displayed_insecure_content =
954 entry->ssl().displayed_insecure_content();
955 nav_info->ran_insecure_content = entry->ssl().ran_insecure_content();
[email protected]6c908bb2009-08-21 19:03:50956 return true;
[email protected]4150ef02009-08-19 23:14:26957}
958
[email protected]cd0dec62010-02-11 02:33:18959scoped_refptr<ExternalTabContainer> ExternalTabContainer::RemovePendingTab(
[email protected]b1c55638612010-03-08 16:26:11960 uintptr_t cookie) {
[email protected]d0ed50d2010-06-22 01:01:32961 ExternalTabContainer::PendingTabs& pending_tabs = pending_tabs_.Get();
962 PendingTabs::iterator index = pending_tabs.find(cookie);
963 if (index != pending_tabs.end()) {
[email protected]632fbb12009-09-06 15:27:14964 scoped_refptr<ExternalTabContainer> container = (*index).second;
[email protected]d0ed50d2010-06-22 01:01:32965 pending_tabs.erase(index);
[email protected]cd0dec62010-02-11 02:33:18966 return container;
[email protected]632fbb12009-09-06 15:27:14967 }
968
969 NOTREACHED() << "Failed to find ExternalTabContainer for cookie: "
970 << cookie;
971 return NULL;
972}
973
[email protected]9ac174e92011-04-16 00:58:56974SkColor ExternalTabContainer::GetInfoBarSeparatorColor() const {
975 return ResourceBundle::toolbar_separator_color;
976}
977
[email protected]4f2d40d2011-05-05 01:33:30978void ExternalTabContainer::InfoBarContainerStateChanged(bool is_animating) {
[email protected]f4f50ef2011-01-21 19:01:19979 if (external_tab_view_)
[email protected]ba67fd82010-07-09 18:30:31980 external_tab_view_->Layout();
[email protected]ab861b42010-02-05 19:13:44981}
982
[email protected]ee120872011-04-15 01:37:06983bool ExternalTabContainer::DrawInfoBarArrows(int* x) const {
984 return false;
985}
986
[email protected]3f70c1e12010-01-12 20:38:49987bool ExternalTabContainer::AcceleratorPressed(
[email protected]c5be11f2011-11-14 13:33:23988 const ui::Accelerator& accelerator) {
989 std::map<ui::Accelerator, int>::const_iterator iter =
[email protected]3f70c1e12010-01-12 20:38:49990 accelerator_table_.find(accelerator);
991 DCHECK(iter != accelerator_table_.end());
992
[email protected]7b8d4a22011-02-10 20:57:54993 if (!tab_contents_.get() || !tab_contents_->render_view_host()) {
[email protected]3f70c1e12010-01-12 20:38:49994 NOTREACHED();
995 return false;
996 }
997
[email protected]216813952011-05-19 22:21:26998 RenderViewHost* host = tab_contents_->render_view_host();
[email protected]3f70c1e12010-01-12 20:38:49999 int command_id = iter->second;
1000 switch (command_id) {
1001 case IDC_ZOOM_PLUS:
[email protected]54087fe2011-10-28 22:02:481002 host->Zoom(content::PAGE_ZOOM_IN);
[email protected]3f70c1e12010-01-12 20:38:491003 break;
1004 case IDC_ZOOM_NORMAL:
[email protected]54087fe2011-10-28 22:02:481005 host->Zoom(content::PAGE_ZOOM_RESET);
[email protected]3f70c1e12010-01-12 20:38:491006 break;
1007 case IDC_ZOOM_MINUS:
[email protected]54087fe2011-10-28 22:02:481008 host->Zoom(content::PAGE_ZOOM_OUT);
[email protected]3f70c1e12010-01-12 20:38:491009 break;
1010 case IDC_DEV_TOOLS:
[email protected]aebdd072011-07-07 12:36:591011 DevToolsWindow::ToggleDevToolsWindow(
[email protected]2a8a98122010-07-16 11:58:481012 tab_contents_->render_view_host(), DEVTOOLS_TOGGLE_ACTION_NONE);
[email protected]3f70c1e12010-01-12 20:38:491013 break;
1014 case IDC_DEV_TOOLS_CONSOLE:
[email protected]aebdd072011-07-07 12:36:591015 DevToolsWindow::ToggleDevToolsWindow(
[email protected]2a8a98122010-07-16 11:58:481016 tab_contents_->render_view_host(),
1017 DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
1018 break;
1019 case IDC_DEV_TOOLS_INSPECT:
[email protected]aebdd072011-07-07 12:36:591020 DevToolsWindow::ToggleDevToolsWindow(
[email protected]2a8a98122010-07-16 11:58:481021 tab_contents_->render_view_host(),
1022 DEVTOOLS_TOGGLE_ACTION_INSPECT);
[email protected]3f70c1e12010-01-12 20:38:491023 break;
1024 default:
1025 NOTREACHED() << "Unsupported accelerator: " << command_id;
1026 return false;
1027 }
1028 return true;
1029}
1030
[email protected]f5cde2b2009-09-11 22:33:581031void ExternalTabContainer::Navigate(const GURL& url, const GURL& referrer) {
[email protected]7b8d4a22011-02-10 20:57:541032 if (!tab_contents_.get()) {
[email protected]f5cde2b2009-09-11 22:33:581033 NOTREACHED();
1034 return;
1035 }
1036
[email protected]366ae242011-05-10 02:23:581037 TRACE_EVENT_BEGIN_ETW("ExternalTabContainer::Navigate", 0, url.spec());
[email protected]a872ea1f2010-08-11 04:45:331038
[email protected]f5cde2b2009-09-11 22:33:581039 tab_contents_->controller().LoadURL(url, referrer,
[email protected]2905f742011-10-13 03:51:581040 content::PAGE_TRANSITION_START_PAGE,
[email protected]79046fd2011-09-10 05:48:331041 std::string());
[email protected]f5cde2b2009-09-11 22:33:581042}
[email protected]f9cc4c452009-10-13 14:56:381043
1044bool ExternalTabContainer::OnGoToEntryOffset(int offset) {
1045 if (load_requests_via_automation_) {
1046 automation_->Send(new AutomationMsg_RequestGoToHistoryEntryOffset(
[email protected]f5494d42010-12-23 22:15:341047 tab_handle_, offset));
[email protected]f9cc4c452009-10-13 14:56:381048 return false;
1049 }
1050
1051 return true;
1052}
[email protected]1a98a932009-11-17 00:12:521053
[email protected]3f70c1e12010-01-12 20:38:491054void ExternalTabContainer::LoadAccelerators() {
1055 HACCEL accelerator_table = AtlLoadAccelerators(IDR_CHROMEFRAME);
1056 DCHECK(accelerator_table);
1057
1058 // We have to copy the table to access its contents.
1059 int count = CopyAcceleratorTable(accelerator_table, 0, 0);
1060 if (count == 0) {
1061 // Nothing to do in that case.
1062 return;
1063 }
1064
[email protected]1f1e7cb2011-10-07 22:55:471065 scoped_array<ACCEL> scoped_accelerators(new ACCEL[count]);
[email protected]3f70c1e12010-01-12 20:38:491066 ACCEL* accelerators = scoped_accelerators.get();
1067 DCHECK(accelerators != NULL);
1068
1069 CopyAcceleratorTable(accelerator_table, accelerators, count);
1070
[email protected]9a56a0d2011-05-13 19:03:311071 focus_manager_ = GetWidget()->GetFocusManager();
[email protected]93685472010-04-23 00:57:501072 DCHECK(focus_manager_);
[email protected]3f70c1e12010-01-12 20:38:491073
1074 // Let's fill our own accelerator table.
1075 for (int i = 0; i < count; ++i) {
1076 bool alt_down = (accelerators[i].fVirt & FALT) == FALT;
1077 bool ctrl_down = (accelerators[i].fVirt & FCONTROL) == FCONTROL;
1078 bool shift_down = (accelerators[i].fVirt & FSHIFT) == FSHIFT;
[email protected]c5be11f2011-11-14 13:33:231079 ui::Accelerator accelerator(
[email protected]b6d81262011-01-13 17:36:091080 static_cast<ui::KeyboardCode>(accelerators[i].key),
[email protected]3f70c1e12010-01-12 20:38:491081 shift_down, ctrl_down, alt_down);
1082 accelerator_table_[accelerator] = accelerators[i].cmd;
1083
1084 // Also register with the focus manager.
[email protected]93685472010-04-23 00:57:501085 if (focus_manager_)
1086 focus_manager_->RegisterAccelerator(accelerator, this);
[email protected]3f70c1e12010-01-12 20:38:491087 }
1088}
[email protected]18290eb2010-01-30 00:47:061089
1090void ExternalTabContainer::OnReinitialize() {
[email protected]6c2e45b2010-05-07 00:55:251091 if (load_requests_via_automation_) {
[email protected]6c2e45b2010-05-07 00:55:251092 RenderViewHost* rvh = tab_contents_->render_view_host();
1093 if (rvh) {
1094 AutomationResourceMessageFilter::ResumePendingRenderView(
[email protected]f3b1a082011-11-18 00:34:301095 rvh->process()->GetID(), rvh->routing_id(),
[email protected]6c2e45b2010-05-07 00:55:251096 tab_handle_, automation_resource_message_filter_);
1097 }
1098 }
1099
[email protected]7b8d4a22011-02-10 20:57:541100 NavigationStateChanged(tab_contents(), 0);
[email protected]18290eb2010-01-30 00:47:061101 ServicePendingOpenURLRequests();
1102}
1103
1104void ExternalTabContainer::ServicePendingOpenURLRequests() {
1105 DCHECK(pending());
1106
1107 set_pending(false);
1108
1109 for (size_t index = 0; index < pending_open_url_requests_.size();
[email protected]7b8d4a22011-02-10 20:57:541110 ++index) {
[email protected]00c37fc2011-08-02 00:22:501111 const OpenURLParams& url_request = pending_open_url_requests_[index];
1112 OpenURLFromTab(tab_contents(), url_request);
[email protected]18290eb2010-01-30 00:47:061113 }
1114 pending_open_url_requests_.clear();
1115}
1116
[email protected]ab861b42010-02-05 19:13:441117void ExternalTabContainer::SetupExternalTabView() {
1118 // Create a TabContentsContainer to handle focus cycling using Tab and
1119 // Shift-Tab.
1120 tab_contents_container_ = new TabContentsContainer;
1121
1122 // The views created here will be destroyed when the ExternalTabContainer
1123 // widget is torn down.
[email protected]ba67fd82010-07-09 18:30:311124 external_tab_view_ = new views::View();
[email protected]ab861b42010-02-05 19:13:441125
[email protected]6c6614f12011-03-31 18:51:421126 InfoBarContainerView* info_bar_container = new InfoBarContainerView(this);
[email protected]95a33ed62011-09-30 15:07:081127 info_bar_container->ChangeTabContents(tab_contents_->infobar_tab_helper());
[email protected]ab861b42010-02-05 19:13:441128
[email protected]ba67fd82010-07-09 18:30:311129 views::GridLayout* layout = new views::GridLayout(external_tab_view_);
1130 // Give this column an identifier of 0.
1131 views::ColumnSet* columns = layout->AddColumnSet(0);
[email protected]ab861b42010-02-05 19:13:441132 columns->AddColumn(views::GridLayout::FILL,
1133 views::GridLayout::FILL,
1134 1,
1135 views::GridLayout::USE_PREF,
1136 0,
1137 0);
1138
[email protected]ba67fd82010-07-09 18:30:311139 external_tab_view_->SetLayoutManager(layout);
[email protected]ab861b42010-02-05 19:13:441140
1141 layout->StartRow(0, 0);
1142 layout->AddView(info_bar_container);
1143 layout->StartRow(1, 0);
1144 layout->AddView(tab_contents_container_);
[email protected]9a56a0d2011-05-13 19:03:311145 GetWidget()->SetContentsView(external_tab_view_);
[email protected]ab861b42010-02-05 19:13:441146 // Note that SetTabContents must be called after AddChildView is called
[email protected]7b8d4a22011-02-10 20:57:541147 tab_contents_container_->ChangeTabContents(tab_contents());
[email protected]ab861b42010-02-05 19:13:441148}
[email protected]9eeb35e2010-09-30 21:38:501149
1150TemporaryPopupExternalTabContainer::TemporaryPopupExternalTabContainer(
1151 AutomationProvider* automation,
1152 AutomationResourceMessageFilter* filter)
1153 : ExternalTabContainer(automation, filter) {
1154}
1155
1156TemporaryPopupExternalTabContainer::~TemporaryPopupExternalTabContainer() {
[email protected]8e96e502010-10-21 20:57:121157 DVLOG(1) << __FUNCTION__;
[email protected]9eeb35e2010-09-30 21:38:501158}
1159
[email protected]992e4542011-07-20 23:09:251160TabContents* TemporaryPopupExternalTabContainer::OpenURLFromTab(
[email protected]9eeb35e2010-09-30 21:38:501161 TabContents* source, const GURL& url, const GURL& referrer,
[email protected]2905f742011-10-13 03:51:581162 WindowOpenDisposition disposition, content::PageTransition transition) {
[email protected]00c37fc2011-08-02 00:22:501163 return OpenURLFromTab(source,
[email protected]e47ae9472011-10-13 19:48:341164 OpenURLParams(url, referrer, disposition, transition,
1165 false));
[email protected]00c37fc2011-08-02 00:22:501166}
1167
1168TabContents* TemporaryPopupExternalTabContainer::OpenURLFromTab(
1169 TabContents* source,
1170 const OpenURLParams& params) {
[email protected]9eeb35e2010-09-30 21:38:501171 if (!automation_)
[email protected]992e4542011-07-20 23:09:251172 return NULL;
[email protected]9eeb35e2010-09-30 21:38:501173
[email protected]00c37fc2011-08-02 00:22:501174 OpenURLParams forward_params = params;
1175 if (params.disposition == CURRENT_TAB) {
[email protected]9eeb35e2010-09-30 21:38:501176 DCHECK(route_all_top_level_navigations_);
[email protected]00c37fc2011-08-02 00:22:501177 forward_params.disposition = NEW_FOREGROUND_TAB;
[email protected]9eeb35e2010-09-30 21:38:501178 }
[email protected]992e4542011-07-20 23:09:251179 TabContents* new_contents =
[email protected]00c37fc2011-08-02 00:22:501180 ExternalTabContainer::OpenURLFromTab(source, forward_params);
[email protected]9eeb35e2010-09-30 21:38:501181 // support only one navigation for a dummy tab before it is killed.
1182 ::DestroyWindow(GetNativeView());
[email protected]992e4542011-07-20 23:09:251183 return new_contents;
[email protected]9eeb35e2010-09-30 21:38:501184}