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.
5 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
7 #include "base/strings/stringprintf.h"
8 #include "content/public/browser/browser_thread.h"
9 #include "content/public/browser/render_process_host.h"
10 #include "content/public/common/url_constants.h"
11 #include "extensions/browser/api/extensions_api_client.h"
12 #include "extensions/browser/extension_registry.h"
13 #include "extensions/browser/extension_system.h"
14 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_constants.h"
15 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest_delegate.h"
16 #include "extensions/browser/process_manager.h"
17 #include "extensions/common/extension_messages.h"
18 #include "extensions/common/feature_switch.h"
19 #include "extensions/common/guest_view/guest_view_constants.h"
20 #include "extensions/strings/grit/extensions_strings.h"
21 #include "ipc/ipc_message_macros.h"
22 #include "net/base/url_util.h"
24 using content::WebContents
;
26 namespace extensions
{
29 const char MimeHandlerViewGuest::Type
[] = "mimehandler";
32 GuestViewBase
* MimeHandlerViewGuest::Create(
33 content::BrowserContext
* browser_context
,
34 int guest_instance_id
) {
35 if (!extensions::FeatureSwitch::mime_handler_view()->IsEnabled())
38 return new MimeHandlerViewGuest(browser_context
, guest_instance_id
);
41 MimeHandlerViewGuest::MimeHandlerViewGuest(
42 content::BrowserContext
* browser_context
,
43 int guest_instance_id
)
44 : GuestView
<MimeHandlerViewGuest
>(browser_context
, guest_instance_id
),
45 delegate_(ExtensionsAPIClient::Get()->CreateMimeHandlerViewGuestDelegate(
49 MimeHandlerViewGuest::~MimeHandlerViewGuest() {
52 WindowController
* MimeHandlerViewGuest::GetExtensionWindowController() const {
56 WebContents
* MimeHandlerViewGuest::GetAssociatedWebContents() const {
57 return web_contents();
60 const char* MimeHandlerViewGuest::GetAPINamespace() const {
61 return "mimeHandlerViewGuestInternal";
64 int MimeHandlerViewGuest::GetTaskPrefix() const {
65 return IDS_EXTENSION_TASK_MANAGER_MIMEHANDLERVIEW_TAG_PREFIX
;
68 // |embedder_extension_id| is empty for mime handler view.
69 void MimeHandlerViewGuest::CreateWebContents(
70 const std::string
& embedder_extension_id
,
71 int embedder_render_process_id
,
72 const GURL
& embedder_site_url
,
73 const base::DictionaryValue
& create_params
,
74 const WebContentsCreatedCallback
& callback
) {
75 std::string orig_mime_type
;
76 create_params
.GetString(mime_handler_view::kMimeType
, &orig_mime_type
);
77 DCHECK(!orig_mime_type
.empty());
79 std::string extension_src
;
80 create_params
.GetString(mime_handler_view::kSrc
, &extension_src
);
81 DCHECK(!extension_src
.empty());
83 GURL
mime_handler_extension_url(extension_src
);
84 if (!mime_handler_extension_url
.is_valid()) {
89 const Extension
* mime_handler_extension
=
90 // TODO(lazyboy): Do we need handle the case where the extension is
91 // terminated (ExtensionRegistry::TERMINATED)?
92 ExtensionRegistry::Get(browser_context())->enabled_extensions().GetByID(
93 mime_handler_extension_url
.host());
94 if (!mime_handler_extension
) {
95 LOG(ERROR
) << "Extension for mime_type not found, mime_type = "
101 ProcessManager
* process_manager
=
102 ExtensionSystem::Get(browser_context())->process_manager();
103 DCHECK(process_manager
);
105 // Use the mime handler extension's SiteInstance to create the guest so it
106 // goes under the same process as the extension.
107 content::SiteInstance
* guest_site_instance
=
108 process_manager
->GetSiteInstanceForURL(
109 Extension::GetBaseURLFromExtensionId(embedder_extension_id
));
111 WebContents::CreateParams
params(browser_context(), guest_site_instance
);
112 params
.guest_delegate
= this;
113 callback
.Run(WebContents::Create(params
));
116 void MimeHandlerViewGuest::DidAttachToEmbedder() {
118 bool success
= attach_params()->GetString(mime_handler_view::kSrc
, &src
);
119 DCHECK(success
&& !src
.empty());
120 web_contents()->GetController().LoadURL(
123 ui::PAGE_TRANSITION_AUTO_TOPLEVEL
,
127 void MimeHandlerViewGuest::DidInitialize() {
128 extension_function_dispatcher_
.reset(
129 new ExtensionFunctionDispatcher(browser_context(), this));
131 delegate_
->AttachHelpers();
134 void MimeHandlerViewGuest::ContentsZoomChange(bool zoom_in
) {
136 delegate_
->ChangeZoom(zoom_in
);
139 void MimeHandlerViewGuest::HandleKeyboardEvent(
141 const content::NativeWebKeyboardEvent
& event
) {
145 // Send the keyboard events back to the embedder to reprocess them.
146 // TODO(fsamuel): This introduces the possibility of out-of-order keyboard
147 // events because the guest may be arbitrarily delayed when responding to
148 // keyboard events. In that time, the embedder may have received and processed
149 // additional key events. This needs to be fixed as soon as possible.
150 // See http://crbug.com/229882.
151 embedder_web_contents()->GetDelegate()->HandleKeyboardEvent(web_contents(),
155 bool MimeHandlerViewGuest::OnMessageReceived(const IPC::Message
& message
) {
157 IPC_BEGIN_MESSAGE_MAP(MimeHandlerViewGuest
, message
)
158 IPC_MESSAGE_HANDLER(ExtensionHostMsg_Request
, OnRequest
)
159 IPC_MESSAGE_UNHANDLED(handled
= false)
160 IPC_END_MESSAGE_MAP()
164 void MimeHandlerViewGuest::OnRequest(
165 const ExtensionHostMsg_Request_Params
& params
) {
166 if (extension_function_dispatcher_
) {
167 extension_function_dispatcher_
->Dispatch(
168 params
, web_contents()->GetRenderViewHost());
172 } // namespace extensions