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/chrome_extension_web_contents_observer.h"
9 #include "chrome/browser/favicon/favicon_tab_helper.h"
10 #include "chrome/browser/profiles/profile.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/common/chrome_version_info.h"
14 #include "components/browsing_data/storage_partition_http_cache_data_remover.h"
15 #include "components/pdf/browser/pdf_web_contents_helper.h"
16 #include "components/renderer_context_menu/context_menu_delegate.h"
17 #include "components/web_cache/browser/web_cache_manager.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "extensions/browser/api/web_request/web_request_api.h"
20 #include "extensions/browser/guest_view/web_view/web_view_constants.h"
22 #if defined(ENABLE_PRINTING)
23 #if defined(ENABLE_PRINT_PREVIEW)
24 #include "chrome/browser/printing/print_preview_message_handler.h"
25 #include "chrome/browser/printing/print_view_manager.h"
27 #include "chrome/browser/printing/print_view_manager_basic.h"
28 #endif // defined(ENABLE_PRINT_PREVIEW)
29 #endif // defined(ENABLE_PRINTING)
31 namespace extensions
{
33 ChromeWebViewGuestDelegate::ChromeWebViewGuestDelegate(
34 WebViewGuest
* web_view_guest
)
35 : pending_context_menu_request_id_(0),
36 chromevox_injected_(false),
37 web_view_guest_(web_view_guest
),
38 weak_ptr_factory_(this) {
41 ChromeWebViewGuestDelegate::~ChromeWebViewGuestDelegate() {
44 void ChromeWebViewGuestDelegate::ClearCache(
45 base::Time remove_since
,
46 const base::Closure
& done_callback
) {
47 int render_process_id
= guest_web_contents()->GetRenderProcessHost()->GetID();
48 // We need to clear renderer cache separately for our process because
49 // StoragePartitionHttpCacheDataRemover::ClearData() does not clear that.
50 web_cache::WebCacheManager::GetInstance()->Remove(render_process_id
);
51 web_cache::WebCacheManager::GetInstance()->ClearCacheForProcess(
54 content::StoragePartition
* partition
=
55 content::BrowserContext::GetStoragePartition(
56 guest_web_contents()->GetBrowserContext(),
57 guest_web_contents()->GetSiteInstance());
59 // StoragePartitionHttpCacheDataRemover removes itself when it is done.
60 // TODO(lazyboy): Once StoragePartitionHttpCacheDataRemover moves to
61 // components/, move |ClearCache| to WebViewGuest: http//crbug.com/471287.
62 browsing_data::StoragePartitionHttpCacheDataRemover::CreateForRange(
63 partition
, remove_since
, base::Time::Now())->Remove(done_callback
);
66 bool ChromeWebViewGuestDelegate::HandleContextMenu(
67 const content::ContextMenuParams
& params
) {
68 ContextMenuDelegate
* menu_delegate
=
69 ContextMenuDelegate::FromWebContents(guest_web_contents());
70 DCHECK(menu_delegate
);
72 pending_menu_
= menu_delegate
->BuildMenu(guest_web_contents(), params
);
74 // Pass it to embedder.
75 int request_id
= ++pending_context_menu_request_id_
;
76 scoped_ptr
<base::DictionaryValue
> args(new base::DictionaryValue());
77 scoped_ptr
<base::ListValue
> items
=
78 MenuModelToValue(pending_menu_
->menu_model());
79 args
->Set(webview::kContextMenuItems
, items
.release());
80 args
->SetInteger(webview::kRequestId
, request_id
);
81 web_view_guest()->DispatchEventToView(
82 new GuestViewBase::Event(webview::kEventContextMenuShow
, args
.Pass()));
86 // TODO(hanxi) Investigate which of these observers should move to the
87 // extension module in the future.
88 void ChromeWebViewGuestDelegate::OnAttachWebViewHelpers(
89 content::WebContents
* contents
) {
90 FaviconTabHelper::CreateForWebContents(contents
);
91 ChromeExtensionWebContentsObserver::CreateForWebContents(contents
);
92 #if defined(ENABLE_PRINTING)
93 #if defined(ENABLE_PRINT_PREVIEW)
94 printing::PrintViewManager::CreateForWebContents(contents
);
95 printing::PrintPreviewMessageHandler::CreateForWebContents(contents
);
97 printing::PrintViewManagerBasic::CreateForWebContents(contents
);
98 #endif // defined(ENABLE_PRINT_PREVIEW)
99 #endif // defined(ENABLE_PRINTING)
100 pdf::PDFWebContentsHelper::CreateForWebContentsWithClient(
102 scoped_ptr
<pdf::PDFWebContentsHelperClient
>(
103 new ChromePDFWebContentsHelperClient()));
106 void ChromeWebViewGuestDelegate::OnDidCommitProvisionalLoadForFrame(
107 bool is_main_frame
) {
109 chromevox_injected_
= false;
112 void ChromeWebViewGuestDelegate::OnDidInitialize() {
113 #if defined(OS_CHROMEOS)
114 chromeos::AccessibilityManager
* accessibility_manager
=
115 chromeos::AccessibilityManager::Get();
116 CHECK(accessibility_manager
);
117 accessibility_subscription_
= accessibility_manager
->RegisterCallback(
118 base::Bind(&ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged
,
119 weak_ptr_factory_
.GetWeakPtr()));
123 void ChromeWebViewGuestDelegate::OnDocumentLoadedInFrame(
124 content::RenderFrameHost
* render_frame_host
) {
125 if (!render_frame_host
->GetParent())
126 InjectChromeVoxIfNeeded(render_frame_host
->GetRenderViewHost());
129 void ChromeWebViewGuestDelegate::OnGuestDestroyed() {
130 // Clean up custom context menu items for this guest.
131 MenuManager
* menu_manager
= MenuManager::Get(
132 Profile::FromBrowserContext(web_view_guest()->browser_context()));
133 menu_manager
->RemoveAllContextItems(MenuItem::ExtensionKey(
134 web_view_guest()->owner_extension_id(),
135 web_view_guest()->view_instance_id()));
139 scoped_ptr
<base::ListValue
> ChromeWebViewGuestDelegate::MenuModelToValue(
140 const ui::SimpleMenuModel
& menu_model
) {
141 scoped_ptr
<base::ListValue
> items(new base::ListValue());
142 for (int i
= 0; i
< menu_model
.GetItemCount(); ++i
) {
143 base::DictionaryValue
* item_value
= new base::DictionaryValue();
144 // TODO(lazyboy): We need to expose some kind of enum equivalent of
145 // |command_id| instead of plain integers.
146 item_value
->SetInteger(webview::kMenuItemCommandId
,
147 menu_model
.GetCommandIdAt(i
));
148 item_value
->SetString(webview::kMenuItemLabel
, menu_model
.GetLabelAt(i
));
149 items
->Append(item_value
);
154 void ChromeWebViewGuestDelegate::OnShowContextMenu(
156 const MenuItemVector
* items
) {
157 if (!pending_menu_
.get())
160 // Make sure this was the correct request.
161 if (request_id
!= pending_context_menu_request_id_
)
164 // TODO(lazyboy): Implement.
167 ContextMenuDelegate
* menu_delegate
=
168 ContextMenuDelegate::FromWebContents(guest_web_contents());
169 menu_delegate
->ShowMenu(pending_menu_
.Pass());
172 void ChromeWebViewGuestDelegate::InjectChromeVoxIfNeeded(
173 content::RenderViewHost
* render_view_host
) {
174 #if defined(OS_CHROMEOS)
175 if (!chromevox_injected_
) {
176 chromeos::AccessibilityManager
* manager
=
177 chromeos::AccessibilityManager::Get();
178 if (manager
&& manager
->IsSpokenFeedbackEnabled()) {
179 manager
->InjectChromeVox(render_view_host
);
180 chromevox_injected_
= true;
186 #if defined(OS_CHROMEOS)
187 void ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged(
188 const chromeos::AccessibilityStatusEventDetails
& details
) {
189 if (details
.notification_type
== chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN
) {
190 accessibility_subscription_
.reset();
191 } else if (details
.notification_type
==
192 chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
) {
194 InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost());
196 chromevox_injected_
= false;
201 } // namespace extensions