Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / guest_view / mime_handler_view / mime_handler_view_guest.cc
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.
4
5 #include "extensions/browser/guest_view/mime_handler_view/mime_handler_view_guest.h"
6
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"
23
24 using content::WebContents;
25
26 namespace extensions {
27
28 // static
29 const char MimeHandlerViewGuest::Type[] = "mimehandler";
30
31 // static
32 GuestViewBase* MimeHandlerViewGuest::Create(
33     content::BrowserContext* browser_context,
34     int guest_instance_id) {
35   if (!extensions::FeatureSwitch::mime_handler_view()->IsEnabled())
36     return NULL;
37
38   return new MimeHandlerViewGuest(browser_context, guest_instance_id);
39 }
40
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(
46           this)) {
47 }
48
49 MimeHandlerViewGuest::~MimeHandlerViewGuest() {
50 }
51
52 WindowController* MimeHandlerViewGuest::GetExtensionWindowController() const {
53   return NULL;
54 }
55
56 WebContents* MimeHandlerViewGuest::GetAssociatedWebContents() const {
57   return web_contents();
58 }
59
60 const char* MimeHandlerViewGuest::GetAPINamespace() const {
61   return "mimeHandlerViewGuestInternal";
62 }
63
64 int MimeHandlerViewGuest::GetTaskPrefix() const {
65   return IDS_EXTENSION_TASK_MANAGER_MIMEHANDLERVIEW_TAG_PREFIX;
66 }
67
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());
78
79   std::string extension_src;
80   create_params.GetString(mime_handler_view::kSrc, &extension_src);
81   DCHECK(!extension_src.empty());
82
83   GURL mime_handler_extension_url(extension_src);
84   if (!mime_handler_extension_url.is_valid()) {
85     callback.Run(NULL);
86     return;
87   }
88
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 = "
96                << orig_mime_type;
97     callback.Run(NULL);
98     return;
99   }
100
101   ProcessManager* process_manager =
102       ExtensionSystem::Get(browser_context())->process_manager();
103   DCHECK(process_manager);
104
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));
110
111   WebContents::CreateParams params(browser_context(), guest_site_instance);
112   params.guest_delegate = this;
113   callback.Run(WebContents::Create(params));
114 }
115
116 void MimeHandlerViewGuest::DidAttachToEmbedder() {
117   std::string src;
118   bool success = attach_params()->GetString(mime_handler_view::kSrc, &src);
119   DCHECK(success && !src.empty());
120   web_contents()->GetController().LoadURL(
121       GURL(src),
122       content::Referrer(),
123       ui::PAGE_TRANSITION_AUTO_TOPLEVEL,
124       std::string());
125 }
126
127 void MimeHandlerViewGuest::DidInitialize() {
128   extension_function_dispatcher_.reset(
129       new ExtensionFunctionDispatcher(browser_context(), this));
130   if (delegate_)
131     delegate_->AttachHelpers();
132 }
133
134 void MimeHandlerViewGuest::ContentsZoomChange(bool zoom_in) {
135   if (delegate_)
136     delegate_->ChangeZoom(zoom_in);
137 }
138
139 void MimeHandlerViewGuest::HandleKeyboardEvent(
140     WebContents* source,
141     const content::NativeWebKeyboardEvent& event) {
142   if (!attached())
143     return;
144
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(),
152                                                               event);
153 }
154
155 bool MimeHandlerViewGuest::OnMessageReceived(const IPC::Message& message) {
156   bool handled = true;
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()
161   return handled;
162 }
163
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());
169   }
170 }
171
172 }  // namespace extensions