diff options
author | tfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-21 06:10:33 +0000 |
---|---|---|
committer | tfarina@chromium.org <tfarina@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-06-21 06:10:33 +0000 |
commit | d370803d8ae64d08ecdf4d99942e97de77ce29af (patch) | |
tree | 5453b377e22bcc1da56e18484ef26661a0a27975 /chrome/browser/external_tab | |
parent | 9e2c5763127d64bce27bfcb1e46c5ea438cd103a (diff) | |
download | chromium_src-d370803d8ae64d08ecdf4d99942e97de77ce29af.zip chromium_src-d370803d8ae64d08ecdf4d99942e97de77ce29af.tar.gz chromium_src-d370803d8ae64d08ecdf4d99942e97de77ce29af.tar.bz2 |
browser: Add ExternalTabContainer interface.
This allow us to remove a dependency in chrome/browser/ui/views from
automation.
BUG=125846
R=ananta@chromium.org,robertshield@chromium.org
TBR=ben@chromium.org
NOTRY=true
Review URL: https://chromiumcodereview.appspot.com/10536198
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@143349 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/external_tab')
-rw-r--r-- | chrome/browser/external_tab/external_tab_container.h | 100 | ||||
-rw-r--r-- | chrome/browser/external_tab/external_tab_container_win.cc | 1211 | ||||
-rw-r--r-- | chrome/browser/external_tab/external_tab_container_win.h | 427 |
3 files changed, 100 insertions, 1638 deletions
diff --git a/chrome/browser/external_tab/external_tab_container.h b/chrome/browser/external_tab/external_tab_container.h new file mode 100644 index 0000000..d12ccf1 --- /dev/null +++ b/chrome/browser/external_tab/external_tab_container.h @@ -0,0 +1,100 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_EXTERNAL_TAB_EXTERNAL_TAB_CONTAINER_H_ +#define CHROME_BROWSER_EXTERNAL_TAB_EXTERNAL_TAB_CONTAINER_H_ +#pragma once + +#include <windows.h> + +#include "base/memory/ref_counted.h" +#include "ui/gfx/native_widget_types.h" + +class AutomationProvider; +class AutomationResourceMessageFilter; +class GURL; +class Profile; +class TabContents; + +namespace content { +class WebContents; +} + +namespace gfx { +class Rect; +} + +namespace IPC { +class Message; +} + +class ExternalTabContainer : public base::RefCounted<ExternalTabContainer> { + public: + static ExternalTabContainer* Create( + AutomationProvider* automation_provider, + AutomationResourceMessageFilter* filter); + + // A helper method that retrieves the ExternalTabContainer object that + // hosts the given tab window. + static ExternalTabContainer* GetContainerForTab(HWND tab_window); + + // Returns the ExternalTabContainer instance associated with the cookie + // passed in. It also erases the corresponding reference from the map. + // Returns NULL if we fail to find the cookie in the map. + static scoped_refptr<ExternalTabContainer> RemovePendingTab(uintptr_t cookie); + + virtual bool Init(Profile* profile, + HWND parent, + const gfx::Rect& bounds, + DWORD style, + bool load_requests_via_automation, + bool handle_top_level_requests, + TabContents* existing_tab_contents, + const GURL& initial_url, + const GURL& referrer, + bool infobars_enabled, + bool supports_full_tab_mode) = 0; + + // Unhook the keystroke listener and notify about the closing WebContents. + // This function gets called from three places, which is fine. + // 1. OnFinalMessage + // 2. In the destructor. + // 3. In AutomationProvider::CreateExternalTab + virtual void Uninitialize() = 0; + + // Used to reinitialize the automation channel and related information + // for this container. Typically used when an ExternalTabContainer + // instance is created by Chrome and attached to an automation client. + virtual bool Reinitialize(AutomationProvider* automation_provider, + AutomationResourceMessageFilter* filter, + gfx::NativeWindow parent_window) = 0; + + // This is invoked when the external host reflects back to us a keyboard + // message it did not process. + virtual void ProcessUnhandledAccelerator(const MSG& msg) = 0; + + // See WebContents::FocusThroughTabTraversal. Called from AutomationProvider. + virtual void FocusThroughTabTraversal(bool reverse, + bool restore_focus_to_view) = 0; + + virtual void RunUnloadHandlers(IPC::Message* reply_message) = 0; + + virtual content::WebContents* GetWebContents() const = 0; + + virtual TabContents* GetTabContents() = 0; + + // This is a wrapper for GetNativeView from ExternalTabContainerWin. + virtual gfx::NativeView GetExternalTabNativeView() const = 0; + + virtual void SetTabHandle(int handle) = 0; + virtual int GetTabHandle() const = 0; + + protected: + virtual ~ExternalTabContainer() {} + + private: + friend class base::RefCounted<ExternalTabContainer>; +}; + +#endif // CHROME_BROWSER_EXTERNAL_TAB_EXTERNAL_TAB_CONTAINER_H_ diff --git a/chrome/browser/external_tab/external_tab_container_win.cc b/chrome/browser/external_tab/external_tab_container_win.cc deleted file mode 100644 index c8805c0..0000000 --- a/chrome/browser/external_tab/external_tab_container_win.cc +++ /dev/null @@ -1,1211 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/browser/external_tab/external_tab_container_win.h" - -#include <string> - -#include "base/bind.h" -#include "base/bind_helpers.h" -#include "base/debug/trace_event.h" -#include "base/i18n/rtl.h" -#include "base/logging.h" -#include "base/memory/scoped_ptr.h" -#include "base/string16.h" -#include "base/utf_string_conversions.h" -#include "base/win/win_util.h" -#include "chrome/app/chrome_command_ids.h" -#include "chrome/app/chrome_dll_resource.h" -#include "chrome/browser/automation/automation_provider.h" -#include "chrome/browser/debugger/devtools_toggle_action.h" -#include "chrome/browser/debugger/devtools_window.h" -#include "chrome/browser/file_select_helper.h" -#include "chrome/browser/history/history_tab_helper.h" -#include "chrome/browser/history/history_types.h" -#include "chrome/browser/infobars/infobar_tab_helper.h" -#include "chrome/browser/profiles/profile.h" -#include "chrome/browser/repost_form_warning_controller.h" -#include "chrome/browser/tab_contents/render_view_context_menu_win.h" -#include "chrome/browser/themes/theme_service.h" -#include "chrome/browser/ui/app_modal_dialogs/javascript_dialog_creator.h" -#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper.h" -#include "chrome/browser/ui/browser.h" -#include "chrome/browser/ui/browser_dialogs.h" -#include "chrome/browser/ui/browser_window.h" -#include "chrome/browser/ui/tab_contents/tab_contents.h" -#include "chrome/browser/ui/views/infobars/infobar_container_view.h" -#include "chrome/common/automation_messages.h" -#include "chrome/common/chrome_constants.h" -#include "chrome/common/chrome_notification_types.h" -#include "chrome/common/render_messages.h" -#include "chrome/common/url_constants.h" -#include "content/public/browser/load_notification_details.h" -#include "content/public/browser/native_web_keyboard_event.h" -#include "content/public/browser/navigation_details.h" -#include "content/public/browser/navigation_entry.h" -#include "content/public/browser/notification_service.h" -#include "content/public/browser/render_process_host.h" -#include "content/public/browser/render_view_host.h" -#include "content/public/browser/web_contents.h" -#include "content/public/browser/web_intents_dispatcher.h" -#include "content/public/common/bindings_policy.h" -#include "content/public/common/frame_navigate_params.h" -#include "content/public/common/page_transition_types.h" -#include "content/public/common/page_zoom.h" -#include "content/public/common/renderer_preferences.h" -#include "content/public/common/ssl_status.h" -#include "grit/generated_resources.h" -#include "grit/locale_settings.h" -#include "third_party/WebKit/Source/Platform/chromium/public/WebReferrerPolicy.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/WebSecurityPolicy.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebCString.h" -#include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h" -#include "ui/base/l10n/l10n_util.h" -#include "ui/base/models/menu_model.h" -#include "ui/base/view_prop.h" -#include "ui/views/controls/webview/webview.h" -#include "ui/views/layout/grid_layout.h" - -using content::BrowserThread; -using content::LoadNotificationDetails; -using content::NativeWebKeyboardEvent; -using content::NavigationController; -using content::NavigationEntry; -using content::OpenURLParams; -using content::RenderViewHost; -using content::SSLStatus; -using content::WebContents; -using ui::ViewProp; -using WebKit::WebCString; -using WebKit::WebReferrerPolicy; -using WebKit::WebSecurityPolicy; -using WebKit::WebString; - -static const char kWindowObjectKey[] = "ChromeWindowObject"; - -namespace { - -// Convert ui::MenuModel into a serializable form for Chrome Frame -ContextMenuModel* ConvertMenuModel(const ui::MenuModel* ui_model) { - ContextMenuModel* new_model = new ContextMenuModel; - - const int index_base = ui_model->GetFirstItemIndex(NULL); - const int item_count = ui_model->GetItemCount(); - new_model->items.reserve(item_count); - for (int i = 0; i < item_count; ++i) { - const int index = index_base + i; - if (ui_model->IsVisibleAt(index)) { - ContextMenuModel::Item item; - item.type = ui_model->GetTypeAt(index); - item.item_id = ui_model->GetCommandIdAt(index); - item.label = ui_model->GetLabelAt(index); - item.checked = ui_model->IsItemCheckedAt(index); - item.enabled = ui_model->IsEnabledAt(index); - if (item.type == ui::MenuModel::TYPE_SUBMENU) - item.submenu = ConvertMenuModel(ui_model->GetSubmenuModelAt(index)); - - new_model->items.push_back(item); - } - } - - return new_model; -} - -} // namespace - -base::LazyInstance<ExternalTabContainer::PendingTabs> - ExternalTabContainer::pending_tabs_ = LAZY_INSTANCE_INITIALIZER; - -ExternalTabContainer::ExternalTabContainer( - AutomationProvider* automation, AutomationResourceMessageFilter* filter) - : views::NativeWidgetWin(new views::Widget), - automation_(automation), - tab_contents_container_(NULL), - tab_handle_(0), - ignore_next_load_notification_(false), - automation_resource_message_filter_(filter), - load_requests_via_automation_(false), - handle_top_level_requests_(false), - ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), - pending_(false), - focus_manager_(NULL), - external_tab_view_(NULL), - unload_reply_message_(NULL), - route_all_top_level_navigations_(false), - is_popup_window_(false) { -} - -ExternalTabContainer::~ExternalTabContainer() { - Uninitialize(); -} - -WebContents * ExternalTabContainer::web_contents() const { - return tab_contents_.get() ? tab_contents_->web_contents() : NULL; -} - -bool ExternalTabContainer::Init(Profile* profile, - HWND parent, - const gfx::Rect& bounds, - DWORD style, - bool load_requests_via_automation, - bool handle_top_level_requests, - TabContents* existing_contents, - const GURL& initial_url, - const GURL& referrer, - bool infobars_enabled, - bool route_all_top_level_navigations) { - if (IsWindow()) { - NOTREACHED(); - return false; - } - - load_requests_via_automation_ = load_requests_via_automation; - handle_top_level_requests_ = handle_top_level_requests; - route_all_top_level_navigations_ = route_all_top_level_navigations; - - set_window_style(WS_POPUP | WS_CLIPCHILDREN); - - views::Widget::InitParams params(views::Widget::InitParams::TYPE_POPUP); - params.bounds = bounds; - params.native_widget = this; - GetWidget()->Init(params); - if (!IsWindow()) { - NOTREACHED(); - return false; - } - - // TODO(jcampan): limit focus traversal to contents. - - prop_.reset(new ViewProp(GetNativeView(), kWindowObjectKey, this)); - - if (existing_contents) { - tab_contents_.reset(existing_contents); - tab_contents_->web_contents()->GetController().SetBrowserContext(profile); - } else { - WebContents* new_contents = WebContents::Create( - profile, NULL, MSG_ROUTING_NONE, NULL, NULL); - tab_contents_.reset(new TabContents(new_contents)); - } - - if (!infobars_enabled) - tab_contents_->infobar_tab_helper()->set_infobars_enabled(false); - - tab_contents_->web_contents()->SetDelegate(this); - - tab_contents_->web_contents()-> - GetMutableRendererPrefs()->browser_handles_non_local_top_level_requests = - handle_top_level_requests; - - if (!existing_contents) { - tab_contents_->web_contents()->GetRenderViewHost()->AllowBindings( - content::BINDINGS_POLICY_EXTERNAL_HOST); - } - - NavigationController* controller = - &tab_contents_->web_contents()->GetController(); - registrar_.Add(this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, - content::Source<NavigationController>(controller)); - registrar_.Add(this, content::NOTIFICATION_LOAD_STOP, - content::Source<NavigationController>(controller)); - registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB, - content::Source<WebContents>(tab_contents_->web_contents())); - registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_DELETED, - content::NotificationService::AllSources()); - registrar_.Add(this, content::NOTIFICATION_RENDER_VIEW_HOST_CREATED, - content::NotificationService::AllSources()); - - content::WebContentsObserver::Observe(tab_contents_->web_contents()); - - // Start loading initial URL - if (!initial_url.is_empty()) { - // Navigate out of context since we don't have a 'tab_handle_' yet. - MessageLoop::current()->PostTask( - FROM_HERE, - base::Bind(&ExternalTabContainer::Navigate, weak_factory_.GetWeakPtr(), - initial_url, referrer)); - } - - // We need WS_POPUP to be on the window during initialization, but - // once initialized we apply the requested style which may or may not - // include the popup bit. - // Note that it's important to do this before we call SetParent since - // during the SetParent call we will otherwise get a WA_ACTIVATE call - // that causes us to steal the current focus. - SetWindowLong(GWL_STYLE, (GetWindowLong(GWL_STYLE) & ~WS_POPUP) | style); - - // Now apply the parenting and style - if (parent) - SetParent(GetNativeView(), parent); - - ::ShowWindow(tab_contents_->web_contents()->GetNativeView(), SW_SHOWNA); - - LoadAccelerators(); - SetupExternalTabView(); - tab_contents_->blocked_content_tab_helper()->set_delegate(this); - return true; -} - -void ExternalTabContainer::Uninitialize() { - registrar_.RemoveAll(); - if (tab_contents_.get()) { - UnregisterRenderViewHost( - tab_contents_->web_contents()->GetRenderViewHost()); - - if (GetWidget()->GetRootView()) - GetWidget()->GetRootView()->RemoveAllChildViews(true); - - content::NotificationService::current()->Notify( - chrome::NOTIFICATION_EXTERNAL_TAB_CLOSED, - content::Source<NavigationController>( - &tab_contents_->web_contents()->GetController()), - content::Details<ExternalTabContainer>(this)); - - tab_contents_.reset(NULL); - } - - if (focus_manager_) { - focus_manager_->UnregisterAccelerators(this); - focus_manager_ = NULL; - } - - external_tab_view_ = NULL; - request_context_ = NULL; - tab_contents_container_ = NULL; -} - -bool ExternalTabContainer::Reinitialize( - AutomationProvider* automation_provider, - AutomationResourceMessageFilter* filter, - gfx::NativeWindow parent_window) { - if (!automation_provider || !filter) { - NOTREACHED(); - return false; - } - - automation_ = automation_provider; - automation_resource_message_filter_ = filter; - // Wait for the automation channel to be initialized before resuming pending - // render views and sending in the navigation state. - MessageLoop::current()->PostTask( - FROM_HERE, base::Bind(&ExternalTabContainer::OnReinitialize, - weak_factory_.GetWeakPtr())); - - if (parent_window) - SetParent(GetNativeView(), parent_window); - return true; -} - -void ExternalTabContainer::SetTabHandle(int handle) { - tab_handle_ = handle; -} - -void ExternalTabContainer::ProcessUnhandledAccelerator(const MSG& msg) { - NativeWebKeyboardEvent keyboard_event(msg); - unhandled_keyboard_event_handler_.HandleKeyboardEvent(keyboard_event, - focus_manager_); -} - -void ExternalTabContainer::FocusThroughTabTraversal( - bool reverse, bool restore_focus_to_view) { - DCHECK(tab_contents_.get()); - if (tab_contents_.get()) - tab_contents_->web_contents()->Focus(); - - // The tab_contents_ member can get destroyed in the context of the call to - // TabContentsViewViews::Focus() above. This method eventually calls SetFocus - // on the native window, which could end up dispatching messages like - // WM_DESTROY for the external tab. - if (tab_contents_.get() && restore_focus_to_view) - tab_contents_->web_contents()->FocusThroughTabTraversal(reverse); -} - -// static -bool ExternalTabContainer::IsExternalTabContainer(HWND window) { - return ViewProp::GetValue(window, kWindowObjectKey) != NULL; -} - -// static -ExternalTabContainer* ExternalTabContainer::GetContainerForTab( - HWND tab_window) { - HWND parent_window = ::GetParent(tab_window); - if (!::IsWindow(parent_window)) { - return NULL; - } - if (!IsExternalTabContainer(parent_window)) { - return NULL; - } - ExternalTabContainer* container = reinterpret_cast<ExternalTabContainer*>( - ViewProp::GetValue(parent_window, kWindowObjectKey)); - return container; -} - -// static -ExternalTabContainer* - ExternalTabContainer::GetExternalContainerFromNativeWindow( - gfx::NativeView native_window) { - ExternalTabContainer* tab_container = NULL; - if (native_window) { - tab_container = reinterpret_cast<ExternalTabContainer*>( - ViewProp::GetValue(native_window, kWindowObjectKey)); - } - return tab_container; -} -//////////////////////////////////////////////////////////////////////////////// -// ExternalTabContainer, content::WebContentsDelegate implementation: - -WebContents* ExternalTabContainer::OpenURLFromTab(WebContents* source, - const OpenURLParams& params) { - if (pending()) { - pending_open_url_requests_.push_back(params); - return NULL; - } - - switch (params.disposition) { - case CURRENT_TAB: - case SINGLETON_TAB: - case NEW_FOREGROUND_TAB: - case NEW_BACKGROUND_TAB: - case NEW_POPUP: - case NEW_WINDOW: - case SAVE_TO_DISK: - if (automation_) { - GURL referrer = GURL(WebSecurityPolicy::generateReferrerHeader( - params.referrer.policy, - params.url, - WebString::fromUTF8(params.referrer.url.spec())).utf8()); - automation_->Send(new AutomationMsg_OpenURL(tab_handle_, - params.url, - referrer, - params.disposition)); - // TODO(ananta) - // We should populate other fields in the - // ViewHostMsg_FrameNavigate_Params structure. Another option could be - // to refactor the UpdateHistoryForNavigation function in WebContents. - content::FrameNavigateParams nav_params; - nav_params.referrer = content::Referrer(referrer, - params.referrer.policy); - nav_params.url = params.url; - nav_params.page_id = -1; - nav_params.transition = content::PAGE_TRANSITION_LINK; - - content::LoadCommittedDetails details; - details.did_replace_entry = false; - - scoped_refptr<history::HistoryAddPageArgs> add_page_args( - tab_contents_->history_tab_helper()-> - CreateHistoryAddPageArgs(params.url, details, nav_params)); - tab_contents_->history_tab_helper()-> - UpdateHistoryForNavigation(add_page_args); - - return tab_contents_->web_contents(); - } - break; - default: - NOTREACHED(); - break; - } - - return NULL; -} - -void ExternalTabContainer::NavigationStateChanged(const WebContents* source, - unsigned changed_flags) { - if (automation_) { - NavigationInfo nav_info; - if (InitNavigationInfo(&nav_info, content::NAVIGATION_TYPE_NAV_IGNORE, 0)) - automation_->Send(new AutomationMsg_NavigationStateChanged( - tab_handle_, changed_flags, nav_info)); - } -} - -void ExternalTabContainer::AddNewContents(WebContents* source, - WebContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) { - if (!automation_) { - DCHECK(pending_); - LOG(ERROR) << "Invalid automation provider. Dropping new contents notify"; - delete new_contents; - return; - } - - scoped_refptr<ExternalTabContainer> new_container; - // If the host is a browser like IE8, then the URL being navigated to in the - // new tab contents could potentially navigate back to Chrome from a new - // IE process. We support full tab mode only for IE and hence we use that as - // a determining factor in whether the new ExternalTabContainer instance is - // created as pending or not. - if (!route_all_top_level_navigations_) { - new_container = new ExternalTabContainer(NULL, NULL); - } else { - // Reuse the same tab handle here as the new container instance is a dummy - // instance which does not have an automation client connected at the other - // end. - new_container = new TemporaryPopupExternalTabContainer( - automation_, automation_resource_message_filter_.get()); - new_container->SetTabHandle(tab_handle_); - } - - // Make sure that ExternalTabContainer instance is initialized with - // an unwrapped Profile. - scoped_ptr<TabContents> tab_contents(new TabContents(new_contents)); - bool result = new_container->Init( - tab_contents->profile()->GetOriginalProfile(), - NULL, - initial_pos, - WS_CHILD, - load_requests_via_automation_, - handle_top_level_requests_, - tab_contents.get(), - GURL(), - GURL(), - true, - route_all_top_level_navigations_); - - if (result) { - Profile* profile = tab_contents->profile(); - tab_contents.release(); // Ownership has been transferred. - if (route_all_top_level_navigations_) { - return; - } - uintptr_t cookie = reinterpret_cast<uintptr_t>(new_container.get()); - pending_tabs_.Get()[cookie] = new_container; - new_container->set_pending(true); - new_container->set_is_popup_window(disposition == NEW_POPUP); - AttachExternalTabParams attach_params_; - attach_params_.cookie = static_cast<uint64>(cookie); - attach_params_.dimensions = initial_pos; - attach_params_.user_gesture = user_gesture; - attach_params_.disposition = disposition; - attach_params_.profile_name = WideToUTF8( - profile->GetPath().DirName().BaseName().value()); - automation_->Send(new AutomationMsg_AttachExternalTab( - tab_handle_, attach_params_)); - } else { - NOTREACHED(); - } -} - -void ExternalTabContainer::WebContentsCreated(WebContents* source_contents, - int64 source_frame_id, - const GURL& target_url, - WebContents* new_contents) { - RenderViewHost* rvh = new_contents->GetRenderViewHost(); - DCHECK(rvh != NULL); - - // Register this render view as a pending render view, i.e. any network - // requests initiated by this render view would be serviced when the - // external host connects to the new external tab instance. - RegisterRenderViewHostForAutomation(rvh, true); -} - -void ExternalTabContainer::CloseContents(content::WebContents* source) { - if (!automation_) - return; - - if (unload_reply_message_) { - AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_, - true); - automation_->Send(unload_reply_message_); - unload_reply_message_ = NULL; - } else { - automation_->Send(new AutomationMsg_CloseExternalTab(tab_handle_)); - } -} - -void ExternalTabContainer::MoveContents(WebContents* source, - const gfx::Rect& pos) { - if (automation_ && is_popup_window_) - automation_->Send(new AutomationMsg_MoveWindow(tab_handle_, pos)); -} - -TabContents* ExternalTabContainer::GetConstrainingTabContents( - TabContents* source) { - return source; -} - -bool ExternalTabContainer::IsPopupOrPanel(const WebContents* source) const { - return is_popup_window_; -} - -void ExternalTabContainer::UpdateTargetURL(WebContents* source, - int32 page_id, - const GURL& url) { - if (automation_) { - string16 url_string = CA2W(url.spec().c_str()); - automation_->Send( - new AutomationMsg_UpdateTargetUrl(tab_handle_, url_string)); - } -} - -void ExternalTabContainer::ContentsZoomChange(bool zoom_in) { -} - -gfx::NativeWindow ExternalTabContainer::GetFrameNativeWindow() { - return hwnd(); -} - -bool ExternalTabContainer::TakeFocus(bool reverse) { - if (automation_) { - automation_->Send(new AutomationMsg_TabbedOut(tab_handle_, - base::win::IsShiftPressed())); - } - - return true; -} - -bool ExternalTabContainer::CanDownload(RenderViewHost* render_view_host, - int request_id, - const std::string& request_method) { - if (load_requests_via_automation_) { - if (automation_) { - // In case the host needs to show UI that needs to take the focus. - ::AllowSetForegroundWindow(ASFW_ANY); - - BrowserThread::PostTask( - BrowserThread::IO, FROM_HERE, - base::Bind( - base::IgnoreResult( - &AutomationResourceMessageFilter::SendDownloadRequestToHost), - automation_resource_message_filter_.get(), 0, tab_handle_, - request_id)); - } - } else { - DLOG(WARNING) << "Downloads are only supported with host browser network " - "stack enabled."; - } - - // Never allow downloads. - return false; -} - -void ExternalTabContainer::RegisterRenderViewHostForAutomation( - RenderViewHost* render_view_host, bool pending_view) { - if (render_view_host) { - AutomationResourceMessageFilter::RegisterRenderView( - render_view_host->GetProcess()->GetID(), - render_view_host->GetRoutingID(), - tab_handle(), - automation_resource_message_filter_, - pending_view); - } -} - -void ExternalTabContainer::RegisterRenderViewHost( - RenderViewHost* render_view_host) { - // RenderViewHost instances that are to be associated with this - // ExternalTabContainer should share the same resource request automation - // settings. - RegisterRenderViewHostForAutomation( - render_view_host, - false); // Network requests should not be handled later. -} - -void ExternalTabContainer::UnregisterRenderViewHost( - RenderViewHost* render_view_host) { - // Undo the resource automation registration performed in - // ExternalTabContainer::RegisterRenderViewHost. - if (render_view_host) { - AutomationResourceMessageFilter::UnRegisterRenderView( - render_view_host->GetProcess()->GetID(), - render_view_host->GetRoutingID()); - } -} - -content::JavaScriptDialogCreator* -ExternalTabContainer::GetJavaScriptDialogCreator() { - return GetJavaScriptDialogCreatorInstance(); -} - -bool ExternalTabContainer::HandleContextMenu( - const content::ContextMenuParams& params) { - if (!automation_) { - NOTREACHED(); - return false; - } - external_context_menu_.reset(RenderViewContextMenuViews::Create( - web_contents(), params)); - static_cast<RenderViewContextMenuWin*>( - external_context_menu_.get())->SetExternal(); - external_context_menu_->Init(); - external_context_menu_->UpdateMenuItemStates(); - - scoped_ptr<ContextMenuModel> context_menu_model( - ConvertMenuModel(&external_context_menu_->menu_model())); - - POINT screen_pt = { params.x, params.y }; - MapWindowPoints(GetNativeView(), HWND_DESKTOP, &screen_pt, 1); - - MiniContextMenuParams ipc_params; - ipc_params.screen_x = screen_pt.x; - ipc_params.screen_y = screen_pt.y; - ipc_params.link_url = params.link_url; - ipc_params.unfiltered_link_url = params.unfiltered_link_url; - ipc_params.src_url = params.src_url; - ipc_params.page_url = params.page_url; - ipc_params.keyword_url = params.keyword_url; - ipc_params.frame_url = params.frame_url; - - bool rtl = base::i18n::IsRTL(); - automation_->Send( - new AutomationMsg_ForwardContextMenuToExternalHost(tab_handle_, - *context_menu_model, - rtl ? TPM_RIGHTALIGN : TPM_LEFTALIGN, ipc_params)); - - return true; -} - -bool ExternalTabContainer::ExecuteContextMenuCommand(int command) { - if (!external_context_menu_.get()) { - NOTREACHED(); - return false; - } - - switch (command) { - case IDS_CONTENT_CONTEXT_SAVEAUDIOAS: - case IDS_CONTENT_CONTEXT_SAVEVIDEOAS: - case IDS_CONTENT_CONTEXT_SAVEIMAGEAS: - case IDS_CONTENT_CONTEXT_SAVELINKAS: { - NOTREACHED(); // Should be handled in host. - break; - } - } - - external_context_menu_->ExecuteCommand(command); - return true; -} - -bool ExternalTabContainer::PreHandleKeyboardEvent( - const NativeWebKeyboardEvent& event, bool* is_keyboard_shortcut) { - return false; -} - -void ExternalTabContainer::HandleKeyboardEvent( - const NativeWebKeyboardEvent& event) { - ProcessUnhandledKeyStroke(event.os_event.hwnd, event.os_event.message, - event.os_event.wParam, event.os_event.lParam); -} - -void ExternalTabContainer::BeforeUnloadFired(WebContents* tab, - bool proceed, - bool* proceed_to_fire_unload) { - *proceed_to_fire_unload = true; - - if (!automation_) { - delete unload_reply_message_; - unload_reply_message_ = NULL; - return; - } - - if (!unload_reply_message_) { - NOTREACHED() << "**** NULL unload reply message pointer."; - return; - } - - if (!proceed) { - AutomationMsg_RunUnloadHandlers::WriteReplyParams(unload_reply_message_, - false); - automation_->Send(unload_reply_message_); - unload_reply_message_ = NULL; - *proceed_to_fire_unload = false; - } -} - -void ExternalTabContainer::ShowRepostFormWarningDialog( - WebContents* source) { - browser::ShowTabModalConfirmDialog( - new RepostFormWarningController(source), - TabContents::FromWebContents(source)); -} - -void ExternalTabContainer::RunFileChooser( - WebContents* tab, const content::FileChooserParams& params) { - FileSelectHelper::RunFileChooser(tab, params); -} - -void ExternalTabContainer::EnumerateDirectory(WebContents* tab, int request_id, - const FilePath& path) { - FileSelectHelper::EnumerateDirectory(tab, request_id, path); -} - -void ExternalTabContainer::JSOutOfMemory(WebContents* tab) { - Browser::JSOutOfMemoryHelper(tab); -} - -void ExternalTabContainer::RegisterProtocolHandler(WebContents* tab, - const std::string& protocol, - const GURL& url, - const string16& title, - bool user_gesture) { - Browser::RegisterProtocolHandlerHelper(tab, protocol, url, title, - user_gesture); -} - -void ExternalTabContainer::RegisterIntentHandler( - WebContents* tab, - const webkit_glue::WebIntentServiceData& data, - bool user_gesture) { - Browser::RegisterIntentHandlerHelper(tab, data, user_gesture); -} - -void ExternalTabContainer::WebIntentDispatch( - WebContents* tab, - content::WebIntentsDispatcher* intents_dispatcher) { - // TODO(binji) How do we want to display the WebIntentPicker bubble if there - // is no BrowserWindow? - delete intents_dispatcher; -} - -void ExternalTabContainer::FindReply(WebContents* tab, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) { - Browser::FindReplyHelper(tab, request_id, number_of_matches, selection_rect, - active_match_ordinal, final_update); -} - -bool ExternalTabContainer::OnMessageReceived(const IPC::Message& message) { - bool handled = true; - IPC_BEGIN_MESSAGE_MAP(ExternalTabContainer, message) - IPC_MESSAGE_HANDLER(ChromeViewHostMsg_ForwardMessageToExternalHost, - OnForwardMessageToExternalHost) - IPC_MESSAGE_UNHANDLED(handled = false) - IPC_END_MESSAGE_MAP() - return handled; -} - -void ExternalTabContainer::DidFailProvisionalLoad( - int64 frame_id, - bool is_main_frame, - const GURL& validated_url, - int error_code, - const string16& error_description, - content::RenderViewHost* render_view_host) { - automation_->Send(new AutomationMsg_NavigationFailed( - tab_handle_, error_code, validated_url)); - ignore_next_load_notification_ = true; -} - -void ExternalTabContainer::OnForwardMessageToExternalHost( - const std::string& message, - const std::string& origin, - const std::string& target) { - if (automation_) { - automation_->Send(new AutomationMsg_ForwardMessageToExternalHost( - tab_handle_, message, origin, target)); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ExternalTabContainer, NotificationObserver implementation: - -void ExternalTabContainer::Observe( - int type, - const content::NotificationSource& source, - const content::NotificationDetails& details) { - if (!automation_) - return; - - static const int kHttpClientErrorStart = 400; - static const int kHttpServerErrorEnd = 510; - - switch (type) { - case content::NOTIFICATION_LOAD_STOP: { - const LoadNotificationDetails* load = - content::Details<LoadNotificationDetails>(details).ptr(); - if (load && content::PageTransitionIsMainFrame(load->origin)) { - TRACE_EVENT_END_ETW("ExternalTabContainer::Navigate", 0, - load->url.spec()); - automation_->Send(new AutomationMsg_TabLoaded(tab_handle_, - load->url)); - } - break; - } - case content::NOTIFICATION_NAV_ENTRY_COMMITTED: { - if (ignore_next_load_notification_) { - ignore_next_load_notification_ = false; - return; - } - - const content::LoadCommittedDetails* commit = - content::Details<content::LoadCommittedDetails>(details).ptr(); - - if (commit->http_status_code >= kHttpClientErrorStart && - commit->http_status_code <= kHttpServerErrorEnd) { - automation_->Send(new AutomationMsg_NavigationFailed( - tab_handle_, commit->http_status_code, commit->entry->GetURL())); - - ignore_next_load_notification_ = true; - } else { - NavigationInfo navigation_info; - // When the previous entry index is invalid, it will be -1, which - // will still make the computation come out right (navigating to the - // 0th entry will be +1). - if (InitNavigationInfo(&navigation_info, commit->type, - commit->previous_entry_index - - tab_contents_->web_contents()-> - GetController().GetLastCommittedEntryIndex())) - automation_->Send(new AutomationMsg_DidNavigate(tab_handle_, - navigation_info)); - } - break; - } - case content::NOTIFICATION_RENDER_VIEW_HOST_CREATED_FOR_TAB: { - if (load_requests_via_automation_) { - RenderViewHost* rvh = content::Details<RenderViewHost>(details).ptr(); - RegisterRenderViewHostForAutomation(rvh, false); - } - break; - } - case content::NOTIFICATION_RENDER_VIEW_HOST_DELETED: { - if (load_requests_via_automation_) { - RenderViewHost* rvh = content::Source<RenderViewHost>(source).ptr(); - UnregisterRenderViewHost(rvh); - } - break; - } - case content::NOTIFICATION_RENDER_VIEW_HOST_CREATED: { - if (load_requests_via_automation_) { - RenderViewHost* rvh = content::Source<RenderViewHost>(source).ptr(); - RegisterRenderViewHostForAutomation(rvh, false); - } - break; - } - default: - NOTREACHED(); - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ExternalTabContainer, views::NativeWidgetWin overrides: - -LRESULT ExternalTabContainer::OnCreate(LPCREATESTRUCT create_struct) { - LRESULT result = views::NativeWidgetWin::OnCreate(create_struct); - if (result == 0) { - // Grab a reference here which will be released in OnFinalMessage - AddRef(); - } - return result; -} - -void ExternalTabContainer::OnDestroy() { - prop_.reset(); - Uninitialize(); - NativeWidgetWin::OnDestroy(); -} - -void ExternalTabContainer::OnFinalMessage(HWND window) { - GetWidget()->OnNativeWidgetDestroyed(); - // Release the reference which we grabbed in WM_CREATE. - Release(); -} - -void ExternalTabContainer::RunUnloadHandlers(IPC::Message* reply_message) { - if (!automation_) { - delete reply_message; - return; - } - - // If we have a pending unload message, then just respond back to this - // request and continue processing the previous unload message. - if (unload_reply_message_) { - AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true); - automation_->Send(reply_message); - return; - } - - unload_reply_message_ = reply_message; - bool wait_for_unload_handlers = - tab_contents_.get() && - Browser::RunUnloadEventsHelper(tab_contents_->web_contents()); - if (!wait_for_unload_handlers) { - AutomationMsg_RunUnloadHandlers::WriteReplyParams(reply_message, true); - automation_->Send(reply_message); - unload_reply_message_ = NULL; - } -} - -//////////////////////////////////////////////////////////////////////////////// -// ExternalTabContainer, private: -bool ExternalTabContainer::ProcessUnhandledKeyStroke(HWND window, - UINT message, - WPARAM wparam, - LPARAM lparam) { - if (!automation_) { - return false; - } - if ((wparam == VK_TAB) && !base::win::IsCtrlPressed()) { - // Tabs are handled separately (except if this is Ctrl-Tab or - // Ctrl-Shift-Tab) - return false; - } - - // Send this keystroke to the external host as it could be processed as an - // accelerator there. If the host does not handle this accelerator, it will - // reflect the accelerator back to us via the ProcessUnhandledAccelerator - // method. - MSG msg = {0}; - msg.hwnd = window; - msg.message = message; - msg.wParam = wparam; - msg.lParam = lparam; - automation_->Send(new AutomationMsg_HandleAccelerator(tab_handle_, msg)); - return true; -} - -bool ExternalTabContainer::InitNavigationInfo(NavigationInfo* nav_info, - content::NavigationType nav_type, - int relative_offset) { - DCHECK(nav_info); - NavigationEntry* entry = - tab_contents_->web_contents()->GetController().GetActiveEntry(); - // If this is very early in the game then we may not have an entry. - if (!entry) - return false; - - nav_info->navigation_type = nav_type; - nav_info->relative_offset = relative_offset; - nav_info->navigation_index = - tab_contents_->web_contents()->GetController().GetCurrentEntryIndex(); - nav_info->url = entry->GetURL(); - nav_info->referrer = entry->GetReferrer().url; - nav_info->title = UTF16ToWideHack(entry->GetTitle()); - if (nav_info->title.empty()) - nav_info->title = UTF8ToWide(nav_info->url.spec()); - - nav_info->security_style = entry->GetSSL().security_style; - int content_status = entry->GetSSL().content_status; - nav_info->displayed_insecure_content = - !!(content_status & SSLStatus::DISPLAYED_INSECURE_CONTENT); - nav_info->ran_insecure_content = - !!(content_status & SSLStatus::RAN_INSECURE_CONTENT); - return true; -} - -scoped_refptr<ExternalTabContainer> ExternalTabContainer::RemovePendingTab( - uintptr_t cookie) { - ExternalTabContainer::PendingTabs& pending_tabs = pending_tabs_.Get(); - PendingTabs::iterator index = pending_tabs.find(cookie); - if (index != pending_tabs.end()) { - scoped_refptr<ExternalTabContainer> container = (*index).second; - pending_tabs.erase(index); - return container; - } - - NOTREACHED() << "Failed to find ExternalTabContainer for cookie: " - << cookie; - return NULL; -} - -SkColor ExternalTabContainer::GetInfoBarSeparatorColor() const { - return ThemeService::GetDefaultColor(ThemeService::COLOR_TOOLBAR_SEPARATOR); -} - -void ExternalTabContainer::InfoBarContainerStateChanged(bool is_animating) { - if (external_tab_view_) - external_tab_view_->Layout(); -} - -bool ExternalTabContainer::DrawInfoBarArrows(int* x) const { - return false; -} - -bool ExternalTabContainer::AcceleratorPressed( - const ui::Accelerator& accelerator) { - std::map<ui::Accelerator, int>::const_iterator iter = - accelerator_table_.find(accelerator); - DCHECK(iter != accelerator_table_.end()); - - if (!tab_contents_.get() || - !tab_contents_->web_contents()->GetRenderViewHost()) { - NOTREACHED(); - return false; - } - - RenderViewHost* host = tab_contents_->web_contents()->GetRenderViewHost(); - int command_id = iter->second; - switch (command_id) { - case IDC_ZOOM_PLUS: - host->Zoom(content::PAGE_ZOOM_IN); - break; - case IDC_ZOOM_NORMAL: - host->Zoom(content::PAGE_ZOOM_RESET); - break; - case IDC_ZOOM_MINUS: - host->Zoom(content::PAGE_ZOOM_OUT); - break; - case IDC_DEV_TOOLS: - DevToolsWindow::ToggleDevToolsWindow( - tab_contents_->web_contents()->GetRenderViewHost(), - DEVTOOLS_TOGGLE_ACTION_NONE); - break; - case IDC_DEV_TOOLS_CONSOLE: - DevToolsWindow::ToggleDevToolsWindow( - tab_contents_->web_contents()->GetRenderViewHost(), - DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE); - break; - case IDC_DEV_TOOLS_INSPECT: - DevToolsWindow::ToggleDevToolsWindow( - tab_contents_->web_contents()->GetRenderViewHost(), - DEVTOOLS_TOGGLE_ACTION_INSPECT); - break; - default: - NOTREACHED() << "Unsupported accelerator: " << command_id; - return false; - } - return true; -} - -bool ExternalTabContainer::CanHandleAccelerators() const { - return true; -} - -void ExternalTabContainer::Navigate(const GURL& url, const GURL& referrer) { - if (!tab_contents_.get()) { - NOTREACHED(); - return; - } - - TRACE_EVENT_BEGIN_ETW("ExternalTabContainer::Navigate", 0, url.spec()); - - tab_contents_->web_contents()->GetController().LoadURL( - url, content::Referrer(referrer, WebKit::WebReferrerPolicyDefault), - content::PAGE_TRANSITION_START_PAGE, std::string()); -} - -bool ExternalTabContainer::OnGoToEntryOffset(int offset) { - if (load_requests_via_automation_) { - automation_->Send(new AutomationMsg_RequestGoToHistoryEntryOffset( - tab_handle_, offset)); - return false; - } - - return true; -} - -void ExternalTabContainer::LoadAccelerators() { - HACCEL accelerator_table = AtlLoadAccelerators(IDR_CHROMEFRAME); - DCHECK(accelerator_table); - - // We have to copy the table to access its contents. - int count = CopyAcceleratorTable(accelerator_table, 0, 0); - if (count == 0) { - // Nothing to do in that case. - return; - } - - scoped_array<ACCEL> scoped_accelerators(new ACCEL[count]); - ACCEL* accelerators = scoped_accelerators.get(); - DCHECK(accelerators != NULL); - - CopyAcceleratorTable(accelerator_table, accelerators, count); - - focus_manager_ = GetWidget()->GetFocusManager(); - DCHECK(focus_manager_); - - // Let's fill our own accelerator table. - for (int i = 0; i < count; ++i) { - ui::Accelerator accelerator( - static_cast<ui::KeyboardCode>(accelerators[i].key), - ui::GetModifiersFromACCEL(accelerators[i])); - accelerator_table_[accelerator] = accelerators[i].cmd; - - // Also register with the focus manager. - if (focus_manager_) { - focus_manager_->RegisterAccelerator( - accelerator, ui::AcceleratorManager::kNormalPriority, this); - } - } -} - -void ExternalTabContainer::OnReinitialize() { - if (load_requests_via_automation_) { - RenderViewHost* rvh = tab_contents_->web_contents()->GetRenderViewHost(); - if (rvh) { - AutomationResourceMessageFilter::ResumePendingRenderView( - rvh->GetProcess()->GetID(), rvh->GetRoutingID(), - tab_handle_, automation_resource_message_filter_); - } - } - - NavigationStateChanged(web_contents(), 0); - ServicePendingOpenURLRequests(); -} - -void ExternalTabContainer::ServicePendingOpenURLRequests() { - DCHECK(pending()); - - set_pending(false); - - for (size_t index = 0; index < pending_open_url_requests_.size(); - ++index) { - const OpenURLParams& url_request = pending_open_url_requests_[index]; - OpenURLFromTab(web_contents(), url_request); - } - pending_open_url_requests_.clear(); -} - -void ExternalTabContainer::SetupExternalTabView() { - // Create a TabContentsContainer to handle focus cycling using Tab and - // Shift-Tab. - tab_contents_container_ = new views::WebView(tab_contents_->profile()); - - // The views created here will be destroyed when the ExternalTabContainer - // widget is torn down. - external_tab_view_ = new views::View(); - - InfoBarContainerView* info_bar_container = new InfoBarContainerView(this); - info_bar_container->ChangeTabContents(tab_contents_->infobar_tab_helper()); - - views::GridLayout* layout = new views::GridLayout(external_tab_view_); - // Give this column an identifier of 0. - views::ColumnSet* columns = layout->AddColumnSet(0); - columns->AddColumn(views::GridLayout::FILL, - views::GridLayout::FILL, - 1, - views::GridLayout::USE_PREF, - 0, - 0); - - external_tab_view_->SetLayoutManager(layout); - - layout->StartRow(0, 0); - layout->AddView(info_bar_container); - layout->StartRow(1, 0); - layout->AddView(tab_contents_container_); - GetWidget()->SetContentsView(external_tab_view_); - // Note that SetTabContents must be called after AddChildView is called - tab_contents_container_->SetWebContents(web_contents()); -} - -TemporaryPopupExternalTabContainer::TemporaryPopupExternalTabContainer( - AutomationProvider* automation, - AutomationResourceMessageFilter* filter) - : ExternalTabContainer(automation, filter) { -} - -TemporaryPopupExternalTabContainer::~TemporaryPopupExternalTabContainer() { - DVLOG(1) << __FUNCTION__; -} - -WebContents* TemporaryPopupExternalTabContainer::OpenURLFromTab( - WebContents* source, - const OpenURLParams& params) { - if (!automation_) - return NULL; - - OpenURLParams forward_params = params; - if (params.disposition == CURRENT_TAB) { - DCHECK(route_all_top_level_navigations_); - forward_params.disposition = NEW_FOREGROUND_TAB; - } - WebContents* new_contents = - ExternalTabContainer::OpenURLFromTab(source, forward_params); - // support only one navigation for a dummy tab before it is killed. - ::DestroyWindow(GetNativeView()); - return new_contents; -} diff --git a/chrome/browser/external_tab/external_tab_container_win.h b/chrome/browser/external_tab/external_tab_container_win.h deleted file mode 100644 index 476b4ce..0000000 --- a/chrome/browser/external_tab/external_tab_container_win.h +++ /dev/null @@ -1,427 +0,0 @@ -// Copyright (c) 2012 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_BROWSER_EXTERNAL_TAB_EXTERNAL_TAB_CONTAINER_WIN_H_ -#define CHROME_BROWSER_EXTERNAL_TAB_EXTERNAL_TAB_CONTAINER_WIN_H_ -#pragma once - -#include <map> -#include <string> -#include <vector> - -#include "base/compiler_specific.h" -#include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" -#include "base/memory/weak_ptr.h" -#include "chrome/browser/automation/automation_resource_message_filter.h" -#include "chrome/browser/infobars/infobar_container.h" -#include "chrome/browser/net/chrome_url_request_context.h" -#include "chrome/browser/ui/blocked_content/blocked_content_tab_helper_delegate.h" -#include "chrome/browser/ui/views/unhandled_keyboard_event_handler.h" -#include "content/public/browser/navigation_type.h" -#include "content/public/browser/notification_observer.h" -#include "content/public/browser/notification_registrar.h" -#include "content/public/browser/web_contents_delegate.h" -#include "content/public/browser/web_contents_observer.h" -#include "ui/base/accelerators/accelerator.h" -#include "ui/views/widget/native_widget_win.h" - -class AutomationProvider; -class Browser; -class Profile; -class TabContentsContainer; -class TabContents; -class RenderViewContextMenuViews; -struct NavigationInfo; - -namespace content { -class WebIntentsDispatcher; -} - -namespace ui { -class ViewProp; -} - -namespace views { -class WebView; -} - -// This class serves as the container window for an external tab. -// An external tab is a Chrome tab that is meant to displayed in an -// external process. This class provides the FocusManger needed by the -// WebContents as well as an implementation of content::WebContentsDelegate. -class ExternalTabContainer : public content::WebContentsDelegate, - public content::WebContentsObserver, - public content::NotificationObserver, - public views::NativeWidgetWin, - public base::RefCounted<ExternalTabContainer>, - public ui::AcceleratorTarget, - public InfoBarContainer::Delegate, - public BlockedContentTabHelperDelegate { - public: - typedef std::map<uintptr_t, scoped_refptr<ExternalTabContainer> > PendingTabs; - - ExternalTabContainer(AutomationProvider* automation, - AutomationResourceMessageFilter* filter); - - content::WebContents* web_contents() const; - TabContents* tab_contents() { return tab_contents_.get(); } - - // Temporary hack so we can send notifications back - void SetTabHandle(int handle); - - int tab_handle() const { - return tab_handle_; - } - - bool Init(Profile* profile, - HWND parent, - const gfx::Rect& bounds, - DWORD style, - bool load_requests_via_automation, - bool handle_top_level_requests, - TabContents* existing_tab_contents, - const GURL& initial_url, - const GURL& referrer, - bool infobars_enabled, - bool supports_full_tab_mode); - - // Unhook the keystroke listener and notify about the closing WebContents. - // This function gets called from three places, which is fine. - // 1. OnFinalMessage - // 2. In the destructor. - // 3. In AutomationProvider::CreateExternalTab - void Uninitialize(); - - // Used to reinitialize the automation channel and related information - // for this container. Typically used when an ExternalTabContainer - // instance is created by Chrome and attached to an automation client. - bool Reinitialize(AutomationProvider* automation_provider, - AutomationResourceMessageFilter* filter, - gfx::NativeWindow parent_window); - - // This is invoked when the external host reflects back to us a keyboard - // message it did not process - void ProcessUnhandledAccelerator(const MSG& msg); - - // See WebContents::FocusThroughTabTraversal. Called from AutomationProvider. - void FocusThroughTabTraversal(bool reverse, bool restore_focus_to_view); - - // A helper method that tests whether the given window is an - // ExternalTabContainer window - static bool IsExternalTabContainer(HWND window); - - // A helper function that returns a pointer to the ExternalTabContainer - // instance associated with a native view. Returns NULL if the window - // is not an ExternalTabContainer. - static ExternalTabContainer* GetExternalContainerFromNativeWindow( - gfx::NativeView native_window); - - // A helper method that retrieves the ExternalTabContainer object that - // hosts the given tab window. - static ExternalTabContainer* GetContainerForTab(HWND tab_window); - - // Overridden from content::WebContentsDelegate: - virtual content::WebContents* OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) OVERRIDE; - virtual void NavigationStateChanged(const content::WebContents* source, - unsigned changed_flags) OVERRIDE; - virtual void AddNewContents(content::WebContents* source, - content::WebContents* new_contents, - WindowOpenDisposition disposition, - const gfx::Rect& initial_pos, - bool user_gesture) OVERRIDE; - virtual void CloseContents(content::WebContents* source) OVERRIDE; - virtual void MoveContents(content::WebContents* source, - const gfx::Rect& pos) OVERRIDE; - virtual bool IsPopupOrPanel( - const content::WebContents* source) const OVERRIDE; - virtual void UpdateTargetURL(content::WebContents* source, int32 page_id, - const GURL& url) OVERRIDE; - virtual void ContentsZoomChange(bool zoom_in) OVERRIDE; - virtual gfx::NativeWindow GetFrameNativeWindow() OVERRIDE; - virtual void WebContentsCreated(content::WebContents* source_contents, - int64 source_frame_id, - const GURL& target_url, - content::WebContents* new_contents) OVERRIDE; - virtual bool PreHandleKeyboardEvent( - const content::NativeWebKeyboardEvent& event, - bool* is_keyboard_shortcut) OVERRIDE; - virtual void HandleKeyboardEvent( - const content::NativeWebKeyboardEvent& event) OVERRIDE; - virtual bool TakeFocus(bool reverse) OVERRIDE; - virtual bool CanDownload(content::RenderViewHost* render_view_host, - int request_id, - const std::string& request_method) OVERRIDE; - virtual bool OnGoToEntryOffset(int offset) OVERRIDE; - virtual bool HandleContextMenu( - const content::ContextMenuParams& params) OVERRIDE; - virtual bool ExecuteContextMenuCommand(int command) OVERRIDE; - virtual void BeforeUnloadFired(content::WebContents* tab, - bool proceed, - bool* proceed_to_fire_unload) OVERRIDE; - virtual content::JavaScriptDialogCreator* - GetJavaScriptDialogCreator() OVERRIDE; - virtual void ShowRepostFormWarningDialog( - content::WebContents* source) OVERRIDE; - virtual void RunFileChooser( - content::WebContents* tab, - const content::FileChooserParams& params) OVERRIDE; - virtual void EnumerateDirectory(content::WebContents* tab, - int request_id, - const FilePath& path) OVERRIDE; - virtual void JSOutOfMemory(content::WebContents* tab); - virtual void RegisterProtocolHandler(content::WebContents* tab, - const std::string& protocol, - const GURL& url, - const string16& title, - bool user_gesture) OVERRIDE; - virtual void RegisterIntentHandler( - content::WebContents* tab, - const webkit_glue::WebIntentServiceData& data, - bool user_gesture) OVERRIDE; - virtual void WebIntentDispatch( - content::WebContents* tab, - content::WebIntentsDispatcher* intents_dispatcher) OVERRIDE; - virtual void FindReply(content::WebContents* tab, - int request_id, - int number_of_matches, - const gfx::Rect& selection_rect, - int active_match_ordinal, - bool final_update) OVERRIDE; - - void RegisterRenderViewHost(content::RenderViewHost* render_view_host); - void UnregisterRenderViewHost(content::RenderViewHost* render_view_host); - - // Overridden from content::WebContentsObserver: - virtual bool OnMessageReceived(const IPC::Message& message); - virtual void DidFailProvisionalLoad( - int64 frame_id, - bool is_main_frame, - const GURL& validated_url, - int error_code, - const string16& error_description, - content::RenderViewHost* render_view_host) OVERRIDE; - - // Message handlers - void OnForwardMessageToExternalHost(const std::string& message, - const std::string& origin, - const std::string& target); - - // Overridden from content::NotificationObserver: - virtual void Observe(int type, - const content::NotificationSource& source, - const content::NotificationDetails& details); - - // Returns the ExternalTabContainer instance associated with the cookie - // passed in. It also erases the corresponding reference from the map. - // Returns NULL if we fail to find the cookie in the map. - static scoped_refptr<ExternalTabContainer> RemovePendingTab(uintptr_t cookie); - - // ui::AcceleratorTarget - bool AcceleratorPressed(const ui::Accelerator& accelerator) OVERRIDE; - bool CanHandleAccelerators() const OVERRIDE; - - bool pending() const { - return pending_; - } - - void set_pending(bool pending) { - pending_ = pending; - } - - void set_is_popup_window(bool is_popup_window) { - is_popup_window_ = is_popup_window; - } - - // InfoBarContainer::Delegate overrides - virtual SkColor GetInfoBarSeparatorColor() const OVERRIDE; - virtual void InfoBarContainerStateChanged(bool is_animating) OVERRIDE; - virtual bool DrawInfoBarArrows(int* x) const OVERRIDE; - - void RunUnloadHandlers(IPC::Message* reply_message); - - // Overridden from BlockedContentTabHelperDelegate: - virtual TabContents* GetConstrainingTabContents(TabContents* source) OVERRIDE; - - protected: - ~ExternalTabContainer(); - // Overridden from views::NativeWidgetWin: - virtual LRESULT OnCreate(LPCREATESTRUCT create_struct); - virtual void OnDestroy(); - virtual void OnFinalMessage(HWND window); - - bool InitNavigationInfo(NavigationInfo* nav_info, - content::NavigationType nav_type, - int relative_offset); - void Navigate(const GURL& url, const GURL& referrer); - - friend class base::RefCounted<ExternalTabContainer>; - - // Helper resource automation registration method, allowing registration of - // pending RenderViewHosts. - void RegisterRenderViewHostForAutomation( - content::RenderViewHost* render_view_host, - bool pending_view); - - // Helper function for processing keystokes coming back from the renderer - // process. - bool ProcessUnhandledKeyStroke(HWND window, UINT message, WPARAM wparam, - LPARAM lparam); - - void LoadAccelerators(); - - // Sends over pending Open URL requests to the external host. - void ServicePendingOpenURLRequests(); - - // Scheduled as a task in ExternalTabContainer::Reinitialize - void OnReinitialize(); - - // Creates and initializes the view hierarchy for this ExternalTabContainer. - void SetupExternalTabView(); - - scoped_ptr<TabContents> tab_contents_; - scoped_refptr<AutomationProvider> automation_; - - content::NotificationRegistrar registrar_; - - // A view to handle focus cycling - views::WebView* tab_contents_container_; - - int tab_handle_; - // A failed navigation like a 404 is followed in chrome with a success - // navigation for the 404 page. We need to ignore the next navigation - // to avoid confusing the clients of the external tab. This member variable - // is set when we need to ignore the next load notification. - bool ignore_next_load_notification_; - - scoped_ptr<RenderViewContextMenuViews> external_context_menu_; - - // A message filter to load resources via automation - scoped_refptr<AutomationResourceMessageFilter> - automation_resource_message_filter_; - - // If all the url requests for this tab are to be loaded via automation. - bool load_requests_via_automation_; - - // whether top level URL requests are to be handled by the automation client. - bool handle_top_level_requests_; - - // Contains ExternalTabContainers that have not been connected to as yet. - static base::LazyInstance<PendingTabs> pending_tabs_; - - // Allows us to run tasks on the ExternalTabContainer instance which are - // bound by its lifetime. - base::WeakPtrFactory<ExternalTabContainer> weak_factory_; - - // The URL request context to be used for this tab. Can be NULL. - scoped_refptr<ChromeURLRequestContextGetter> request_context_; - - UnhandledKeyboardEventHandler unhandled_keyboard_event_handler_; - - // A mapping between accelerators and commands. - std::map<ui::Accelerator, int> accelerator_table_; - - // Top level navigations received for a tab while it is waiting for an ack - // from the external host go here. Scenario is a window.open executes on a - // page in ChromeFrame. A new WebContents is created and the current - // ExternalTabContainer is notified via AddNewContents. At this point we - // send off an attach tab request to the host browser. Before the host - // browser sends over the ack, we receive a top level URL navigation for the - // new tab, which needs to be routed over the correct automation channel. - // We receive the automation channel only when the external host acks the - // attach tab request. - // Contains the list of URL requests which are pending waiting for an ack - // from the external host. - std::vector<content::OpenURLParams> pending_open_url_requests_; - - // Set to true if the ExternalTabContainer instance is waiting for an ack - // from the host. - bool pending_; - - views::FocusManager* focus_manager_; - - views::View* external_tab_view_; - - IPC::Message* unload_reply_message_; - - // set to true if the host needs to get notified of all top level navigations - // in this page. This typically applies to hosts which would render the new - // page without chrome frame. - bool route_all_top_level_navigations_; - - scoped_ptr<ui::ViewProp> prop_; - - // if this tab is a popup - bool is_popup_window_; - - DISALLOW_COPY_AND_ASSIGN(ExternalTabContainer); -}; - -// This class is instantiated for handling requests to open popups for external -// tabs hosted in browsers which need to be notified about all top level -// navigations. An instance of this class is created for handling window.open -// or link navigations with target blank, etc. -class TemporaryPopupExternalTabContainer : public ExternalTabContainer { - public: - TemporaryPopupExternalTabContainer(AutomationProvider* automation, - AutomationResourceMessageFilter* filter); - virtual ~TemporaryPopupExternalTabContainer(); - - virtual bool OnGoToEntryOffset(int offset) { - NOTREACHED(); - return false; - } - - virtual bool ProcessUnhandledKeyStroke(HWND window, UINT message, - WPARAM wparam, LPARAM lparam) { - NOTREACHED(); - return false; - } - - virtual void Observe(int type, const content::NotificationSource& source, - const content::NotificationDetails& details) {} - - virtual content::WebContents* OpenURLFromTab( - content::WebContents* source, - const content::OpenURLParams& params) OVERRIDE; - - virtual void NavigationStateChanged(const content::WebContents* source, - unsigned changed_flags) { - NOTREACHED(); - } - - virtual void CloseContents(content::WebContents* source) { - NOTREACHED(); - } - - virtual void UpdateTargetURL(content::WebContents* source, int32 page_id, - const GURL& url) { - NOTREACHED(); - } - - void ForwardMessageToExternalHost(const std::string& message, - const std::string& origin, - const std::string& target) { - NOTREACHED(); - } - - virtual bool TakeFocus(bool reverse) { - NOTREACHED(); - return false; - } - - virtual bool HandleContextMenu(const content::ContextMenuParams& params) { - NOTREACHED(); - return false; - } - - virtual void BeforeUnloadFired(content::WebContents* tab, bool proceed, - bool* proceed_to_fire_unload) { - NOTREACHED(); - } -}; - -#endif // CHROME_BROWSER_EXTERNAL_TAB_EXTERNAL_TAB_CONTAINER_WIN_H_ |