Add GCMChannelStatusSyncer to schedule requests and enable/disable GCM
[chromium-blink-merge.git] / chrome / browser / guest_view / web_view / chrome_web_view_guest_delegate.cc
blob30c5c20016c85f9dffc167bc0caae5a07033e09d
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 #include "chrome/browser/guest_view/web_view/chrome_web_view_guest_delegate.h"
8 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
9 #include "chrome/browser/extensions/chrome_extension_web_contents_observer.h"
10 #include "chrome/browser/favicon/favicon_tab_helper.h"
11 #include "chrome/browser/renderer_context_menu/render_view_context_menu.h"
12 #include "chrome/browser/ui/pdf/chrome_pdf_web_contents_helper_client.h"
13 #include "chrome/browser/ui/zoom/zoom_controller.h"
14 #include "chrome/common/chrome_version_info.h"
15 #include "components/pdf/browser/pdf_web_contents_helper.h"
16 #include "components/renderer_context_menu/context_menu_delegate.h"
17 #include "content/public/common/page_zoom.h"
18 #include "extensions/browser/guest_view/web_view/web_view_constants.h"
20 #if defined(ENABLE_PRINTING)
21 #if defined(ENABLE_FULL_PRINTING)
22 #include "chrome/browser/printing/print_preview_message_handler.h"
23 #include "chrome/browser/printing/print_view_manager.h"
24 #else
25 #include "chrome/browser/printing/print_view_manager_basic.h"
26 #endif // defined(ENABLE_FULL_PRINTING)
27 #endif // defined(ENABLE_PRINTING)
29 void RemoveWebViewEventListenersOnIOThread(
30 void* profile,
31 const std::string& extension_id,
32 int embedder_process_id,
33 int view_instance_id) {
34 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO));
35 ExtensionWebRequestEventRouter::GetInstance()->RemoveWebViewEventListeners(
36 profile,
37 extension_id,
38 embedder_process_id,
39 view_instance_id);
42 ChromeWebViewGuestDelegate::ChromeWebViewGuestDelegate(
43 extensions::WebViewGuest* web_view_guest)
44 : WebViewGuestDelegate(web_view_guest),
45 find_helper_(web_view_guest),
46 pending_context_menu_request_id_(0),
47 chromevox_injected_(false),
48 current_zoom_factor_(1.0) {
51 ChromeWebViewGuestDelegate::~ChromeWebViewGuestDelegate() {
54 void ChromeWebViewGuestDelegate::Find(
55 const base::string16& search_text,
56 const blink::WebFindOptions& options,
57 extensions::WebViewInternalFindFunction* find_function) {
58 find_helper_.Find(guest_web_contents(), search_text, options, find_function);
61 void ChromeWebViewGuestDelegate::FindReply(content::WebContents* source,
62 int request_id,
63 int number_of_matches,
64 const gfx::Rect& selection_rect,
65 int active_match_ordinal,
66 bool final_update) {
67 find_helper_.FindReply(request_id, number_of_matches, selection_rect,
68 active_match_ordinal, final_update);
71 void ChromeWebViewGuestDelegate::StopFinding(content::StopFindAction action) {
72 find_helper_.CancelAllFindSessions();
73 guest_web_contents()->StopFinding(action);
76 double ChromeWebViewGuestDelegate::GetZoom() {
77 return current_zoom_factor_;
80 bool ChromeWebViewGuestDelegate::HandleContextMenu(
81 const content::ContextMenuParams& params) {
82 ContextMenuDelegate* menu_delegate =
83 ContextMenuDelegate::FromWebContents(guest_web_contents());
84 DCHECK(menu_delegate);
86 pending_menu_ = menu_delegate->BuildMenu(guest_web_contents(), params);
88 // Pass it to embedder.
89 int request_id = ++pending_context_menu_request_id_;
90 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
91 scoped_ptr<base::ListValue> items =
92 MenuModelToValue(pending_menu_->menu_model());
93 args->Set(webview::kContextMenuItems, items.release());
94 args->SetInteger(webview::kRequestId, request_id);
95 web_view_guest()->DispatchEventToEmbedder(
96 new extensions::GuestViewBase::Event(
97 webview::kEventContextMenu, args.Pass()));
98 return true;
101 // TODO(hanxi) Investigate which of these observers should move to the
102 // extension module in the future.
103 void ChromeWebViewGuestDelegate::OnAttachWebViewHelpers(
104 content::WebContents* contents) {
105 // Create a zoom controller for the guest contents give it access to
106 // GetZoomLevel() and and SetZoomLevel() in WebViewGuest.
107 // TODO(wjmaclean) This currently uses the same HostZoomMap as the browser
108 // context, but we eventually want to isolate the guest contents from zoom
109 // changes outside the guest (e.g. in the main browser), so we should
110 // create a separate HostZoomMap for the guest.
111 ZoomController::CreateForWebContents(contents);
113 FaviconTabHelper::CreateForWebContents(contents);
114 extensions::ChromeExtensionWebContentsObserver::
115 CreateForWebContents(contents);
116 #if defined(ENABLE_PRINTING)
117 #if defined(ENABLE_FULL_PRINTING)
118 printing::PrintViewManager::CreateForWebContents(contents);
119 printing::PrintPreviewMessageHandler::CreateForWebContents(contents);
120 #else
121 printing::PrintViewManagerBasic::CreateForWebContents(contents);
122 #endif // defined(ENABLE_FULL_PRINTING)
123 #endif // defined(ENABLE_PRINTING)
124 pdf::PDFWebContentsHelper::CreateForWebContentsWithClient(
125 contents,
126 scoped_ptr<pdf::PDFWebContentsHelperClient>(
127 new ChromePDFWebContentsHelperClient()));
130 void ChromeWebViewGuestDelegate::OnEmbedderDestroyed() {
131 // TODO(fsamuel): WebRequest event listeners for <webview> should survive
132 // reparenting of a <webview> within a single embedder. Right now, we keep
133 // around the browser state for the listener for the lifetime of the embedder.
134 // Ideally, the lifetime of the listeners should match the lifetime of the
135 // <webview> DOM node. Once http://crbug.com/156219 is resolved we can move
136 // the call to RemoveWebViewEventListenersOnIOThread back to
137 // WebViewGuest::WebContentsDestroyed.
138 content::BrowserThread::PostTask(
139 content::BrowserThread::IO,
140 FROM_HERE,
141 base::Bind(
142 &RemoveWebViewEventListenersOnIOThread,
143 web_view_guest()->browser_context(),
144 web_view_guest()->embedder_extension_id(),
145 web_view_guest()->embedder_render_process_id(),
146 web_view_guest()->view_instance_id()));
149 void ChromeWebViewGuestDelegate::OnDidCommitProvisionalLoadForFrame(
150 bool is_main_frame) {
151 find_helper_.CancelAllFindSessions();
153 // Update the current zoom factor for the new page.
154 ZoomController* zoom_controller =
155 ZoomController::FromWebContents(guest_web_contents());
156 DCHECK(zoom_controller);
157 current_zoom_factor_ = zoom_controller->GetZoomLevel();
158 if (is_main_frame)
159 chromevox_injected_ = false;
162 void ChromeWebViewGuestDelegate::OnDidInitialize() {
163 #if defined(OS_CHROMEOS)
164 chromeos::AccessibilityManager* accessibility_manager =
165 chromeos::AccessibilityManager::Get();
166 CHECK(accessibility_manager);
167 accessibility_subscription_ = accessibility_manager->RegisterCallback(
168 base::Bind(&ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged,
169 base::Unretained(this)));
170 #endif
173 void ChromeWebViewGuestDelegate::OnDocumentLoadedInFrame(
174 content::RenderFrameHost* render_frame_host) {
175 if (!render_frame_host->GetParent())
176 InjectChromeVoxIfNeeded(render_frame_host->GetRenderViewHost());
179 void ChromeWebViewGuestDelegate::OnGuestDestroyed() {
180 // Clean up custom context menu items for this guest.
181 extensions::MenuManager* menu_manager = extensions::MenuManager::Get(
182 Profile::FromBrowserContext(web_view_guest()->browser_context()));
183 menu_manager->RemoveAllContextItems(extensions::MenuItem::ExtensionKey(
184 web_view_guest()->embedder_extension_id(),
185 web_view_guest()->view_instance_id()));
188 // static
189 scoped_ptr<base::ListValue> ChromeWebViewGuestDelegate::MenuModelToValue(
190 const ui::SimpleMenuModel& menu_model) {
191 scoped_ptr<base::ListValue> items(new base::ListValue());
192 for (int i = 0; i < menu_model.GetItemCount(); ++i) {
193 base::DictionaryValue* item_value = new base::DictionaryValue();
194 // TODO(lazyboy): We need to expose some kind of enum equivalent of
195 // |command_id| instead of plain integers.
196 item_value->SetInteger(webview::kMenuItemCommandId,
197 menu_model.GetCommandIdAt(i));
198 item_value->SetString(webview::kMenuItemLabel, menu_model.GetLabelAt(i));
199 items->Append(item_value);
201 return items.Pass();
204 void ChromeWebViewGuestDelegate::OnRenderProcessGone() {
205 // Cancel all find sessions in progress.
206 find_helper_.CancelAllFindSessions();
209 void ChromeWebViewGuestDelegate::OnSetZoom(double zoom_factor) {
210 ZoomController* zoom_controller =
211 ZoomController::FromWebContents(guest_web_contents());
212 DCHECK(zoom_controller);
213 double zoom_level = content::ZoomFactorToZoomLevel(zoom_factor);
214 zoom_controller->SetZoomLevel(zoom_level);
216 scoped_ptr<base::DictionaryValue> args(new base::DictionaryValue());
217 args->SetDouble(webview::kOldZoomFactor, current_zoom_factor_);
218 args->SetDouble(webview::kNewZoomFactor, zoom_factor);
219 web_view_guest()->DispatchEventToEmbedder(
220 new extensions::GuestViewBase::Event(
221 webview::kEventZoomChange, args.Pass()));
222 current_zoom_factor_ = zoom_factor;
225 void ChromeWebViewGuestDelegate::OnShowContextMenu(
226 int request_id,
227 const MenuItemVector* items) {
228 if (!pending_menu_.get())
229 return;
231 // Make sure this was the correct request.
232 if (request_id != pending_context_menu_request_id_)
233 return;
235 // TODO(lazyboy): Implement.
236 DCHECK(!items);
238 ContextMenuDelegate* menu_delegate =
239 ContextMenuDelegate::FromWebContents(guest_web_contents());
240 menu_delegate->ShowMenu(pending_menu_.Pass());
243 void ChromeWebViewGuestDelegate::InjectChromeVoxIfNeeded(
244 content::RenderViewHost* render_view_host) {
245 #if defined(OS_CHROMEOS)
246 if (!chromevox_injected_) {
247 chromeos::AccessibilityManager* manager =
248 chromeos::AccessibilityManager::Get();
249 if (manager && manager->IsSpokenFeedbackEnabled()) {
250 manager->InjectChromeVox(render_view_host);
251 chromevox_injected_ = true;
254 #endif
257 #if defined(OS_CHROMEOS)
258 void ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged(
259 const chromeos::AccessibilityStatusEventDetails& details) {
260 if (details.notification_type == chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN) {
261 accessibility_subscription_.reset();
262 } else if (details.notification_type ==
263 chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK) {
264 if (details.enabled)
265 InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost());
266 else
267 chromevox_injected_ = false;
270 #endif