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/renderer/extension_helper.h"
7 #include "content/public/renderer/render_view.h"
8 #include "content/public/renderer/render_view_visitor.h"
9 #include "extensions/common/constants.h"
10 #include "extensions/common/extension_messages.h"
11 #include "extensions/common/permissions/permissions_data.h"
12 #include "extensions/common/url_pattern_set.h"
13 #include "extensions/renderer/api/automation/automation_api_helper.h"
14 #include "extensions/renderer/console.h"
15 #include "extensions/renderer/dispatcher.h"
16 #include "third_party/WebKit/public/platform/WebURLRequest.h"
17 #include "third_party/WebKit/public/web/WebConsoleMessage.h"
18 #include "third_party/WebKit/public/web/WebDocument.h"
19 #include "third_party/WebKit/public/web/WebLocalFrame.h"
20 #include "third_party/WebKit/public/web/WebView.h"
22 using content::ConsoleMessageLevel
;
23 using blink::WebConsoleMessage
;
24 using blink::WebDataSource
;
25 using blink::WebFrame
;
26 using blink::WebLocalFrame
;
27 using blink::WebURLRequest
;
30 namespace extensions
{
34 // A RenderViewVisitor class that iterates through the set of available
35 // views, looking for a view of the given type, in the given browser window
36 // and within the given extension.
37 // Used to accumulate the list of views associated with an extension.
38 class ViewAccumulator
: public content::RenderViewVisitor
{
40 ViewAccumulator(const std::string
& extension_id
,
41 int browser_window_id
,
43 : extension_id_(extension_id
),
44 browser_window_id_(browser_window_id
),
45 view_type_(view_type
) {
48 std::vector
<content::RenderView
*> views() { return views_
; }
50 // Returns false to terminate the iteration.
51 bool Visit(content::RenderView
* render_view
) override
{
52 ExtensionHelper
* helper
= ExtensionHelper::Get(render_view
);
53 if (!ViewTypeMatches(helper
->view_type(), view_type_
))
56 GURL url
= render_view
->GetWebView()->mainFrame()->document().url();
57 if (!url
.SchemeIs(kExtensionScheme
))
59 const std::string
& extension_id
= url
.host();
60 if (extension_id
!= extension_id_
)
63 if (browser_window_id_
!= extension_misc::kUnknownWindowId
&&
64 helper
->browser_window_id() != browser_window_id_
) {
68 views_
.push_back(render_view
);
70 if (view_type_
== VIEW_TYPE_EXTENSION_BACKGROUND_PAGE
)
71 return false; // There can be only one...
76 // Returns true if |type| "isa" |match|.
77 static bool ViewTypeMatches(ViewType type
, ViewType match
) {
81 // INVALID means match all.
82 if (match
== VIEW_TYPE_INVALID
)
88 std::string extension_id_
;
89 int browser_window_id_
;
91 std::vector
<content::RenderView
*> views_
;
97 std::vector
<content::RenderView
*> ExtensionHelper::GetExtensionViews(
98 const std::string
& extension_id
,
99 int browser_window_id
,
100 ViewType view_type
) {
101 ViewAccumulator
accumulator(extension_id
, browser_window_id
, view_type
);
102 content::RenderView::ForEach(&accumulator
);
103 return accumulator
.views();
107 content::RenderView
* ExtensionHelper::GetBackgroundPage(
108 const std::string
& extension_id
) {
109 ViewAccumulator
accumulator(extension_id
, extension_misc::kUnknownWindowId
,
110 VIEW_TYPE_EXTENSION_BACKGROUND_PAGE
);
111 content::RenderView::ForEach(&accumulator
);
112 CHECK_LE(accumulator
.views().size(), 1u);
113 if (accumulator
.views().size() == 0)
115 return accumulator
.views()[0];
118 ExtensionHelper::ExtensionHelper(content::RenderView
* render_view
,
119 Dispatcher
* dispatcher
)
120 : content::RenderViewObserver(render_view
),
121 content::RenderViewObserverTracker
<ExtensionHelper
>(render_view
),
122 dispatcher_(dispatcher
),
123 view_type_(VIEW_TYPE_INVALID
),
124 browser_window_id_(-1) {
125 // Lifecycle managed by RenderViewObserver.
126 new AutomationApiHelper(render_view
);
129 ExtensionHelper::~ExtensionHelper() {
132 bool ExtensionHelper::OnMessageReceived(const IPC::Message
& message
) {
134 IPC_BEGIN_MESSAGE_MAP(ExtensionHelper
, message
)
135 IPC_MESSAGE_HANDLER(ExtensionMsg_Response
, OnExtensionResponse
)
136 IPC_MESSAGE_HANDLER(ExtensionMsg_MessageInvoke
, OnExtensionMessageInvoke
)
137 IPC_MESSAGE_HANDLER(ExtensionMsg_SetFrameName
, OnSetFrameName
)
138 IPC_MESSAGE_HANDLER(ExtensionMsg_UpdateBrowserWindowId
,
139 OnUpdateBrowserWindowId
)
140 IPC_MESSAGE_HANDLER(ExtensionMsg_NotifyRenderViewType
,
141 OnNotifyRendererViewType
)
142 IPC_MESSAGE_HANDLER(ExtensionMsg_AddMessageToConsole
,
143 OnAddMessageToConsole
)
144 IPC_MESSAGE_HANDLER(ExtensionMsg_AppWindowClosed
,
146 IPC_MESSAGE_UNHANDLED(handled
= false)
147 IPC_END_MESSAGE_MAP()
151 void ExtensionHelper::DidCreateDocumentElement(WebLocalFrame
* frame
) {
152 dispatcher_
->DidCreateDocumentElement(frame
);
155 void ExtensionHelper::DraggableRegionsChanged(blink::WebFrame
* frame
) {
156 blink::WebVector
<blink::WebDraggableRegion
> webregions
=
157 frame
->document().draggableRegions();
158 std::vector
<DraggableRegion
> regions
;
159 for (size_t i
= 0; i
< webregions
.size(); ++i
) {
160 DraggableRegion region
;
161 region
.bounds
= webregions
[i
].bounds
;
162 region
.draggable
= webregions
[i
].draggable
;
163 regions
.push_back(region
);
165 Send(new ExtensionHostMsg_UpdateDraggableRegions(routing_id(), regions
));
168 void ExtensionHelper::DidMatchCSS(
169 blink::WebLocalFrame
* frame
,
170 const blink::WebVector
<blink::WebString
>& newly_matching_selectors
,
171 const blink::WebVector
<blink::WebString
>& stopped_matching_selectors
) {
172 dispatcher_
->DidMatchCSS(
173 frame
, newly_matching_selectors
, stopped_matching_selectors
);
176 void ExtensionHelper::OnExtensionResponse(int request_id
,
178 const base::ListValue
& response
,
179 const std::string
& error
) {
180 dispatcher_
->OnExtensionResponse(request_id
,
186 void ExtensionHelper::OnExtensionMessageInvoke(const std::string
& extension_id
,
187 const std::string
& module_name
,
188 const std::string
& function_name
,
189 const base::ListValue
& args
,
191 dispatcher_
->InvokeModuleSystemMethod(
192 render_view(), extension_id
, module_name
, function_name
, args
,
196 void ExtensionHelper::OnNotifyRendererViewType(ViewType type
) {
200 void ExtensionHelper::OnSetFrameName(const std::string
& name
) {
201 blink::WebView
* web_view
= render_view()->GetWebView();
203 web_view
->mainFrame()->setName(blink::WebString::fromUTF8(name
));
206 void ExtensionHelper::OnUpdateBrowserWindowId(int window_id
) {
207 browser_window_id_
= window_id
;
210 void ExtensionHelper::OnAddMessageToConsole(ConsoleMessageLevel level
,
211 const std::string
& message
) {
212 console::AddMessage(render_view(), level
, message
);
215 void ExtensionHelper::OnAppWindowClosed() {
216 v8::HandleScope
scope(v8::Isolate::GetCurrent());
217 v8::Local
<v8::Context
> v8_context
=
218 render_view()->GetWebView()->mainFrame()->mainWorldScriptContext();
219 ScriptContext
* script_context
=
220 dispatcher_
->script_context_set().GetByV8Context(v8_context
);
223 script_context
->module_system()->CallModuleMethod("app.window",
224 "onAppWindowClosed");
227 } // namespace extensions