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_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/guest_view/browser/guest_view_event.h"
16 #include "components/renderer_context_menu/context_menu_delegate.h"
17 #include "content/public/browser/render_process_host.h"
18 #include "extensions/browser/api/web_request/web_request_api.h"
19 #include "extensions/browser/guest_view/web_view/web_view_constants.h"
21 using guest_view::GuestViewEvent
;
23 namespace extensions
{
25 ChromeWebViewGuestDelegate::ChromeWebViewGuestDelegate(
26 WebViewGuest
* web_view_guest
)
27 : pending_context_menu_request_id_(0),
28 chromevox_injected_(false),
29 web_view_guest_(web_view_guest
),
30 weak_ptr_factory_(this) {
33 ChromeWebViewGuestDelegate::~ChromeWebViewGuestDelegate() {
36 bool ChromeWebViewGuestDelegate::HandleContextMenu(
37 const content::ContextMenuParams
& params
) {
38 ContextMenuDelegate
* menu_delegate
=
39 ContextMenuDelegate::FromWebContents(guest_web_contents());
40 DCHECK(menu_delegate
);
42 pending_menu_
= menu_delegate
->BuildMenu(guest_web_contents(), params
);
43 // It's possible for the returned menu to be null, so early out to avoid
44 // a crash. TODO(wjmaclean): find out why it's possible for this to happen
45 // in the first place, and if it's an error.
49 // Pass it to embedder.
50 int request_id
= ++pending_context_menu_request_id_
;
51 scoped_ptr
<base::DictionaryValue
> args(new base::DictionaryValue());
52 scoped_ptr
<base::ListValue
> items
=
53 MenuModelToValue(pending_menu_
->menu_model());
54 args
->Set(webview::kContextMenuItems
, items
.release());
55 args
->SetInteger(webview::kRequestId
, request_id
);
56 web_view_guest()->DispatchEventToView(
57 new GuestViewEvent(webview::kEventContextMenuShow
, args
.Pass()));
61 void ChromeWebViewGuestDelegate::OnDidInitialize() {
62 #if defined(OS_CHROMEOS)
63 chromeos::AccessibilityManager
* accessibility_manager
=
64 chromeos::AccessibilityManager::Get();
65 CHECK(accessibility_manager
);
66 accessibility_subscription_
= accessibility_manager
->RegisterCallback(
67 base::Bind(&ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged
,
68 weak_ptr_factory_
.GetWeakPtr()));
72 void ChromeWebViewGuestDelegate::OnGuestDestroyed() {
73 // Clean up custom context menu items for this guest.
74 MenuManager
* menu_manager
= MenuManager::Get(
75 Profile::FromBrowserContext(web_view_guest()->browser_context()));
76 menu_manager
->RemoveAllContextItems(MenuItem::ExtensionKey(
77 web_view_guest()->owner_host(),
78 web_view_guest()->view_instance_id()));
82 scoped_ptr
<base::ListValue
> ChromeWebViewGuestDelegate::MenuModelToValue(
83 const ui::SimpleMenuModel
& menu_model
) {
84 scoped_ptr
<base::ListValue
> items(new base::ListValue());
85 for (int i
= 0; i
< menu_model
.GetItemCount(); ++i
) {
86 base::DictionaryValue
* item_value
= new base::DictionaryValue();
87 // TODO(lazyboy): We need to expose some kind of enum equivalent of
88 // |command_id| instead of plain integers.
89 item_value
->SetInteger(webview::kMenuItemCommandId
,
90 menu_model
.GetCommandIdAt(i
));
91 item_value
->SetString(webview::kMenuItemLabel
, menu_model
.GetLabelAt(i
));
92 items
->Append(item_value
);
97 void ChromeWebViewGuestDelegate::OnShowContextMenu(
99 const MenuItemVector
* items
) {
100 if (!pending_menu_
.get())
103 // Make sure this was the correct request.
104 if (request_id
!= pending_context_menu_request_id_
)
107 // TODO(lazyboy): Implement.
110 ContextMenuDelegate
* menu_delegate
=
111 ContextMenuDelegate::FromWebContents(guest_web_contents());
112 menu_delegate
->ShowMenu(pending_menu_
.Pass());
115 void ChromeWebViewGuestDelegate::InjectChromeVoxIfNeeded(
116 content::RenderViewHost
* render_view_host
) {
117 #if defined(OS_CHROMEOS)
118 if (!chromevox_injected_
) {
119 chromeos::AccessibilityManager
* manager
=
120 chromeos::AccessibilityManager::Get();
121 if (manager
&& manager
->IsSpokenFeedbackEnabled()) {
122 manager
->InjectChromeVox(render_view_host
);
123 chromevox_injected_
= true;
129 #if defined(OS_CHROMEOS)
130 void ChromeWebViewGuestDelegate::OnAccessibilityStatusChanged(
131 const chromeos::AccessibilityStatusEventDetails
& details
) {
132 if (details
.notification_type
== chromeos::ACCESSIBILITY_MANAGER_SHUTDOWN
) {
133 accessibility_subscription_
.reset();
134 } else if (details
.notification_type
==
135 chromeos::ACCESSIBILITY_TOGGLE_SPOKEN_FEEDBACK
) {
137 InjectChromeVoxIfNeeded(guest_web_contents()->GetRenderViewHost());
139 chromevox_injected_
= false;
144 } // namespace extensions