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/api/web_view/web_view_internal_api.h"
7 #include "base/strings/stringprintf.h"
8 #include "base/strings/utf_string_conversions.h"
9 #include "content/public/browser/render_process_host.h"
10 #include "content/public/browser/render_view_host.h"
11 #include "content/public/browser/storage_partition.h"
12 #include "content/public/browser/web_contents.h"
13 #include "content/public/common/stop_find_action.h"
14 #include "extensions/common/api/web_view_internal.h"
15 #include "third_party/WebKit/public/web/WebFindOptions.h"
17 using content::WebContents
;
18 using extensions::core_api::web_view_internal::SetPermission::Params
;
19 using extensions::core_api::extension_types::InjectDetails
;
20 namespace webview
= extensions::core_api::web_view_internal
;
24 const char kAppCacheKey
[] = "appcache";
25 const char kCookiesKey
[] = "cookies";
26 const char kFileSystemsKey
[] = "fileSystems";
27 const char kIndexedDBKey
[] = "indexedDB";
28 const char kLocalStorageKey
[] = "localStorage";
29 const char kWebSQLKey
[] = "webSQL";
30 const char kSinceKey
[] = "since";
32 int MaskForKey(const char* key
) {
33 if (strcmp(key
, kAppCacheKey
) == 0)
34 return content::StoragePartition::REMOVE_DATA_MASK_APPCACHE
;
35 if (strcmp(key
, kCookiesKey
) == 0)
36 return content::StoragePartition::REMOVE_DATA_MASK_COOKIES
;
37 if (strcmp(key
, kFileSystemsKey
) == 0)
38 return content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS
;
39 if (strcmp(key
, kIndexedDBKey
) == 0)
40 return content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB
;
41 if (strcmp(key
, kLocalStorageKey
) == 0)
42 return content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE
;
43 if (strcmp(key
, kWebSQLKey
) == 0)
44 return content::StoragePartition::REMOVE_DATA_MASK_WEBSQL
;
50 namespace extensions
{
52 bool WebViewInternalExtensionFunction::RunAsync() {
54 EXTENSION_FUNCTION_VALIDATE(args_
->GetInteger(0, &instance_id
));
55 WebViewGuest
* guest
= WebViewGuest::From(
56 render_view_host()->GetProcess()->GetID(), instance_id
);
60 return RunAsyncSafe(guest
);
63 bool WebViewInternalNavigateFunction::RunAsyncSafe(WebViewGuest
* guest
) {
64 scoped_ptr
<webview::Navigate::Params
> params(
65 webview::Navigate::Params::Create(*args_
));
66 EXTENSION_FUNCTION_VALIDATE(params
.get());
67 std::string src
= params
->src
;
68 guest
->NavigateGuest(src
, true /* force_navigation */);
72 WebViewInternalExecuteCodeFunction::WebViewInternalExecuteCodeFunction()
73 : guest_instance_id_(0), guest_src_(GURL::EmptyGURL()) {
76 WebViewInternalExecuteCodeFunction::~WebViewInternalExecuteCodeFunction() {
79 bool WebViewInternalExecuteCodeFunction::Init() {
83 if (!args_
->GetInteger(0, &guest_instance_id_
))
86 if (!guest_instance_id_
)
90 if (!args_
->GetString(1, &src
))
93 guest_src_
= GURL(src
);
94 if (!guest_src_
.is_valid())
97 base::DictionaryValue
* details_value
= NULL
;
98 if (!args_
->GetDictionary(2, &details_value
))
100 scoped_ptr
<InjectDetails
> details(new InjectDetails());
101 if (!InjectDetails::Populate(*details_value
, details
.get()))
104 details_
= details
.Pass();
108 bool WebViewInternalExecuteCodeFunction::ShouldInsertCSS() const {
112 bool WebViewInternalExecuteCodeFunction::CanExecuteScriptOnPage() {
116 extensions::ScriptExecutor
*
117 WebViewInternalExecuteCodeFunction::GetScriptExecutor() {
118 if (!render_view_host() || !render_view_host()->GetProcess())
120 WebViewGuest
* guest
= WebViewGuest::From(
121 render_view_host()->GetProcess()->GetID(), guest_instance_id_
);
125 return guest
->script_executor();
128 bool WebViewInternalExecuteCodeFunction::IsWebView() const {
132 const GURL
& WebViewInternalExecuteCodeFunction::GetWebViewSrc() const {
136 WebViewInternalExecuteScriptFunction::WebViewInternalExecuteScriptFunction() {
139 void WebViewInternalExecuteScriptFunction::OnExecuteCodeFinished(
140 const std::string
& error
,
142 const base::ListValue
& result
) {
144 SetResult(result
.DeepCopy());
145 WebViewInternalExecuteCodeFunction::OnExecuteCodeFinished(
146 error
, on_url
, result
);
149 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() {
152 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const {
156 WebViewInternalCaptureVisibleRegionFunction::
157 WebViewInternalCaptureVisibleRegionFunction() {
160 WebViewInternalCaptureVisibleRegionFunction::
161 ~WebViewInternalCaptureVisibleRegionFunction() {
164 bool WebViewInternalCaptureVisibleRegionFunction::IsScreenshotEnabled() {
168 WebContents
* WebViewInternalCaptureVisibleRegionFunction::GetWebContentsForID(
170 WebViewGuest
* guest
= WebViewGuest::From(
171 render_view_host()->GetProcess()->GetID(), instance_id
);
172 return guest
? guest
->web_contents() : NULL
;
175 void WebViewInternalCaptureVisibleRegionFunction::OnCaptureFailure(
176 FailureReason reason
) {
180 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() {
183 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() {
186 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest
* guest
) {
187 scoped_ptr
<webview::SetName::Params
> params(
188 webview::SetName::Params::Create(*args_
));
189 EXTENSION_FUNCTION_VALIDATE(params
.get());
190 guest
->SetName(params
->frame_name
);
195 WebViewInternalSetAllowTransparencyFunction::
196 WebViewInternalSetAllowTransparencyFunction() {
199 WebViewInternalSetAllowTransparencyFunction::
200 ~WebViewInternalSetAllowTransparencyFunction() {
203 bool WebViewInternalSetAllowTransparencyFunction::RunAsyncSafe(
204 WebViewGuest
* guest
) {
205 scoped_ptr
<webview::SetAllowTransparency::Params
> params(
206 webview::SetAllowTransparency::Params::Create(*args_
));
207 EXTENSION_FUNCTION_VALIDATE(params
.get());
208 guest
->SetAllowTransparency(params
->allow
);
213 WebViewInternalSetZoomFunction::WebViewInternalSetZoomFunction() {
216 WebViewInternalSetZoomFunction::~WebViewInternalSetZoomFunction() {
219 bool WebViewInternalSetZoomFunction::RunAsyncSafe(WebViewGuest
* guest
) {
220 scoped_ptr
<webview::SetZoom::Params
> params(
221 webview::SetZoom::Params::Create(*args_
));
222 EXTENSION_FUNCTION_VALIDATE(params
.get());
223 guest
->SetZoom(params
->zoom_factor
);
229 WebViewInternalGetZoomFunction::WebViewInternalGetZoomFunction() {
232 WebViewInternalGetZoomFunction::~WebViewInternalGetZoomFunction() {
235 bool WebViewInternalGetZoomFunction::RunAsyncSafe(WebViewGuest
* guest
) {
236 scoped_ptr
<webview::GetZoom::Params
> params(
237 webview::GetZoom::Params::Create(*args_
));
238 EXTENSION_FUNCTION_VALIDATE(params
.get());
240 double zoom_factor
= guest
->GetZoom();
241 SetResult(new base::FundamentalValue(zoom_factor
));
246 WebViewInternalFindFunction::WebViewInternalFindFunction() {
249 WebViewInternalFindFunction::~WebViewInternalFindFunction() {
252 bool WebViewInternalFindFunction::RunAsyncSafe(WebViewGuest
* guest
) {
253 scoped_ptr
<webview::Find::Params
> params(
254 webview::Find::Params::Create(*args_
));
255 EXTENSION_FUNCTION_VALIDATE(params
.get());
257 // Convert the std::string search_text to string16.
258 base::string16 search_text
;
260 params
->search_text
.c_str(), params
->search_text
.length(), &search_text
);
262 // Set the find options to their default values.
263 blink::WebFindOptions options
;
264 if (params
->options
) {
266 params
->options
->backward
? !*params
->options
->backward
: true;
268 params
->options
->match_case
? *params
->options
->match_case
: false;
271 guest
->StartFinding(search_text
, options
, this);
275 WebViewInternalStopFindingFunction::WebViewInternalStopFindingFunction() {
278 WebViewInternalStopFindingFunction::~WebViewInternalStopFindingFunction() {
281 bool WebViewInternalStopFindingFunction::RunAsyncSafe(WebViewGuest
* guest
) {
282 scoped_ptr
<webview::StopFinding::Params
> params(
283 webview::StopFinding::Params::Create(*args_
));
284 EXTENSION_FUNCTION_VALIDATE(params
.get());
286 // Set the StopFindAction.
287 content::StopFindAction action
;
288 switch (params
->action
) {
289 case webview::StopFinding::Params::ACTION_CLEAR
:
290 action
= content::STOP_FIND_ACTION_CLEAR_SELECTION
;
292 case webview::StopFinding::Params::ACTION_KEEP
:
293 action
= content::STOP_FIND_ACTION_KEEP_SELECTION
;
295 case webview::StopFinding::Params::ACTION_ACTIVATE
:
296 action
= content::STOP_FIND_ACTION_ACTIVATE_SELECTION
;
299 action
= content::STOP_FIND_ACTION_KEEP_SELECTION
;
302 guest
->StopFinding(action
);
306 WebViewInternalLoadDataWithBaseUrlFunction::
307 WebViewInternalLoadDataWithBaseUrlFunction() {
310 WebViewInternalLoadDataWithBaseUrlFunction::
311 ~WebViewInternalLoadDataWithBaseUrlFunction() {
314 bool WebViewInternalLoadDataWithBaseUrlFunction::RunAsyncSafe(
315 WebViewGuest
* guest
) {
316 scoped_ptr
<webview::LoadDataWithBaseUrl::Params
> params(
317 webview::LoadDataWithBaseUrl::Params::Create(*args_
));
318 EXTENSION_FUNCTION_VALIDATE(params
.get());
320 // If a virtual URL was provided, use it. Otherwise, the user will be shown
322 std::string virtual_url
=
323 params
->virtual_url
? *params
->virtual_url
: params
->data_url
;
325 bool successful
= guest
->LoadDataWithBaseURL(
326 params
->data_url
, params
->base_url
, virtual_url
, &error_
);
327 SendResponse(successful
);
331 WebViewInternalGoFunction::WebViewInternalGoFunction() {
334 WebViewInternalGoFunction::~WebViewInternalGoFunction() {
337 bool WebViewInternalGoFunction::RunAsyncSafe(WebViewGuest
* guest
) {
338 scoped_ptr
<webview::Go::Params
> params(webview::Go::Params::Create(*args_
));
339 EXTENSION_FUNCTION_VALIDATE(params
.get());
341 bool successful
= guest
->Go(params
->relative_index
);
342 SetResult(new base::FundamentalValue(successful
));
347 WebViewInternalReloadFunction::WebViewInternalReloadFunction() {
350 WebViewInternalReloadFunction::~WebViewInternalReloadFunction() {
353 bool WebViewInternalReloadFunction::RunAsyncSafe(WebViewGuest
* guest
) {
358 WebViewInternalSetPermissionFunction::WebViewInternalSetPermissionFunction() {
361 WebViewInternalSetPermissionFunction::~WebViewInternalSetPermissionFunction() {
364 bool WebViewInternalSetPermissionFunction::RunAsyncSafe(WebViewGuest
* guest
) {
365 scoped_ptr
<webview::SetPermission::Params
> params(
366 webview::SetPermission::Params::Create(*args_
));
367 EXTENSION_FUNCTION_VALIDATE(params
.get());
369 WebViewPermissionHelper::PermissionResponseAction action
=
370 WebViewPermissionHelper::DEFAULT
;
371 switch (params
->action
) {
372 case Params::ACTION_ALLOW
:
373 action
= WebViewPermissionHelper::ALLOW
;
375 case Params::ACTION_DENY
:
376 action
= WebViewPermissionHelper::DENY
;
378 case Params::ACTION_DEFAULT
:
384 std::string user_input
;
385 if (params
->user_input
)
386 user_input
= *params
->user_input
;
388 WebViewPermissionHelper
* web_view_permission_helper
=
389 WebViewPermissionHelper::FromWebContents(guest
->web_contents());
391 WebViewPermissionHelper::SetPermissionResult result
=
392 web_view_permission_helper
->SetPermission(
393 params
->request_id
, action
, user_input
);
395 EXTENSION_FUNCTION_VALIDATE(result
!=
396 WebViewPermissionHelper::SET_PERMISSION_INVALID
);
398 SetResult(new base::FundamentalValue(
399 result
== WebViewPermissionHelper::SET_PERMISSION_ALLOWED
));
404 WebViewInternalOverrideUserAgentFunction::
405 WebViewInternalOverrideUserAgentFunction() {
408 WebViewInternalOverrideUserAgentFunction::
409 ~WebViewInternalOverrideUserAgentFunction() {
412 bool WebViewInternalOverrideUserAgentFunction::RunAsyncSafe(
413 WebViewGuest
* guest
) {
414 scoped_ptr
<webview::OverrideUserAgent::Params
> params(
415 webview::OverrideUserAgent::Params::Create(*args_
));
416 EXTENSION_FUNCTION_VALIDATE(params
.get());
418 guest
->SetUserAgentOverride(params
->user_agent_override
);
422 WebViewInternalStopFunction::WebViewInternalStopFunction() {
425 WebViewInternalStopFunction::~WebViewInternalStopFunction() {
428 bool WebViewInternalStopFunction::RunAsyncSafe(WebViewGuest
* guest
) {
433 WebViewInternalTerminateFunction::WebViewInternalTerminateFunction() {
436 WebViewInternalTerminateFunction::~WebViewInternalTerminateFunction() {
439 bool WebViewInternalTerminateFunction::RunAsyncSafe(WebViewGuest
* guest
) {
444 WebViewInternalClearDataFunction::WebViewInternalClearDataFunction()
445 : remove_mask_(0), bad_message_(false) {
448 WebViewInternalClearDataFunction::~WebViewInternalClearDataFunction() {
451 // Parses the |dataToRemove| argument to generate the remove mask. Sets
452 // |bad_message_| (like EXTENSION_FUNCTION_VALIDATE would if this were a bool
453 // method) if 'dataToRemove' is not present.
454 uint32
WebViewInternalClearDataFunction::GetRemovalMask() {
455 base::DictionaryValue
* data_to_remove
;
456 if (!args_
->GetDictionary(2, &data_to_remove
)) {
461 uint32 remove_mask
= 0;
462 for (base::DictionaryValue::Iterator
i(*data_to_remove
); !i
.IsAtEnd();
464 bool selected
= false;
465 if (!i
.value().GetAsBoolean(&selected
)) {
470 remove_mask
|= MaskForKey(i
.key().c_str());
476 // TODO(lazyboy): Parameters in this extension function are similar (or a
477 // sub-set) to BrowsingDataRemoverFunction. How can we share this code?
478 bool WebViewInternalClearDataFunction::RunAsyncSafe(WebViewGuest
* guest
) {
479 // Grab the initial |options| parameter, and parse out the arguments.
480 base::DictionaryValue
* options
;
481 EXTENSION_FUNCTION_VALIDATE(args_
->GetDictionary(1, &options
));
484 // If |ms_since_epoch| isn't set, default it to 0.
485 double ms_since_epoch
;
486 if (!options
->GetDouble(kSinceKey
, &ms_since_epoch
)) {
490 // base::Time takes a double that represents seconds since epoch. JavaScript
491 // gives developers milliseconds, so do a quick conversion before populating
492 // the object. Also, Time::FromDoubleT converts double time 0 to empty Time
493 // object. So we need to do special handling here.
494 remove_since_
= (ms_since_epoch
== 0)
495 ? base::Time::UnixEpoch()
496 : base::Time::FromDoubleT(ms_since_epoch
/ 1000.0);
498 remove_mask_
= GetRemovalMask();
502 AddRef(); // Balanced below or in WebViewInternalClearDataFunction::Done().
504 bool scheduled
= false;
506 scheduled
= guest
->ClearData(
509 base::Bind(&WebViewInternalClearDataFunction::ClearDataDone
, this));
511 if (!remove_mask_
|| !scheduled
) {
513 Release(); // Balanced above.
517 // Will finish asynchronously.
521 void WebViewInternalClearDataFunction::ClearDataDone() {
522 Release(); // Balanced in RunAsync().
526 } // namespace extensions