103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// found in the LICENSE file.
403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h"
703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/favicon/favicon_tab_helper.h"
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h"
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/ui/zoom/zoom_controller.h"
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/common/chrome_version_info.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "components/pdf/browser/pdf_web_contents_helper.h"
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "components/renderer_context_menu/context_menu_delegate.h"
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "content/public/common/page_zoom.h"
171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/api/web_request/web_request_api.h"
181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "extensions/browser/guest_view/web_view/web_view_constants.h"
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(ENABLE_PRINTING)
2103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(ENABLE_FULL_PRINTING)
2203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/printing/print_preview_message_handler.h"
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/printing/print_view_manager.h"
2403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#else
2503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#include "chrome/browser/printing/print_view_manager_basic.h"
2603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif  // defined(ENABLE_FULL_PRINTING)
2703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif  // defined(ENABLE_PRINTING)
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid RemoveWebViewEventListenersOnIOThread(
301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    void* profile,
311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const std::string& extension_id,
321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int embedder_process_id,
331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    int view_instance_id) {
341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners(
361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      profile,
371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      extension_id,
381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      embedder_process_id,
391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      view_instance_id);
401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
4203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)ChromeWebViewGuestDelegate::ChromeWebViewGuestDelegate(
4303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    extensions::WebViewGuest* web_view_guest)
441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    : pending_context_menu_request_id_(0),
451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      chromevox_injected_(false),
461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      current_zoom_factor_(1.0),
471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      web_view_guest_(web_view_guest) {
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
4903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)ChromeWebViewGuestDelegate::~ChromeWebViewGuestDelegate() {
5103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
5203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)double ChromeWebViewGuestDelegate::GetZoom() {
5403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return current_zoom_factor_;
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
5603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
5703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)bool ChromeWebViewGuestDelegate::HandleContextMenu(
5803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const content::ContextMenuParams& params) {
5903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ContextMenuDelegate* menu_delegate =
6003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ContextMenuDelegate::FromWebContents(guest_web_contents());
6103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(menu_delegate);
6203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  pending_menu_ = menu_delegate->BuildMenu(guest_web_contents(), params);
6403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
6503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Pass it to embedder.
6603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  int request_id = ++pending_context_menu_request_id_;
6703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
6803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<base::ListValue> items =
6903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      MenuModelToValue(pending_menu_->menu_model());
7003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  args->Set(webview::kContextMenuItems, items.release());
7103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  args->SetInteger(webview::kRequestId, request_id);
721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_view_guest()->DispatchEventToEmbedder(
7303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      new extensions::GuestViewBase::Event(
7403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          webview::kEventContextMenu, args.Pass()));
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return true;
7603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
7703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// TODO(hanxi) Investigate which of these observers should move to the
7903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// extension module in the future.
8003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::OnAttachWebViewHelpers(
8103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::WebContents* contents) {
8203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Create a zoom controller for the guest contents give it access to
8303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // GetZoomLevel() and and SetZoomLevel() in WebViewGuest.
8403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // TODO(wjmaclean) This currently uses the same HostZoomMap as the browser
8503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // context, but we eventually want to isolate the guest contents from zoom
8603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // changes outside the guest (e.g. in the main browser), so we should
8703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // create a separate HostZoomMap for the guest.
8803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ZoomController::CreateForWebContents(contents);
8903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
9003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  FaviconTabHelper::CreateForWebContents(contents);
9103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  extensions::ChromeExtensionWebContentsObserver::
9203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      CreateForWebContents(contents);
9303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(ENABLE_PRINTING)
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(ENABLE_FULL_PRINTING)
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  printing::PrintViewManager::CreateForWebContents(contents);
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  printing::PrintPreviewMessageHandler::CreateForWebContents(contents);
9703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#else
9803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  printing::PrintViewManagerBasic::CreateForWebContents(contents);
9903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif  // defined(ENABLE_FULL_PRINTING)
10003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif  // defined(ENABLE_PRINTING)
1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  pdf::PDFWebContentsHelper::CreateForWebContentsWithClient(
1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      contents,
1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      scoped_ptr<pdf::PDFWebContentsHelperClient>(
1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          new ChromePDFWebContentsHelperClient()));
1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeWebViewGuestDelegate::OnEmbedderDestroyed() {
1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(fsamuel): WebRequest event listeners for <webview> should survive
1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // reparenting of a <webview> within a single embedder. Right now, we keep
1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // around the browser state for the listener for the lifetime of the embedder.
1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Ideally, the lifetime of the listeners should match the lifetime of the
1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // <webview> DOM node. Once http://crbug.com/156219 is resolved we can move
1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // the call to RemoveWebViewEventListenersOnIOThread back to
1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // WebViewGuest::WebContentsDestroyed.
1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  content::BrowserThread::PostTask(
1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      content::BrowserThread::IO,
1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      FROM_HERE,
1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      base::Bind(
1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          &RemoveWebViewEventListenersOnIOThread,
1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          web_view_guest()->browser_context(),
1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          web_view_guest()->embedder_extension_id(),
1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          web_view_guest()->embedder_render_process_id(),
1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci          web_view_guest()->view_instance_id()));
1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeWebViewGuestDelegate::OnDidAttachToEmbedder() {
1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // TODO(fsamuel): This code should be implemented in GuestViewBase once the
1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // ZoomController moves to the extensions module.
1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ZoomController* zoom_controller = ZoomController::FromWebContents(
1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      web_view_guest()->embedder_web_contents());
1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  if (!zoom_controller)
1321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    return;
1331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Listen to the embedder's zoom changes.
1341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  zoom_controller->AddObserver(this);
1351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  // Set the guest's initial zoom level to be equal to the embedder's.
1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ZoomController::FromWebContents(guest_web_contents())->
1371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SetZoomLevel(zoom_controller->GetZoomLevel());
13803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
13903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
14003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::OnDidCommitProvisionalLoadForFrame(
14103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    bool is_main_frame) {
14203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Update the current zoom factor for the new page.
14303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ZoomController* zoom_controller =
14403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ZoomController::FromWebContents(guest_web_contents());
14503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(zoom_controller);
14603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  current_zoom_factor_ = zoom_controller->GetZoomLevel();
14703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (is_main_frame)
14803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    chromevox_injected_ = false;
14903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
15003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
15103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::OnDidInitialize() {
15203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_CHROMEOS)
15303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  chromeos::AccessibilityManager* accessibility_manager =
15403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      chromeos::AccessibilityManager::Get();
15503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  CHECK(accessibility_manager);
15603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  accessibility_subscription_ = accessibility_manager->RegisterCallback(
15703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      base::Bind(&ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged,
15803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                 base::Unretained(this)));
15903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif
16003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
16103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
16203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::OnDocumentLoadedInFrame(
16303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::RenderFrameHost* render_frame_host) {
16403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!render_frame_host->GetParent())
16503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    InjectChromeVoxIfNeeded(render_frame_host->GetRenderViewHost());
16603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
16703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
16803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::OnGuestDestroyed() {
16903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Clean up custom context menu items for this guest.
17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  extensions::MenuManager* menu_manager = extensions::MenuManager::Get(
1711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      Profile::FromBrowserContext(web_view_guest()->browser_context()));
17203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  menu_manager->RemoveAllContextItems(extensions::MenuItem::ExtensionKey(
1731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      web_view_guest()->embedder_extension_id(),
1741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      web_view_guest()->view_instance_id()));
17503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
17603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
17703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)// static
17803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)scoped_ptr<base::ListValue> ChromeWebViewGuestDelegate::MenuModelToValue(
17903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const ui::SimpleMenuModel& menu_model) {
18003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<base::ListValue> items(new base::ListValue());
18103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for (int i = 0; i < menu_model.GetItemCount(); ++i) {
18203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    base::DictionaryValue* item_value = new base::DictionaryValue();
18303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // TODO(lazyboy): We need to expose some kind of enum equivalent of
18403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    // |command_id| instead of plain integers.
18503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    item_value->SetInteger(webview::kMenuItemCommandId,
18603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)                           menu_model.GetCommandIdAt(i));
18703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    item_value->SetString(webview::kMenuItemLabel, menu_model.GetLabelAt(i));
18803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    items->Append(item_value);
18903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
19003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  return items.Pass();
19103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
19203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
19303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::OnSetZoom(double zoom_factor) {
19403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ZoomController* zoom_controller =
19503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ZoomController::FromWebContents(guest_web_contents());
19603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(zoom_controller);
19703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  double zoom_level = content::ZoomFactorToZoomLevel(zoom_factor);
19803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  zoom_controller->SetZoomLevel(zoom_level);
19903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
20003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
20103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  args->SetDouble(webview::kOldZoomFactor, current_zoom_factor_);
20203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  args->SetDouble(webview::kNewZoomFactor, zoom_factor);
2031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  web_view_guest()->DispatchEventToEmbedder(
20403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      new extensions::GuestViewBase::Event(
20503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)          webview::kEventZoomChange, args.Pass()));
20603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  current_zoom_factor_ = zoom_factor;
20703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
20803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
20903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::OnShowContextMenu(
21003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    int request_id,
21103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const MenuItemVector* items) {
21203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!pending_menu_.get())
21303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return;
21403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
21503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // Make sure this was the correct request.
21603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (request_id != pending_context_menu_request_id_)
21703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return;
21803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
21903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  // TODO(lazyboy): Implement.
22003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  DCHECK(!items);
22103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  ContextMenuDelegate* menu_delegate =
22303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      ContextMenuDelegate::FromWebContents(guest_web_contents());
22403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  menu_delegate->ShowMenu(pending_menu_.Pass());
22503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
22603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
22703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::InjectChromeVoxIfNeeded(
22803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    content::RenderViewHost* render_view_host) {
22903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_CHROMEOS)
23003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (!chromevox_injected_) {
23103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    chromeos::AccessibilityManager* manager =
23203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        chromeos::AccessibilityManager::Get();
23303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (manager && manager->IsSpokenFeedbackEnabled()) {
23403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      manager->InjectChromeVox(render_view_host);
23503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      chromevox_injected_ = true;
23603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    }
23703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
23803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif
23903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
24003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
24103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#if defined(OS_CHROMEOS)
24203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged(
24303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    const chromeos::AccessibilityStatusEventDetails& details) {
24403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  if (details.notification_type == chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN) {
24503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    accessibility_subscription_.reset();
24603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  } else if (details.notification_type ==
24703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) {
24803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    if (details.enabled)
24903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost());
25003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    else
25103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)      chromevox_injected_ = false;
25203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  }
25303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
25403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)#endif
2551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
2561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ChromeWebViewGuestDelegate::OnZoomChanged(
2571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    const ZoomController::ZoomChangedEventData& data) {
2581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci  ZoomController::FromWebContents(guest_web_contents())->
2591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci      SetZoomLevel(data.new_zoom_level);
2601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci}
261