Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / extensions / browser / api / guest_view / web_view / web_view_internal_api.cc
blobcee2f5ea0b9c61505800981b0fec2a3909eb1101
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/guest_view/web_view/web_view_internal_api.h"
7 #include "base/strings/string_number_conversions.h"
8 #include "base/strings/stringprintf.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "content/public/browser/browser_context.h"
11 #include "content/public/browser/render_frame_host.h"
12 #include "content/public/browser/render_process_host.h"
13 #include "content/public/browser/render_view_host.h"
14 #include "content/public/browser/web_contents.h"
15 #include "content/public/common/stop_find_action.h"
16 #include "content/public/common/url_fetcher.h"
17 #include "extensions/browser/guest_view/web_view/web_view_constants.h"
18 #include "extensions/browser/guest_view/web_view/web_view_content_script_manager.h"
19 #include "extensions/common/api/web_view_internal.h"
20 #include "extensions/common/error_utils.h"
21 #include "extensions/common/manifest_constants.h"
22 #include "extensions/common/permissions/permissions_data.h"
23 #include "extensions/common/user_script.h"
24 #include "third_party/WebKit/public/web/WebFindOptions.h"
26 using content::WebContents;
27 using extensions::ExtensionResource;
28 using extensions::api::web_view_internal::ContentScriptDetails;
29 using extensions::api::web_view_internal::InjectionItems;
30 using extensions::api::web_view_internal::SetPermission::Params;
31 using extensions::api::extension_types::InjectDetails;
32 using extensions::UserScript;
33 using ui_zoom::ZoomController;
34 // error messages for content scripts:
35 namespace errors = extensions::manifest_errors;
36 namespace web_view_internal = extensions::api::web_view_internal;
38 namespace {
40 const char kAppCacheKey[] = "appcache";
41 const char kCacheKey[] = "cache";
42 const char kCookiesKey[] = "cookies";
43 const char kFileSystemsKey[] = "fileSystems";
44 const char kIndexedDBKey[] = "indexedDB";
45 const char kLocalStorageKey[] = "localStorage";
46 const char kWebSQLKey[] = "webSQL";
47 const char kSinceKey[] = "since";
48 const char kLoadFileError[] = "Failed to load file: \"*\". ";
49 const char kViewInstanceIdError[] = "view_instance_id is missing.";
50 const char kDuplicatedContentScriptNamesError[] =
51 "The given content script name already exists.";
53 uint32 MaskForKey(const char* key) {
54 if (strcmp(key, kAppCacheKey) == 0)
55 return webview::WEB_VIEW_REMOVE_DATA_MASK_APPCACHE;
56 if (strcmp(key, kCacheKey) == 0)
57 return webview::WEB_VIEW_REMOVE_DATA_MASK_CACHE;
58 if (strcmp(key, kCookiesKey) == 0)
59 return webview::WEB_VIEW_REMOVE_DATA_MASK_COOKIES;
60 if (strcmp(key, kFileSystemsKey) == 0)
61 return webview::WEB_VIEW_REMOVE_DATA_MASK_FILE_SYSTEMS;
62 if (strcmp(key, kIndexedDBKey) == 0)
63 return webview::WEB_VIEW_REMOVE_DATA_MASK_INDEXEDDB;
64 if (strcmp(key, kLocalStorageKey) == 0)
65 return webview::WEB_VIEW_REMOVE_DATA_MASK_LOCAL_STORAGE;
66 if (strcmp(key, kWebSQLKey) == 0)
67 return webview::WEB_VIEW_REMOVE_DATA_MASK_WEBSQL;
68 return 0;
71 HostID GenerateHostIDFromEmbedder(const extensions::Extension* extension,
72 const content::WebContents* web_contents) {
73 if (extension)
74 return HostID(HostID::EXTENSIONS, extension->id());
76 if (web_contents && web_contents->GetWebUI()) {
77 const GURL& url = web_contents->GetSiteInstance()->GetSiteURL();
78 return HostID(HostID::WEBUI, url.spec());
80 NOTREACHED();
81 return HostID();
84 // Creates content script files when parsing InjectionItems of "js" or "css"
85 // proterties, and stores them in the |result|.
86 void AddScriptFiles(const GURL& owner_base_url,
87 const extensions::Extension* extension,
88 const InjectionItems& items,
89 UserScript::FileList* result) {
90 // files:
91 if (items.files) {
92 for (const std::string& relative : *items.files) {
93 GURL url = owner_base_url.Resolve(relative);
94 if (extension) {
95 ExtensionResource resource = extension->GetResource(relative);
96 result->push_back(UserScript::File(resource.extension_root(),
97 resource.relative_path(), url));
98 } else {
99 result->push_back(extensions::UserScript::File(base::FilePath(),
100 base::FilePath(), url));
104 // code:
105 if (items.code) {
106 extensions::UserScript::File file((base::FilePath()), (base::FilePath()),
107 GURL());
108 file.set_content(*items.code);
109 result->push_back(file);
113 // Parses the values stored in ContentScriptDetails, and constructs a
114 // UserScript.
115 bool ParseContentScript(const ContentScriptDetails& script_value,
116 const extensions::Extension* extension,
117 const GURL& owner_base_url,
118 UserScript* script,
119 std::string* error) {
120 // matches (required):
121 if (script_value.matches.empty())
122 return false;
124 // The default for WebUI is not having special access, but we can change that
125 // if needed.
126 bool allowed_everywhere = false;
127 if (extension &&
128 extensions::PermissionsData::CanExecuteScriptEverywhere(extension))
129 allowed_everywhere = true;
131 for (const std::string& match : script_value.matches) {
132 URLPattern pattern(UserScript::ValidUserScriptSchemes(allowed_everywhere));
133 if (pattern.Parse(match) != URLPattern::PARSE_SUCCESS) {
134 *error = errors::kInvalidMatches;
135 return false;
137 script->add_url_pattern(pattern);
140 // exclude_matches:
141 if (script_value.exclude_matches) {
142 const std::vector<std::string>& exclude_matches =
143 *(script_value.exclude_matches.get());
144 for (const std::string& exclude_match : exclude_matches) {
145 URLPattern pattern(
146 UserScript::ValidUserScriptSchemes(allowed_everywhere));
148 if (pattern.Parse(exclude_match) != URLPattern::PARSE_SUCCESS) {
149 *error = errors::kInvalidExcludeMatches;
150 return false;
152 script->add_exclude_url_pattern(pattern);
155 // run_at:
156 if (script_value.run_at) {
157 UserScript::RunLocation run_at = UserScript::UNDEFINED;
158 switch (script_value.run_at) {
159 case extensions::api::extension_types::RUN_AT_NONE:
160 case extensions::api::extension_types::RUN_AT_DOCUMENT_IDLE:
161 run_at = UserScript::DOCUMENT_IDLE;
162 break;
163 case extensions::api::extension_types::RUN_AT_DOCUMENT_START:
164 run_at = UserScript::DOCUMENT_START;
165 break;
166 case extensions::api::extension_types::RUN_AT_DOCUMENT_END:
167 run_at = UserScript::DOCUMENT_END;
168 break;
170 // The default for run_at is RUN_AT_DOCUMENT_IDLE.
171 script->set_run_location(run_at);
174 // match_about_blank:
175 if (script_value.match_about_blank)
176 script->set_match_about_blank(*script_value.match_about_blank);
178 // css:
179 if (script_value.css) {
180 AddScriptFiles(owner_base_url, extension, *script_value.css,
181 &script->css_scripts());
184 // js:
185 if (script_value.js) {
186 AddScriptFiles(owner_base_url, extension, *script_value.js,
187 &script->js_scripts());
190 // all_frames:
191 if (script_value.all_frames)
192 script->set_match_all_frames(*script_value.all_frames);
194 // include_globs:
195 if (script_value.include_globs) {
196 for (const std::string& glob : *script_value.include_globs)
197 script->add_glob(glob);
200 // exclude_globs:
201 if (script_value.exclude_globs) {
202 for (const std::string& glob : *script_value.exclude_globs)
203 script->add_exclude_glob(glob);
206 return true;
209 bool ParseContentScripts(
210 std::vector<linked_ptr<ContentScriptDetails>> content_script_list,
211 const extensions::Extension* extension,
212 const HostID& host_id,
213 bool incognito_enabled,
214 const GURL& owner_base_url,
215 std::set<UserScript>* result,
216 std::string* error) {
217 if (content_script_list.empty())
218 return false;
220 std::set<std::string> names;
221 for (const linked_ptr<ContentScriptDetails> script_value :
222 content_script_list) {
223 const std::string& name = script_value->name;
224 if (!names.insert(name).second) {
225 // The name was already in the list.
226 *error = kDuplicatedContentScriptNamesError;
227 return false;
230 UserScript script;
231 if (!ParseContentScript(*script_value, extension, owner_base_url, &script,
232 error))
233 return false;
235 script.set_id(UserScript::GenerateUserScriptID());
236 script.set_name(name);
237 script.set_incognito_enabled(incognito_enabled);
238 script.set_host_id(host_id);
239 script.set_consumer_instance_type(UserScript::WEBVIEW);
240 result->insert(script);
242 return true;
245 } // namespace
247 namespace extensions {
249 bool WebViewInternalExtensionFunction::RunAsync() {
250 int instance_id = 0;
251 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
252 WebViewGuest* guest = WebViewGuest::From(
253 render_frame_host()->GetProcess()->GetID(), instance_id);
254 if (!guest)
255 return false;
257 return RunAsyncSafe(guest);
260 bool WebViewInternalNavigateFunction::RunAsyncSafe(WebViewGuest* guest) {
261 scoped_ptr<web_view_internal::Navigate::Params> params(
262 web_view_internal::Navigate::Params::Create(*args_));
263 EXTENSION_FUNCTION_VALIDATE(params.get());
264 std::string src = params->src;
265 guest->NavigateGuest(src, true /* force_navigation */);
266 return true;
269 WebViewInternalExecuteCodeFunction::WebViewInternalExecuteCodeFunction()
270 : guest_instance_id_(0), guest_src_(GURL::EmptyGURL()) {
273 WebViewInternalExecuteCodeFunction::~WebViewInternalExecuteCodeFunction() {
276 bool WebViewInternalExecuteCodeFunction::Init() {
277 if (details_.get())
278 return true;
280 if (!args_->GetInteger(0, &guest_instance_id_))
281 return false;
283 if (!guest_instance_id_)
284 return false;
286 std::string src;
287 if (!args_->GetString(1, &src))
288 return false;
290 guest_src_ = GURL(src);
291 if (!guest_src_.is_valid())
292 return false;
294 base::DictionaryValue* details_value = NULL;
295 if (!args_->GetDictionary(2, &details_value))
296 return false;
297 scoped_ptr<InjectDetails> details(new InjectDetails());
298 if (!InjectDetails::Populate(*details_value, details.get()))
299 return false;
301 details_ = details.Pass();
303 if (extension()) {
304 set_host_id(HostID(HostID::EXTENSIONS, extension()->id()));
305 return true;
308 WebContents* web_contents = GetSenderWebContents();
309 if (web_contents && web_contents->GetWebUI()) {
310 const GURL& url = render_frame_host()->GetSiteInstance()->GetSiteURL();
311 set_host_id(HostID(HostID::WEBUI, url.spec()));
312 return true;
314 return false;
317 bool WebViewInternalExecuteCodeFunction::ShouldInsertCSS() const {
318 return false;
321 bool WebViewInternalExecuteCodeFunction::CanExecuteScriptOnPage() {
322 return true;
325 extensions::ScriptExecutor*
326 WebViewInternalExecuteCodeFunction::GetScriptExecutor() {
327 if (!render_frame_host() || !render_frame_host()->GetProcess())
328 return NULL;
329 WebViewGuest* guest = WebViewGuest::From(
330 render_frame_host()->GetProcess()->GetID(), guest_instance_id_);
331 if (!guest)
332 return NULL;
334 return guest->script_executor();
337 bool WebViewInternalExecuteCodeFunction::IsWebView() const {
338 return true;
341 const GURL& WebViewInternalExecuteCodeFunction::GetWebViewSrc() const {
342 return guest_src_;
345 bool WebViewInternalExecuteCodeFunction::LoadFileForWebUI(
346 const std::string& file_src,
347 const WebUIURLFetcher::WebUILoadFileCallback& callback) {
348 if (!render_frame_host() || !render_frame_host()->GetProcess())
349 return false;
350 WebViewGuest* guest = WebViewGuest::From(
351 render_frame_host()->GetProcess()->GetID(), guest_instance_id_);
352 if (!guest || host_id().type() != HostID::WEBUI)
353 return false;
355 GURL owner_base_url(guest->GetOwnerSiteURL().GetWithEmptyPath());
356 GURL file_url(owner_base_url.Resolve(file_src));
358 url_fetcher_.reset(new WebUIURLFetcher(
359 this->browser_context(), render_frame_host()->GetProcess()->GetID(),
360 render_view_host_do_not_use()->GetRoutingID(), file_url, callback));
361 url_fetcher_->Start();
362 return true;
365 bool WebViewInternalExecuteCodeFunction::LoadFile(const std::string& file) {
366 if (!extension()) {
367 if (LoadFileForWebUI(
368 *details_->file,
369 base::Bind(
370 &WebViewInternalExecuteCodeFunction::DidLoadAndLocalizeFile,
371 this, file)))
372 return true;
374 SendResponse(false);
375 error_ = ErrorUtils::FormatErrorMessage(kLoadFileError, file);
376 return false;
378 return ExecuteCodeFunction::LoadFile(file);
381 WebViewInternalExecuteScriptFunction::WebViewInternalExecuteScriptFunction() {
384 void WebViewInternalExecuteScriptFunction::OnExecuteCodeFinished(
385 const std::string& error,
386 const GURL& on_url,
387 const base::ListValue& result) {
388 if (error.empty())
389 SetResult(result.DeepCopy());
390 WebViewInternalExecuteCodeFunction::OnExecuteCodeFinished(
391 error, on_url, result);
394 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() {
397 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const {
398 return true;
401 WebViewInternalAddContentScriptsFunction::
402 WebViewInternalAddContentScriptsFunction() {
405 WebViewInternalAddContentScriptsFunction::
406 ~WebViewInternalAddContentScriptsFunction() {
409 ExecuteCodeFunction::ResponseAction
410 WebViewInternalAddContentScriptsFunction::Run() {
411 scoped_ptr<web_view_internal::AddContentScripts::Params> params(
412 web_view_internal::AddContentScripts::Params::Create(*args_));
413 EXTENSION_FUNCTION_VALIDATE(params.get());
415 if (!params->instance_id)
416 return RespondNow(Error(kViewInstanceIdError));
418 GURL owner_base_url(
419 render_frame_host()->GetSiteInstance()->GetSiteURL().GetWithEmptyPath());
420 std::set<UserScript> result;
422 content::WebContents* sender_web_contents = GetSenderWebContents();
423 HostID host_id = GenerateHostIDFromEmbedder(extension(), sender_web_contents);
424 bool incognito_enabled = browser_context()->IsOffTheRecord();
426 if (!ParseContentScripts(params->content_script_list, extension(), host_id,
427 incognito_enabled, owner_base_url, &result, &error_))
428 return RespondNow(Error(error_));
430 WebViewContentScriptManager* manager =
431 WebViewContentScriptManager::Get(browser_context());
432 DCHECK(manager);
434 manager->AddContentScripts(
435 sender_web_contents->GetRenderProcessHost()->GetID(),
436 render_view_host_do_not_use(), params->instance_id, host_id, result);
438 return RespondNow(NoArguments());
441 WebViewInternalRemoveContentScriptsFunction::
442 WebViewInternalRemoveContentScriptsFunction() {
445 WebViewInternalRemoveContentScriptsFunction::
446 ~WebViewInternalRemoveContentScriptsFunction() {
449 ExecuteCodeFunction::ResponseAction
450 WebViewInternalRemoveContentScriptsFunction::Run() {
451 scoped_ptr<web_view_internal::RemoveContentScripts::Params> params(
452 web_view_internal::RemoveContentScripts::Params::Create(*args_));
453 EXTENSION_FUNCTION_VALIDATE(params.get());
455 if (!params->instance_id)
456 return RespondNow(Error(kViewInstanceIdError));
458 WebViewContentScriptManager* manager =
459 WebViewContentScriptManager::Get(browser_context());
460 DCHECK(manager);
462 content::WebContents* sender_web_contents = GetSenderWebContents();
463 HostID host_id = GenerateHostIDFromEmbedder(extension(), sender_web_contents);
465 std::vector<std::string> script_name_list;
466 if (params->script_name_list)
467 script_name_list.swap(*params->script_name_list);
468 manager->RemoveContentScripts(
469 sender_web_contents->GetRenderProcessHost()->GetID(),
470 params->instance_id, host_id, script_name_list);
471 return RespondNow(NoArguments());
474 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() {
477 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() {
480 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest* guest) {
481 scoped_ptr<web_view_internal::SetName::Params> params(
482 web_view_internal::SetName::Params::Create(*args_));
483 EXTENSION_FUNCTION_VALIDATE(params.get());
484 guest->SetName(params->frame_name);
485 SendResponse(true);
486 return true;
489 WebViewInternalSetAllowTransparencyFunction::
490 WebViewInternalSetAllowTransparencyFunction() {
493 WebViewInternalSetAllowTransparencyFunction::
494 ~WebViewInternalSetAllowTransparencyFunction() {
497 bool WebViewInternalSetAllowTransparencyFunction::RunAsyncSafe(
498 WebViewGuest* guest) {
499 scoped_ptr<web_view_internal::SetAllowTransparency::Params> params(
500 web_view_internal::SetAllowTransparency::Params::Create(*args_));
501 EXTENSION_FUNCTION_VALIDATE(params.get());
502 guest->SetAllowTransparency(params->allow);
503 SendResponse(true);
504 return true;
507 WebViewInternalSetAllowScalingFunction::
508 WebViewInternalSetAllowScalingFunction() {
511 WebViewInternalSetAllowScalingFunction::
512 ~WebViewInternalSetAllowScalingFunction() {
515 bool WebViewInternalSetAllowScalingFunction::RunAsyncSafe(WebViewGuest* guest) {
516 scoped_ptr<web_view_internal::SetAllowScaling::Params> params(
517 web_view_internal::SetAllowScaling::Params::Create(*args_));
518 EXTENSION_FUNCTION_VALIDATE(params.get());
519 guest->SetAllowScaling(params->allow);
520 SendResponse(true);
521 return true;
524 WebViewInternalSetZoomFunction::WebViewInternalSetZoomFunction() {
527 WebViewInternalSetZoomFunction::~WebViewInternalSetZoomFunction() {
530 bool WebViewInternalSetZoomFunction::RunAsyncSafe(WebViewGuest* guest) {
531 scoped_ptr<web_view_internal::SetZoom::Params> params(
532 web_view_internal::SetZoom::Params::Create(*args_));
533 EXTENSION_FUNCTION_VALIDATE(params.get());
534 guest->SetZoom(params->zoom_factor);
536 SendResponse(true);
537 return true;
540 WebViewInternalGetZoomFunction::WebViewInternalGetZoomFunction() {
543 WebViewInternalGetZoomFunction::~WebViewInternalGetZoomFunction() {
546 bool WebViewInternalGetZoomFunction::RunAsyncSafe(WebViewGuest* guest) {
547 scoped_ptr<web_view_internal::GetZoom::Params> params(
548 web_view_internal::GetZoom::Params::Create(*args_));
549 EXTENSION_FUNCTION_VALIDATE(params.get());
551 double zoom_factor = guest->GetZoom();
552 SetResult(new base::FundamentalValue(zoom_factor));
553 SendResponse(true);
554 return true;
557 WebViewInternalSetZoomModeFunction::WebViewInternalSetZoomModeFunction() {
560 WebViewInternalSetZoomModeFunction::~WebViewInternalSetZoomModeFunction() {
563 bool WebViewInternalSetZoomModeFunction::RunAsyncSafe(WebViewGuest* guest) {
564 scoped_ptr<web_view_internal::SetZoomMode::Params> params(
565 web_view_internal::SetZoomMode::Params::Create(*args_));
566 EXTENSION_FUNCTION_VALIDATE(params.get());
568 ZoomController::ZoomMode zoom_mode = ZoomController::ZOOM_MODE_DEFAULT;
569 switch (params->zoom_mode) {
570 case web_view_internal::ZOOM_MODE_PER_ORIGIN:
571 zoom_mode = ZoomController::ZOOM_MODE_DEFAULT;
572 break;
573 case web_view_internal::ZOOM_MODE_PER_VIEW:
574 zoom_mode = ZoomController::ZOOM_MODE_ISOLATED;
575 break;
576 case web_view_internal::ZOOM_MODE_DISABLED:
577 zoom_mode = ZoomController::ZOOM_MODE_DISABLED;
578 break;
579 default:
580 NOTREACHED();
583 guest->SetZoomMode(zoom_mode);
585 SendResponse(true);
586 return true;
589 WebViewInternalGetZoomModeFunction::WebViewInternalGetZoomModeFunction() {
592 WebViewInternalGetZoomModeFunction::~WebViewInternalGetZoomModeFunction() {
595 bool WebViewInternalGetZoomModeFunction::RunAsyncSafe(WebViewGuest* guest) {
596 scoped_ptr<web_view_internal::GetZoomMode::Params> params(
597 web_view_internal::GetZoomMode::Params::Create(*args_));
598 EXTENSION_FUNCTION_VALIDATE(params.get());
600 web_view_internal::ZoomMode zoom_mode = web_view_internal::ZOOM_MODE_NONE;
601 switch (guest->GetZoomMode()) {
602 case ZoomController::ZOOM_MODE_DEFAULT:
603 zoom_mode = web_view_internal::ZOOM_MODE_PER_ORIGIN;
604 break;
605 case ZoomController::ZOOM_MODE_ISOLATED:
606 zoom_mode = web_view_internal::ZOOM_MODE_PER_VIEW;
607 break;
608 case ZoomController::ZOOM_MODE_DISABLED:
609 zoom_mode = web_view_internal::ZOOM_MODE_DISABLED;
610 break;
611 default:
612 NOTREACHED();
615 SetResult(new base::StringValue(web_view_internal::ToString(zoom_mode)));
616 SendResponse(true);
617 return true;
620 WebViewInternalFindFunction::WebViewInternalFindFunction() {
623 WebViewInternalFindFunction::~WebViewInternalFindFunction() {
626 bool WebViewInternalFindFunction::RunAsyncSafe(WebViewGuest* guest) {
627 scoped_ptr<web_view_internal::Find::Params> params(
628 web_view_internal::Find::Params::Create(*args_));
629 EXTENSION_FUNCTION_VALIDATE(params.get());
631 // Convert the std::string search_text to string16.
632 base::string16 search_text;
633 base::UTF8ToUTF16(
634 params->search_text.c_str(), params->search_text.length(), &search_text);
636 // Set the find options to their default values.
637 blink::WebFindOptions options;
638 if (params->options) {
639 options.forward =
640 params->options->backward ? !*params->options->backward : true;
641 options.matchCase =
642 params->options->match_case ? *params->options->match_case : false;
645 guest->StartFindInternal(search_text, options, this);
646 return true;
649 WebViewInternalStopFindingFunction::WebViewInternalStopFindingFunction() {
652 WebViewInternalStopFindingFunction::~WebViewInternalStopFindingFunction() {
655 bool WebViewInternalStopFindingFunction::RunAsyncSafe(WebViewGuest* guest) {
656 scoped_ptr<web_view_internal::StopFinding::Params> params(
657 web_view_internal::StopFinding::Params::Create(*args_));
658 EXTENSION_FUNCTION_VALIDATE(params.get());
660 // Set the StopFindAction.
661 content::StopFindAction action;
662 switch (params->action) {
663 case web_view_internal::STOP_FINDING_ACTION_CLEAR:
664 action = content::STOP_FIND_ACTION_CLEAR_SELECTION;
665 break;
666 case web_view_internal::STOP_FINDING_ACTION_KEEP:
667 action = content::STOP_FIND_ACTION_KEEP_SELECTION;
668 break;
669 case web_view_internal::STOP_FINDING_ACTION_ACTIVATE:
670 action = content::STOP_FIND_ACTION_ACTIVATE_SELECTION;
671 break;
672 default:
673 action = content::STOP_FIND_ACTION_KEEP_SELECTION;
676 guest->StopFindingInternal(action);
677 return true;
680 WebViewInternalLoadDataWithBaseUrlFunction::
681 WebViewInternalLoadDataWithBaseUrlFunction() {
684 WebViewInternalLoadDataWithBaseUrlFunction::
685 ~WebViewInternalLoadDataWithBaseUrlFunction() {
688 bool WebViewInternalLoadDataWithBaseUrlFunction::RunAsyncSafe(
689 WebViewGuest* guest) {
690 scoped_ptr<web_view_internal::LoadDataWithBaseUrl::Params> params(
691 web_view_internal::LoadDataWithBaseUrl::Params::Create(*args_));
692 EXTENSION_FUNCTION_VALIDATE(params.get());
694 // If a virtual URL was provided, use it. Otherwise, the user will be shown
695 // the data URL.
696 std::string virtual_url =
697 params->virtual_url ? *params->virtual_url : params->data_url;
699 bool successful = guest->LoadDataWithBaseURL(
700 params->data_url, params->base_url, virtual_url, &error_);
701 SendResponse(successful);
702 return successful;
705 WebViewInternalGoFunction::WebViewInternalGoFunction() {
708 WebViewInternalGoFunction::~WebViewInternalGoFunction() {
711 bool WebViewInternalGoFunction::RunAsyncSafe(WebViewGuest* guest) {
712 scoped_ptr<web_view_internal::Go::Params> params(
713 web_view_internal::Go::Params::Create(*args_));
714 EXTENSION_FUNCTION_VALIDATE(params.get());
716 bool successful = guest->Go(params->relative_index);
717 SetResult(new base::FundamentalValue(successful));
718 SendResponse(true);
719 return true;
722 WebViewInternalReloadFunction::WebViewInternalReloadFunction() {
725 WebViewInternalReloadFunction::~WebViewInternalReloadFunction() {
728 bool WebViewInternalReloadFunction::RunAsyncSafe(WebViewGuest* guest) {
729 guest->Reload();
730 return true;
733 WebViewInternalSetPermissionFunction::WebViewInternalSetPermissionFunction() {
736 WebViewInternalSetPermissionFunction::~WebViewInternalSetPermissionFunction() {
739 bool WebViewInternalSetPermissionFunction::RunAsyncSafe(WebViewGuest* guest) {
740 scoped_ptr<web_view_internal::SetPermission::Params> params(
741 web_view_internal::SetPermission::Params::Create(*args_));
742 EXTENSION_FUNCTION_VALIDATE(params.get());
744 WebViewPermissionHelper::PermissionResponseAction action =
745 WebViewPermissionHelper::DEFAULT;
746 switch (params->action) {
747 case api::web_view_internal::SET_PERMISSION_ACTION_ALLOW:
748 action = WebViewPermissionHelper::ALLOW;
749 break;
750 case api::web_view_internal::SET_PERMISSION_ACTION_DENY:
751 action = WebViewPermissionHelper::DENY;
752 break;
753 case api::web_view_internal::SET_PERMISSION_ACTION_DEFAULT:
754 break;
755 default:
756 NOTREACHED();
759 std::string user_input;
760 if (params->user_input)
761 user_input = *params->user_input;
763 WebViewPermissionHelper* web_view_permission_helper =
764 WebViewPermissionHelper::FromWebContents(guest->web_contents());
766 WebViewPermissionHelper::SetPermissionResult result =
767 web_view_permission_helper->SetPermission(
768 params->request_id, action, user_input);
770 EXTENSION_FUNCTION_VALIDATE(result !=
771 WebViewPermissionHelper::SET_PERMISSION_INVALID);
773 SetResult(new base::FundamentalValue(
774 result == WebViewPermissionHelper::SET_PERMISSION_ALLOWED));
775 SendResponse(true);
776 return true;
779 WebViewInternalOverrideUserAgentFunction::
780 WebViewInternalOverrideUserAgentFunction() {
783 WebViewInternalOverrideUserAgentFunction::
784 ~WebViewInternalOverrideUserAgentFunction() {
787 bool WebViewInternalOverrideUserAgentFunction::RunAsyncSafe(
788 WebViewGuest* guest) {
789 scoped_ptr<web_view_internal::OverrideUserAgent::Params> params(
790 web_view_internal::OverrideUserAgent::Params::Create(*args_));
791 EXTENSION_FUNCTION_VALIDATE(params.get());
793 guest->SetUserAgentOverride(params->user_agent_override);
794 return true;
797 WebViewInternalStopFunction::WebViewInternalStopFunction() {
800 WebViewInternalStopFunction::~WebViewInternalStopFunction() {
803 bool WebViewInternalStopFunction::RunAsyncSafe(WebViewGuest* guest) {
804 guest->Stop();
805 return true;
808 WebViewInternalTerminateFunction::WebViewInternalTerminateFunction() {
811 WebViewInternalTerminateFunction::~WebViewInternalTerminateFunction() {
814 bool WebViewInternalTerminateFunction::RunAsyncSafe(WebViewGuest* guest) {
815 guest->Terminate();
816 return true;
819 WebViewInternalClearDataFunction::WebViewInternalClearDataFunction()
820 : remove_mask_(0), bad_message_(false) {
823 WebViewInternalClearDataFunction::~WebViewInternalClearDataFunction() {
826 // Parses the |dataToRemove| argument to generate the remove mask. Sets
827 // |bad_message_| (like EXTENSION_FUNCTION_VALIDATE would if this were a bool
828 // method) if 'dataToRemove' is not present.
829 uint32 WebViewInternalClearDataFunction::GetRemovalMask() {
830 base::DictionaryValue* data_to_remove;
831 if (!args_->GetDictionary(2, &data_to_remove)) {
832 bad_message_ = true;
833 return 0;
836 uint32 remove_mask = 0;
837 for (base::DictionaryValue::Iterator i(*data_to_remove); !i.IsAtEnd();
838 i.Advance()) {
839 bool selected = false;
840 if (!i.value().GetAsBoolean(&selected)) {
841 bad_message_ = true;
842 return 0;
844 if (selected)
845 remove_mask |= MaskForKey(i.key().c_str());
848 return remove_mask;
851 // TODO(lazyboy): Parameters in this extension function are similar (or a
852 // sub-set) to BrowsingDataRemoverFunction. How can we share this code?
853 bool WebViewInternalClearDataFunction::RunAsyncSafe(WebViewGuest* guest) {
854 // Grab the initial |options| parameter, and parse out the arguments.
855 base::DictionaryValue* options;
856 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options));
857 DCHECK(options);
859 // If |ms_since_epoch| isn't set, default it to 0.
860 double ms_since_epoch;
861 if (!options->GetDouble(kSinceKey, &ms_since_epoch)) {
862 ms_since_epoch = 0;
865 // base::Time takes a double that represents seconds since epoch. JavaScript
866 // gives developers milliseconds, so do a quick conversion before populating
867 // the object. Also, Time::FromDoubleT converts double time 0 to empty Time
868 // object. So we need to do special handling here.
869 remove_since_ = (ms_since_epoch == 0)
870 ? base::Time::UnixEpoch()
871 : base::Time::FromDoubleT(ms_since_epoch / 1000.0);
873 remove_mask_ = GetRemovalMask();
874 if (bad_message_)
875 return false;
877 AddRef(); // Balanced below or in WebViewInternalClearDataFunction::Done().
879 bool scheduled = false;
880 if (remove_mask_) {
881 scheduled = guest->ClearData(
882 remove_since_,
883 remove_mask_,
884 base::Bind(&WebViewInternalClearDataFunction::ClearDataDone, this));
886 if (!remove_mask_ || !scheduled) {
887 SendResponse(false);
888 Release(); // Balanced above.
889 return false;
892 // Will finish asynchronously.
893 return true;
896 void WebViewInternalClearDataFunction::ClearDataDone() {
897 Release(); // Balanced in RunAsync().
898 SendResponse(true);
901 } // namespace extensions