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 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() {
159 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() {
162 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest
* guest
) {
163 scoped_ptr
<webview::SetName::Params
> params(
164 webview::SetName::Params::Create(*args_
));
165 EXTENSION_FUNCTION_VALIDATE(params
.get());
166 guest
->SetName(params
->frame_name
);
171 WebViewInternalSetAllowTransparencyFunction::
172 WebViewInternalSetAllowTransparencyFunction() {
175 WebViewInternalSetAllowTransparencyFunction::
176 ~WebViewInternalSetAllowTransparencyFunction() {
179 bool WebViewInternalSetAllowTransparencyFunction::RunAsyncSafe(
180 WebViewGuest
* guest
) {
181 scoped_ptr
<webview::SetAllowTransparency::Params
> params(
182 webview::SetAllowTransparency::Params::Create(*args_
));
183 EXTENSION_FUNCTION_VALIDATE(params
.get());
184 guest
->SetAllowTransparency(params
->allow
);
189 WebViewInternalSetAllowScalingFunction::
190 WebViewInternalSetAllowScalingFunction() {
193 WebViewInternalSetAllowScalingFunction::
194 ~WebViewInternalSetAllowScalingFunction() {
197 bool WebViewInternalSetAllowScalingFunction::RunAsyncSafe(WebViewGuest
* guest
) {
198 scoped_ptr
<webview::SetAllowScaling::Params
> params(
199 webview::SetAllowScaling::Params::Create(*args_
));
200 EXTENSION_FUNCTION_VALIDATE(params
.get());
201 guest
->SetAllowScaling(params
->allow
);
206 WebViewInternalSetZoomFunction::WebViewInternalSetZoomFunction() {
209 WebViewInternalSetZoomFunction::~WebViewInternalSetZoomFunction() {
212 bool WebViewInternalSetZoomFunction::RunAsyncSafe(WebViewGuest
* guest
) {
213 scoped_ptr
<webview::SetZoom::Params
> params(
214 webview::SetZoom::Params::Create(*args_
));
215 EXTENSION_FUNCTION_VALIDATE(params
.get());
216 guest
->SetZoom(params
->zoom_factor
);
222 WebViewInternalGetZoomFunction::WebViewInternalGetZoomFunction() {
225 WebViewInternalGetZoomFunction::~WebViewInternalGetZoomFunction() {
228 bool WebViewInternalGetZoomFunction::RunAsyncSafe(WebViewGuest
* guest
) {
229 scoped_ptr
<webview::GetZoom::Params
> params(
230 webview::GetZoom::Params::Create(*args_
));
231 EXTENSION_FUNCTION_VALIDATE(params
.get());
233 double zoom_factor
= guest
->zoom();
234 SetResult(new base::FundamentalValue(zoom_factor
));
239 WebViewInternalFindFunction::WebViewInternalFindFunction() {
242 WebViewInternalFindFunction::~WebViewInternalFindFunction() {
245 bool WebViewInternalFindFunction::RunAsyncSafe(WebViewGuest
* guest
) {
246 scoped_ptr
<webview::Find::Params
> params(
247 webview::Find::Params::Create(*args_
));
248 EXTENSION_FUNCTION_VALIDATE(params
.get());
250 // Convert the std::string search_text to string16.
251 base::string16 search_text
;
253 params
->search_text
.c_str(), params
->search_text
.length(), &search_text
);
255 // Set the find options to their default values.
256 blink::WebFindOptions options
;
257 if (params
->options
) {
259 params
->options
->backward
? !*params
->options
->backward
: true;
261 params
->options
->match_case
? *params
->options
->match_case
: false;
264 guest
->StartFindInternal(search_text
, options
, this);
268 WebViewInternalStopFindingFunction::WebViewInternalStopFindingFunction() {
271 WebViewInternalStopFindingFunction::~WebViewInternalStopFindingFunction() {
274 bool WebViewInternalStopFindingFunction::RunAsyncSafe(WebViewGuest
* guest
) {
275 scoped_ptr
<webview::StopFinding::Params
> params(
276 webview::StopFinding::Params::Create(*args_
));
277 EXTENSION_FUNCTION_VALIDATE(params
.get());
279 // Set the StopFindAction.
280 content::StopFindAction action
;
281 switch (params
->action
) {
282 case webview::StopFinding::Params::ACTION_CLEAR
:
283 action
= content::STOP_FIND_ACTION_CLEAR_SELECTION
;
285 case webview::StopFinding::Params::ACTION_KEEP
:
286 action
= content::STOP_FIND_ACTION_KEEP_SELECTION
;
288 case webview::StopFinding::Params::ACTION_ACTIVATE
:
289 action
= content::STOP_FIND_ACTION_ACTIVATE_SELECTION
;
292 action
= content::STOP_FIND_ACTION_KEEP_SELECTION
;
295 guest
->StopFindingInternal(action
);
299 WebViewInternalLoadDataWithBaseUrlFunction::
300 WebViewInternalLoadDataWithBaseUrlFunction() {
303 WebViewInternalLoadDataWithBaseUrlFunction::
304 ~WebViewInternalLoadDataWithBaseUrlFunction() {
307 bool WebViewInternalLoadDataWithBaseUrlFunction::RunAsyncSafe(
308 WebViewGuest
* guest
) {
309 scoped_ptr
<webview::LoadDataWithBaseUrl::Params
> params(
310 webview::LoadDataWithBaseUrl::Params::Create(*args_
));
311 EXTENSION_FUNCTION_VALIDATE(params
.get());
313 // If a virtual URL was provided, use it. Otherwise, the user will be shown
315 std::string virtual_url
=
316 params
->virtual_url
? *params
->virtual_url
: params
->data_url
;
318 bool successful
= guest
->LoadDataWithBaseURL(
319 params
->data_url
, params
->base_url
, virtual_url
, &error_
);
320 SendResponse(successful
);
324 WebViewInternalGoFunction::WebViewInternalGoFunction() {
327 WebViewInternalGoFunction::~WebViewInternalGoFunction() {
330 bool WebViewInternalGoFunction::RunAsyncSafe(WebViewGuest
* guest
) {
331 scoped_ptr
<webview::Go::Params
> params(webview::Go::Params::Create(*args_
));
332 EXTENSION_FUNCTION_VALIDATE(params
.get());
334 bool successful
= guest
->Go(params
->relative_index
);
335 SetResult(new base::FundamentalValue(successful
));
340 WebViewInternalReloadFunction::WebViewInternalReloadFunction() {
343 WebViewInternalReloadFunction::~WebViewInternalReloadFunction() {
346 bool WebViewInternalReloadFunction::RunAsyncSafe(WebViewGuest
* guest
) {
351 WebViewInternalSetPermissionFunction::WebViewInternalSetPermissionFunction() {
354 WebViewInternalSetPermissionFunction::~WebViewInternalSetPermissionFunction() {
357 bool WebViewInternalSetPermissionFunction::RunAsyncSafe(WebViewGuest
* guest
) {
358 scoped_ptr
<webview::SetPermission::Params
> params(
359 webview::SetPermission::Params::Create(*args_
));
360 EXTENSION_FUNCTION_VALIDATE(params
.get());
362 WebViewPermissionHelper::PermissionResponseAction action
=
363 WebViewPermissionHelper::DEFAULT
;
364 switch (params
->action
) {
365 case Params::ACTION_ALLOW
:
366 action
= WebViewPermissionHelper::ALLOW
;
368 case Params::ACTION_DENY
:
369 action
= WebViewPermissionHelper::DENY
;
371 case Params::ACTION_DEFAULT
:
377 std::string user_input
;
378 if (params
->user_input
)
379 user_input
= *params
->user_input
;
381 WebViewPermissionHelper
* web_view_permission_helper
=
382 WebViewPermissionHelper::FromWebContents(guest
->web_contents());
384 WebViewPermissionHelper::SetPermissionResult result
=
385 web_view_permission_helper
->SetPermission(
386 params
->request_id
, action
, user_input
);
388 EXTENSION_FUNCTION_VALIDATE(result
!=
389 WebViewPermissionHelper::SET_PERMISSION_INVALID
);
391 SetResult(new base::FundamentalValue(
392 result
== WebViewPermissionHelper::SET_PERMISSION_ALLOWED
));
397 WebViewInternalOverrideUserAgentFunction::
398 WebViewInternalOverrideUserAgentFunction() {
401 WebViewInternalOverrideUserAgentFunction::
402 ~WebViewInternalOverrideUserAgentFunction() {
405 bool WebViewInternalOverrideUserAgentFunction::RunAsyncSafe(
406 WebViewGuest
* guest
) {
407 scoped_ptr
<webview::OverrideUserAgent::Params
> params(
408 webview::OverrideUserAgent::Params::Create(*args_
));
409 EXTENSION_FUNCTION_VALIDATE(params
.get());
411 guest
->SetUserAgentOverride(params
->user_agent_override
);
415 WebViewInternalStopFunction::WebViewInternalStopFunction() {
418 WebViewInternalStopFunction::~WebViewInternalStopFunction() {
421 bool WebViewInternalStopFunction::RunAsyncSafe(WebViewGuest
* guest
) {
426 WebViewInternalTerminateFunction::WebViewInternalTerminateFunction() {
429 WebViewInternalTerminateFunction::~WebViewInternalTerminateFunction() {
432 bool WebViewInternalTerminateFunction::RunAsyncSafe(WebViewGuest
* guest
) {
437 WebViewInternalClearDataFunction::WebViewInternalClearDataFunction()
438 : remove_mask_(0), bad_message_(false) {
441 WebViewInternalClearDataFunction::~WebViewInternalClearDataFunction() {
444 // Parses the |dataToRemove| argument to generate the remove mask. Sets
445 // |bad_message_| (like EXTENSION_FUNCTION_VALIDATE would if this were a bool
446 // method) if 'dataToRemove' is not present.
447 uint32
WebViewInternalClearDataFunction::GetRemovalMask() {
448 base::DictionaryValue
* data_to_remove
;
449 if (!args_
->GetDictionary(2, &data_to_remove
)) {
454 uint32 remove_mask
= 0;
455 for (base::DictionaryValue::Iterator
i(*data_to_remove
); !i
.IsAtEnd();
457 bool selected
= false;
458 if (!i
.value().GetAsBoolean(&selected
)) {
463 remove_mask
|= MaskForKey(i
.key().c_str());
469 // TODO(lazyboy): Parameters in this extension function are similar (or a
470 // sub-set) to BrowsingDataRemoverFunction. How can we share this code?
471 bool WebViewInternalClearDataFunction::RunAsyncSafe(WebViewGuest
* guest
) {
472 // Grab the initial |options| parameter, and parse out the arguments.
473 base::DictionaryValue
* options
;
474 EXTENSION_FUNCTION_VALIDATE(args_
->GetDictionary(1, &options
));
477 // If |ms_since_epoch| isn't set, default it to 0.
478 double ms_since_epoch
;
479 if (!options
->GetDouble(kSinceKey
, &ms_since_epoch
)) {
483 // base::Time takes a double that represents seconds since epoch. JavaScript
484 // gives developers milliseconds, so do a quick conversion before populating
485 // the object. Also, Time::FromDoubleT converts double time 0 to empty Time
486 // object. So we need to do special handling here.
487 remove_since_
= (ms_since_epoch
== 0)
488 ? base::Time::UnixEpoch()
489 : base::Time::FromDoubleT(ms_since_epoch
/ 1000.0);
491 remove_mask_
= GetRemovalMask();
495 AddRef(); // Balanced below or in WebViewInternalClearDataFunction::Done().
497 bool scheduled
= false;
499 scheduled
= guest
->ClearData(
502 base::Bind(&WebViewInternalClearDataFunction::ClearDataDone
, this));
504 if (!remove_mask_
|| !scheduled
) {
506 Release(); // Balanced above.
510 // Will finish asynchronously.
514 void WebViewInternalClearDataFunction::ClearDataDone() {
515 Release(); // Balanced in RunAsync().
519 } // namespace extensions