Don't show supervised user as "already on this device" while they're being imported.
[chromium-blink-merge.git] / extensions / browser / api / guest_view / web_view / web_view_internal_api.cc
blob56eb6d68d6119c74894480261c790bf849ac077a
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_process_host.h"
12 #include "content/public/browser/render_view_host.h"
13 #include "content/public/browser/web_contents.h"
14 #include "content/public/common/stop_find_action.h"
15 #include "content/public/common/url_fetcher.h"
16 #include "extensions/browser/guest_view/web_view/web_view_constants.h"
17 #include "extensions/browser/guest_view/web_view/web_view_content_script_manager.h"
18 #include "extensions/common/api/web_view_internal.h"
19 #include "extensions/common/error_utils.h"
20 #include "extensions/common/manifest_constants.h"
21 #include "extensions/common/permissions/permissions_data.h"
22 #include "extensions/common/user_script.h"
23 #include "third_party/WebKit/public/web/WebFindOptions.h"
25 using content::WebContents;
26 using extensions::ExtensionResource;
27 using extensions::core_api::web_view_internal::ContentScriptDetails;
28 using extensions::core_api::web_view_internal::InjectionItems;
29 using extensions::core_api::web_view_internal::SetPermission::Params;
30 using extensions::core_api::extension_types::InjectDetails;
31 using extensions::UserScript;
32 using ui_zoom::ZoomController;
33 // error messages for content scripts:
34 namespace errors = extensions::manifest_errors;
35 namespace web_view_internal = extensions::core_api::web_view_internal;
37 namespace {
39 const char kAppCacheKey[] = "appcache";
40 const char kCacheKey[] = "cache";
41 const char kCookiesKey[] = "cookies";
42 const char kFileSystemsKey[] = "fileSystems";
43 const char kIndexedDBKey[] = "indexedDB";
44 const char kLocalStorageKey[] = "localStorage";
45 const char kWebSQLKey[] = "webSQL";
46 const char kSinceKey[] = "since";
47 const char kLoadFileError[] = "Failed to load file: \"*\". ";
48 const char kViewInstanceIdError[] = "view_instance_id is missing.";
49 const char kDuplicatedContentScriptNamesError[] =
50 "The given content script name already exists.";
52 uint32 MaskForKey(const char* key) {
53 if (strcmp(key, kAppCacheKey) == 0)
54 return webview::WEB_VIEW_REMOVE_DATA_MASK_APPCACHE;
55 if (strcmp(key, kCacheKey) == 0)
56 return webview::WEB_VIEW_REMOVE_DATA_MASK_CACHE;
57 if (strcmp(key, kCookiesKey) == 0)
58 return webview::WEB_VIEW_REMOVE_DATA_MASK_COOKIES;
59 if (strcmp(key, kFileSystemsKey) == 0)
60 return webview::WEB_VIEW_REMOVE_DATA_MASK_FILE_SYSTEMS;
61 if (strcmp(key, kIndexedDBKey) == 0)
62 return webview::WEB_VIEW_REMOVE_DATA_MASK_INDEXEDDB;
63 if (strcmp(key, kLocalStorageKey) == 0)
64 return webview::WEB_VIEW_REMOVE_DATA_MASK_LOCAL_STORAGE;
65 if (strcmp(key, kWebSQLKey) == 0)
66 return webview::WEB_VIEW_REMOVE_DATA_MASK_WEBSQL;
67 return 0;
70 HostID GenerateHostIDFromEmbedder(const extensions::Extension* extension,
71 const content::WebContents* web_contents) {
72 if (extension)
73 return HostID(HostID::EXTENSIONS, extension->id());
75 if (web_contents && web_contents->GetWebUI()) {
76 const GURL& url = web_contents->GetSiteInstance()->GetSiteURL();
77 return HostID(HostID::WEBUI, url.spec());
79 NOTREACHED();
80 return HostID();
83 // Creates content script files when parsing InjectionItems of "js" or "css"
84 // proterties, and stores them in the |result|.
85 void AddScriptFiles(const GURL& owner_base_url,
86 const extensions::Extension* extension,
87 const InjectionItems& items,
88 UserScript::FileList* result) {
89 // files:
90 if (items.files) {
91 for (const std::string& relative : *items.files) {
92 GURL url = owner_base_url.Resolve(relative);
93 if (extension) {
94 ExtensionResource resource = extension->GetResource(relative);
95 result->push_back(UserScript::File(resource.extension_root(),
96 resource.relative_path(), url));
97 } else {
98 result->push_back(extensions::UserScript::File(base::FilePath(),
99 base::FilePath(), url));
103 // code:
104 if (items.code) {
105 extensions::UserScript::File file((base::FilePath()), (base::FilePath()),
106 GURL());
107 file.set_content(*items.code);
108 result->push_back(file);
112 // Parses the values stored in ContentScriptDetails, and constructs a
113 // UserScript.
114 bool ParseContentScript(const ContentScriptDetails& script_value,
115 const extensions::Extension* extension,
116 const GURL& owner_base_url,
117 UserScript* script,
118 std::string* error) {
119 // matches (required):
120 if (script_value.matches.empty())
121 return false;
123 // The default for WebUI is not having special access, but we can change that
124 // if needed.
125 bool allowed_everywhere = false;
126 if (extension &&
127 extensions::PermissionsData::CanExecuteScriptEverywhere(extension))
128 allowed_everywhere = true;
130 for (const std::string& match : script_value.matches) {
131 URLPattern pattern(UserScript::ValidUserScriptSchemes(allowed_everywhere));
132 if (pattern.Parse(match) != URLPattern::PARSE_SUCCESS) {
133 *error = errors::kInvalidMatches;
134 return false;
136 script->add_url_pattern(pattern);
139 // exclude_matches:
140 if (script_value.exclude_matches) {
141 const std::vector<std::string>& exclude_matches =
142 *(script_value.exclude_matches.get());
143 for (const std::string& exclude_match : exclude_matches) {
144 URLPattern pattern(
145 UserScript::ValidUserScriptSchemes(allowed_everywhere));
147 if (pattern.Parse(exclude_match) != URLPattern::PARSE_SUCCESS) {
148 *error = errors::kInvalidExcludeMatches;
149 return false;
151 script->add_exclude_url_pattern(pattern);
154 // run_at:
155 if (script_value.run_at) {
156 UserScript::RunLocation run_at = UserScript::UNDEFINED;
157 switch (script_value.run_at) {
158 case extensions::core_api::extension_types::RUN_AT_NONE:
159 case extensions::core_api::extension_types::RUN_AT_DOCUMENT_IDLE:
160 run_at = UserScript::DOCUMENT_IDLE;
161 break;
162 case extensions::core_api::extension_types::RUN_AT_DOCUMENT_START:
163 run_at = UserScript::DOCUMENT_START;
164 break;
165 case extensions::core_api::extension_types::RUN_AT_DOCUMENT_END:
166 run_at = UserScript::DOCUMENT_END;
167 break;
169 // The default for run_at is RUN_AT_DOCUMENT_IDLE.
170 script->set_run_location(run_at);
173 // match_about_blank:
174 if (script_value.match_about_blank)
175 script->set_match_about_blank(*script_value.match_about_blank);
177 // css:
178 if (script_value.css) {
179 AddScriptFiles(owner_base_url, extension, *script_value.css,
180 &script->css_scripts());
183 // js:
184 if (script_value.js) {
185 AddScriptFiles(owner_base_url, extension, *script_value.js,
186 &script->js_scripts());
189 // all_frames:
190 if (script_value.all_frames)
191 script->set_match_all_frames(*script_value.all_frames);
193 // include_globs:
194 if (script_value.include_globs) {
195 for (const std::string& glob : *script_value.include_globs)
196 script->add_glob(glob);
199 // exclude_globs:
200 if (script_value.exclude_globs) {
201 for (const std::string& glob : *script_value.exclude_globs)
202 script->add_exclude_glob(glob);
205 return true;
208 bool ParseContentScripts(
209 std::vector<linked_ptr<ContentScriptDetails>> content_script_list,
210 const extensions::Extension* extension,
211 const HostID& host_id,
212 bool incognito_enabled,
213 const GURL& owner_base_url,
214 std::set<UserScript>* result,
215 std::string* error) {
216 if (content_script_list.empty())
217 return false;
219 std::set<std::string> names;
220 for (const linked_ptr<ContentScriptDetails> script_value :
221 content_script_list) {
222 const std::string& name = script_value->name;
223 if (!names.insert(name).second) {
224 // The name was already in the list.
225 *error = kDuplicatedContentScriptNamesError;
226 return false;
229 UserScript script;
230 if (!ParseContentScript(*script_value, extension, owner_base_url, &script,
231 error))
232 return false;
234 script.set_id(UserScript::GenerateUserScriptID());
235 script.set_name(name);
236 script.set_incognito_enabled(incognito_enabled);
237 script.set_host_id(host_id);
238 script.set_consumer_instance_type(UserScript::WEBVIEW);
239 result->insert(script);
241 return true;
244 } // namespace
246 namespace extensions {
248 bool WebViewInternalExtensionFunction::RunAsync() {
249 int instance_id = 0;
250 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
251 WebViewGuest* guest = WebViewGuest::From(
252 render_view_host()->GetProcess()->GetID(), instance_id);
253 if (!guest)
254 return false;
256 return RunAsyncSafe(guest);
259 bool WebViewInternalNavigateFunction::RunAsyncSafe(WebViewGuest* guest) {
260 scoped_ptr<web_view_internal::Navigate::Params> params(
261 web_view_internal::Navigate::Params::Create(*args_));
262 EXTENSION_FUNCTION_VALIDATE(params.get());
263 std::string src = params->src;
264 guest->NavigateGuest(src, true /* force_navigation */);
265 return true;
268 WebViewInternalExecuteCodeFunction::WebViewInternalExecuteCodeFunction()
269 : guest_instance_id_(0), guest_src_(GURL::EmptyGURL()) {
272 WebViewInternalExecuteCodeFunction::~WebViewInternalExecuteCodeFunction() {
275 bool WebViewInternalExecuteCodeFunction::Init() {
276 if (details_.get())
277 return true;
279 if (!args_->GetInteger(0, &guest_instance_id_))
280 return false;
282 if (!guest_instance_id_)
283 return false;
285 std::string src;
286 if (!args_->GetString(1, &src))
287 return false;
289 guest_src_ = GURL(src);
290 if (!guest_src_.is_valid())
291 return false;
293 base::DictionaryValue* details_value = NULL;
294 if (!args_->GetDictionary(2, &details_value))
295 return false;
296 scoped_ptr<InjectDetails> details(new InjectDetails());
297 if (!InjectDetails::Populate(*details_value, details.get()))
298 return false;
300 details_ = details.Pass();
302 if (extension()) {
303 set_host_id(HostID(HostID::EXTENSIONS, extension()->id()));
304 return true;
307 WebContents* web_contents = GetSenderWebContents();
308 if (web_contents && web_contents->GetWebUI()) {
309 const GURL& url = render_view_host()->GetSiteInstance()->GetSiteURL();
310 set_host_id(HostID(HostID::WEBUI, url.spec()));
311 return true;
313 return false;
316 bool WebViewInternalExecuteCodeFunction::ShouldInsertCSS() const {
317 return false;
320 bool WebViewInternalExecuteCodeFunction::CanExecuteScriptOnPage() {
321 return true;
324 extensions::ScriptExecutor*
325 WebViewInternalExecuteCodeFunction::GetScriptExecutor() {
326 if (!render_view_host() || !render_view_host()->GetProcess())
327 return NULL;
328 WebViewGuest* guest = WebViewGuest::From(
329 render_view_host()->GetProcess()->GetID(), guest_instance_id_);
330 if (!guest)
331 return NULL;
333 return guest->script_executor();
336 bool WebViewInternalExecuteCodeFunction::IsWebView() const {
337 return true;
340 const GURL& WebViewInternalExecuteCodeFunction::GetWebViewSrc() const {
341 return guest_src_;
344 bool WebViewInternalExecuteCodeFunction::LoadFileForWebUI(
345 const std::string& file_src,
346 const WebUIURLFetcher::WebUILoadFileCallback& callback) {
347 if (!render_view_host() || !render_view_host()->GetProcess())
348 return false;
349 WebViewGuest* guest = WebViewGuest::From(
350 render_view_host()->GetProcess()->GetID(), guest_instance_id_);
351 if (!guest || host_id().type() != HostID::WEBUI)
352 return false;
354 GURL owner_base_url(guest->GetOwnerSiteURL().GetWithEmptyPath());
355 GURL file_url(owner_base_url.Resolve(file_src));
357 url_fetcher_.reset(new WebUIURLFetcher(
358 this->browser_context(), render_view_host()->GetProcess()->GetID(),
359 render_view_host()->GetRoutingID(), file_url, callback));
360 url_fetcher_->Start();
361 return true;
364 bool WebViewInternalExecuteCodeFunction::LoadFile(const std::string& file) {
365 if (!extension()) {
366 if (LoadFileForWebUI(
367 *details_->file,
368 base::Bind(
369 &WebViewInternalExecuteCodeFunction::DidLoadAndLocalizeFile,
370 this, file)))
371 return true;
373 SendResponse(false);
374 error_ = ErrorUtils::FormatErrorMessage(kLoadFileError, file);
375 return false;
377 return ExecuteCodeFunction::LoadFile(file);
380 WebViewInternalExecuteScriptFunction::WebViewInternalExecuteScriptFunction() {
383 void WebViewInternalExecuteScriptFunction::OnExecuteCodeFinished(
384 const std::string& error,
385 const GURL& on_url,
386 const base::ListValue& result) {
387 if (error.empty())
388 SetResult(result.DeepCopy());
389 WebViewInternalExecuteCodeFunction::OnExecuteCodeFinished(
390 error, on_url, result);
393 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() {
396 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const {
397 return true;
400 WebViewInternalAddContentScriptsFunction::
401 WebViewInternalAddContentScriptsFunction() {
404 WebViewInternalAddContentScriptsFunction::
405 ~WebViewInternalAddContentScriptsFunction() {
408 ExecuteCodeFunction::ResponseAction
409 WebViewInternalAddContentScriptsFunction::Run() {
410 scoped_ptr<web_view_internal::AddContentScripts::Params> params(
411 web_view_internal::AddContentScripts::Params::Create(*args_));
412 EXTENSION_FUNCTION_VALIDATE(params.get());
414 if (!params->instance_id)
415 return RespondNow(Error(kViewInstanceIdError));
417 GURL owner_base_url(
418 render_view_host()->GetSiteInstance()->GetSiteURL().GetWithEmptyPath());
419 std::set<UserScript> result;
421 content::WebContents* sender_web_contents = GetSenderWebContents();
422 HostID host_id = GenerateHostIDFromEmbedder(extension(), sender_web_contents);
423 bool incognito_enabled = browser_context()->IsOffTheRecord();
425 if (!ParseContentScripts(params->content_script_list, extension(), host_id,
426 incognito_enabled, owner_base_url, &result, &error_))
427 return RespondNow(Error(error_));
429 WebViewContentScriptManager* manager =
430 WebViewContentScriptManager::Get(browser_context());
431 DCHECK(manager);
433 manager->AddContentScripts(sender_web_contents,
434 render_view_host()->GetRoutingID(),
435 params->instance_id, host_id, result);
437 return RespondNow(NoArguments());
440 WebViewInternalRemoveContentScriptsFunction::
441 WebViewInternalRemoveContentScriptsFunction() {
444 WebViewInternalRemoveContentScriptsFunction::
445 ~WebViewInternalRemoveContentScriptsFunction() {
448 ExecuteCodeFunction::ResponseAction
449 WebViewInternalRemoveContentScriptsFunction::Run() {
450 scoped_ptr<web_view_internal::RemoveContentScripts::Params> params(
451 web_view_internal::RemoveContentScripts::Params::Create(*args_));
452 EXTENSION_FUNCTION_VALIDATE(params.get());
454 if (!params->instance_id)
455 return RespondNow(Error(kViewInstanceIdError));
457 WebViewContentScriptManager* manager =
458 WebViewContentScriptManager::Get(browser_context());
459 DCHECK(manager);
461 content::WebContents* sender_web_contents = GetSenderWebContents();
462 HostID host_id = GenerateHostIDFromEmbedder(extension(), sender_web_contents);
464 std::vector<std::string> script_name_list;
465 if (params->script_name_list)
466 script_name_list.swap(*params->script_name_list);
467 manager->RemoveContentScripts(GetSenderWebContents(), params->instance_id,
468 host_id, script_name_list);
469 return RespondNow(NoArguments());
472 WebViewInternalSetNameFunction::WebViewInternalSetNameFunction() {
475 WebViewInternalSetNameFunction::~WebViewInternalSetNameFunction() {
478 bool WebViewInternalSetNameFunction::RunAsyncSafe(WebViewGuest* guest) {
479 scoped_ptr<web_view_internal::SetName::Params> params(
480 web_view_internal::SetName::Params::Create(*args_));
481 EXTENSION_FUNCTION_VALIDATE(params.get());
482 guest->SetName(params->frame_name);
483 SendResponse(true);
484 return true;
487 WebViewInternalSetAllowTransparencyFunction::
488 WebViewInternalSetAllowTransparencyFunction() {
491 WebViewInternalSetAllowTransparencyFunction::
492 ~WebViewInternalSetAllowTransparencyFunction() {
495 bool WebViewInternalSetAllowTransparencyFunction::RunAsyncSafe(
496 WebViewGuest* guest) {
497 scoped_ptr<web_view_internal::SetAllowTransparency::Params> params(
498 web_view_internal::SetAllowTransparency::Params::Create(*args_));
499 EXTENSION_FUNCTION_VALIDATE(params.get());
500 guest->SetAllowTransparency(params->allow);
501 SendResponse(true);
502 return true;
505 WebViewInternalSetAllowScalingFunction::
506 WebViewInternalSetAllowScalingFunction() {
509 WebViewInternalSetAllowScalingFunction::
510 ~WebViewInternalSetAllowScalingFunction() {
513 bool WebViewInternalSetAllowScalingFunction::RunAsyncSafe(WebViewGuest* guest) {
514 scoped_ptr<web_view_internal::SetAllowScaling::Params> params(
515 web_view_internal::SetAllowScaling::Params::Create(*args_));
516 EXTENSION_FUNCTION_VALIDATE(params.get());
517 guest->SetAllowScaling(params->allow);
518 SendResponse(true);
519 return true;
522 WebViewInternalSetZoomFunction::WebViewInternalSetZoomFunction() {
525 WebViewInternalSetZoomFunction::~WebViewInternalSetZoomFunction() {
528 bool WebViewInternalSetZoomFunction::RunAsyncSafe(WebViewGuest* guest) {
529 scoped_ptr<web_view_internal::SetZoom::Params> params(
530 web_view_internal::SetZoom::Params::Create(*args_));
531 EXTENSION_FUNCTION_VALIDATE(params.get());
532 guest->SetZoom(params->zoom_factor);
534 SendResponse(true);
535 return true;
538 WebViewInternalGetZoomFunction::WebViewInternalGetZoomFunction() {
541 WebViewInternalGetZoomFunction::~WebViewInternalGetZoomFunction() {
544 bool WebViewInternalGetZoomFunction::RunAsyncSafe(WebViewGuest* guest) {
545 scoped_ptr<web_view_internal::GetZoom::Params> params(
546 web_view_internal::GetZoom::Params::Create(*args_));
547 EXTENSION_FUNCTION_VALIDATE(params.get());
549 double zoom_factor = guest->GetZoom();
550 SetResult(new base::FundamentalValue(zoom_factor));
551 SendResponse(true);
552 return true;
555 WebViewInternalSetZoomModeFunction::WebViewInternalSetZoomModeFunction() {
558 WebViewInternalSetZoomModeFunction::~WebViewInternalSetZoomModeFunction() {
561 bool WebViewInternalSetZoomModeFunction::RunAsyncSafe(WebViewGuest* guest) {
562 scoped_ptr<web_view_internal::SetZoomMode::Params> params(
563 web_view_internal::SetZoomMode::Params::Create(*args_));
564 EXTENSION_FUNCTION_VALIDATE(params.get());
566 ZoomController::ZoomMode zoom_mode = ZoomController::ZOOM_MODE_DEFAULT;
567 switch (params->zoom_mode) {
568 case web_view_internal::ZOOM_MODE_PER_ORIGIN:
569 zoom_mode = ZoomController::ZOOM_MODE_DEFAULT;
570 break;
571 case web_view_internal::ZOOM_MODE_PER_VIEW:
572 zoom_mode = ZoomController::ZOOM_MODE_ISOLATED;
573 break;
574 case web_view_internal::ZOOM_MODE_DISABLED:
575 zoom_mode = ZoomController::ZOOM_MODE_DISABLED;
576 break;
577 default:
578 NOTREACHED();
581 guest->SetZoomMode(zoom_mode);
583 SendResponse(true);
584 return true;
587 WebViewInternalGetZoomModeFunction::WebViewInternalGetZoomModeFunction() {
590 WebViewInternalGetZoomModeFunction::~WebViewInternalGetZoomModeFunction() {
593 bool WebViewInternalGetZoomModeFunction::RunAsyncSafe(WebViewGuest* guest) {
594 scoped_ptr<web_view_internal::GetZoomMode::Params> params(
595 web_view_internal::GetZoomMode::Params::Create(*args_));
596 EXTENSION_FUNCTION_VALIDATE(params.get());
598 web_view_internal::ZoomMode zoom_mode = web_view_internal::ZOOM_MODE_NONE;
599 switch (guest->GetZoomMode()) {
600 case ZoomController::ZOOM_MODE_DEFAULT:
601 zoom_mode = web_view_internal::ZOOM_MODE_PER_ORIGIN;
602 break;
603 case ZoomController::ZOOM_MODE_ISOLATED:
604 zoom_mode = web_view_internal::ZOOM_MODE_PER_VIEW;
605 break;
606 case ZoomController::ZOOM_MODE_DISABLED:
607 zoom_mode = web_view_internal::ZOOM_MODE_DISABLED;
608 break;
609 default:
610 NOTREACHED();
613 SetResult(new base::StringValue(web_view_internal::ToString(zoom_mode)));
614 SendResponse(true);
615 return true;
618 WebViewInternalFindFunction::WebViewInternalFindFunction() {
621 WebViewInternalFindFunction::~WebViewInternalFindFunction() {
624 bool WebViewInternalFindFunction::RunAsyncSafe(WebViewGuest* guest) {
625 scoped_ptr<web_view_internal::Find::Params> params(
626 web_view_internal::Find::Params::Create(*args_));
627 EXTENSION_FUNCTION_VALIDATE(params.get());
629 // Convert the std::string search_text to string16.
630 base::string16 search_text;
631 base::UTF8ToUTF16(
632 params->search_text.c_str(), params->search_text.length(), &search_text);
634 // Set the find options to their default values.
635 blink::WebFindOptions options;
636 if (params->options) {
637 options.forward =
638 params->options->backward ? !*params->options->backward : true;
639 options.matchCase =
640 params->options->match_case ? *params->options->match_case : false;
643 guest->StartFindInternal(search_text, options, this);
644 return true;
647 WebViewInternalStopFindingFunction::WebViewInternalStopFindingFunction() {
650 WebViewInternalStopFindingFunction::~WebViewInternalStopFindingFunction() {
653 bool WebViewInternalStopFindingFunction::RunAsyncSafe(WebViewGuest* guest) {
654 scoped_ptr<web_view_internal::StopFinding::Params> params(
655 web_view_internal::StopFinding::Params::Create(*args_));
656 EXTENSION_FUNCTION_VALIDATE(params.get());
658 // Set the StopFindAction.
659 content::StopFindAction action;
660 switch (params->action) {
661 case web_view_internal::STOP_FINDING_ACTION_CLEAR:
662 action = content::STOP_FIND_ACTION_CLEAR_SELECTION;
663 break;
664 case web_view_internal::STOP_FINDING_ACTION_KEEP:
665 action = content::STOP_FIND_ACTION_KEEP_SELECTION;
666 break;
667 case web_view_internal::STOP_FINDING_ACTION_ACTIVATE:
668 action = content::STOP_FIND_ACTION_ACTIVATE_SELECTION;
669 break;
670 default:
671 action = content::STOP_FIND_ACTION_KEEP_SELECTION;
674 guest->StopFindingInternal(action);
675 return true;
678 WebViewInternalLoadDataWithBaseUrlFunction::
679 WebViewInternalLoadDataWithBaseUrlFunction() {
682 WebViewInternalLoadDataWithBaseUrlFunction::
683 ~WebViewInternalLoadDataWithBaseUrlFunction() {
686 bool WebViewInternalLoadDataWithBaseUrlFunction::RunAsyncSafe(
687 WebViewGuest* guest) {
688 scoped_ptr<web_view_internal::LoadDataWithBaseUrl::Params> params(
689 web_view_internal::LoadDataWithBaseUrl::Params::Create(*args_));
690 EXTENSION_FUNCTION_VALIDATE(params.get());
692 // If a virtual URL was provided, use it. Otherwise, the user will be shown
693 // the data URL.
694 std::string virtual_url =
695 params->virtual_url ? *params->virtual_url : params->data_url;
697 bool successful = guest->LoadDataWithBaseURL(
698 params->data_url, params->base_url, virtual_url, &error_);
699 SendResponse(successful);
700 return successful;
703 WebViewInternalGoFunction::WebViewInternalGoFunction() {
706 WebViewInternalGoFunction::~WebViewInternalGoFunction() {
709 bool WebViewInternalGoFunction::RunAsyncSafe(WebViewGuest* guest) {
710 scoped_ptr<web_view_internal::Go::Params> params(
711 web_view_internal::Go::Params::Create(*args_));
712 EXTENSION_FUNCTION_VALIDATE(params.get());
714 bool successful = guest->Go(params->relative_index);
715 SetResult(new base::FundamentalValue(successful));
716 SendResponse(true);
717 return true;
720 WebViewInternalReloadFunction::WebViewInternalReloadFunction() {
723 WebViewInternalReloadFunction::~WebViewInternalReloadFunction() {
726 bool WebViewInternalReloadFunction::RunAsyncSafe(WebViewGuest* guest) {
727 guest->Reload();
728 return true;
731 WebViewInternalSetPermissionFunction::WebViewInternalSetPermissionFunction() {
734 WebViewInternalSetPermissionFunction::~WebViewInternalSetPermissionFunction() {
737 bool WebViewInternalSetPermissionFunction::RunAsyncSafe(WebViewGuest* guest) {
738 scoped_ptr<web_view_internal::SetPermission::Params> params(
739 web_view_internal::SetPermission::Params::Create(*args_));
740 EXTENSION_FUNCTION_VALIDATE(params.get());
742 WebViewPermissionHelper::PermissionResponseAction action =
743 WebViewPermissionHelper::DEFAULT;
744 switch (params->action) {
745 case core_api::web_view_internal::SET_PERMISSION_ACTION_ALLOW:
746 action = WebViewPermissionHelper::ALLOW;
747 break;
748 case core_api::web_view_internal::SET_PERMISSION_ACTION_DENY:
749 action = WebViewPermissionHelper::DENY;
750 break;
751 case core_api::web_view_internal::SET_PERMISSION_ACTION_DEFAULT:
752 break;
753 default:
754 NOTREACHED();
757 std::string user_input;
758 if (params->user_input)
759 user_input = *params->user_input;
761 WebViewPermissionHelper* web_view_permission_helper =
762 WebViewPermissionHelper::FromWebContents(guest->web_contents());
764 WebViewPermissionHelper::SetPermissionResult result =
765 web_view_permission_helper->SetPermission(
766 params->request_id, action, user_input);
768 EXTENSION_FUNCTION_VALIDATE(result !=
769 WebViewPermissionHelper::SET_PERMISSION_INVALID);
771 SetResult(new base::FundamentalValue(
772 result == WebViewPermissionHelper::SET_PERMISSION_ALLOWED));
773 SendResponse(true);
774 return true;
777 WebViewInternalOverrideUserAgentFunction::
778 WebViewInternalOverrideUserAgentFunction() {
781 WebViewInternalOverrideUserAgentFunction::
782 ~WebViewInternalOverrideUserAgentFunction() {
785 bool WebViewInternalOverrideUserAgentFunction::RunAsyncSafe(
786 WebViewGuest* guest) {
787 scoped_ptr<web_view_internal::OverrideUserAgent::Params> params(
788 web_view_internal::OverrideUserAgent::Params::Create(*args_));
789 EXTENSION_FUNCTION_VALIDATE(params.get());
791 guest->SetUserAgentOverride(params->user_agent_override);
792 return true;
795 WebViewInternalStopFunction::WebViewInternalStopFunction() {
798 WebViewInternalStopFunction::~WebViewInternalStopFunction() {
801 bool WebViewInternalStopFunction::RunAsyncSafe(WebViewGuest* guest) {
802 guest->Stop();
803 return true;
806 WebViewInternalTerminateFunction::WebViewInternalTerminateFunction() {
809 WebViewInternalTerminateFunction::~WebViewInternalTerminateFunction() {
812 bool WebViewInternalTerminateFunction::RunAsyncSafe(WebViewGuest* guest) {
813 guest->Terminate();
814 return true;
817 WebViewInternalClearDataFunction::WebViewInternalClearDataFunction()
818 : remove_mask_(0), bad_message_(false) {
821 WebViewInternalClearDataFunction::~WebViewInternalClearDataFunction() {
824 // Parses the |dataToRemove| argument to generate the remove mask. Sets
825 // |bad_message_| (like EXTENSION_FUNCTION_VALIDATE would if this were a bool
826 // method) if 'dataToRemove' is not present.
827 uint32 WebViewInternalClearDataFunction::GetRemovalMask() {
828 base::DictionaryValue* data_to_remove;
829 if (!args_->GetDictionary(2, &data_to_remove)) {
830 bad_message_ = true;
831 return 0;
834 uint32 remove_mask = 0;
835 for (base::DictionaryValue::Iterator i(*data_to_remove); !i.IsAtEnd();
836 i.Advance()) {
837 bool selected = false;
838 if (!i.value().GetAsBoolean(&selected)) {
839 bad_message_ = true;
840 return 0;
842 if (selected)
843 remove_mask |= MaskForKey(i.key().c_str());
846 return remove_mask;
849 // TODO(lazyboy): Parameters in this extension function are similar (or a
850 // sub-set) to BrowsingDataRemoverFunction. How can we share this code?
851 bool WebViewInternalClearDataFunction::RunAsyncSafe(WebViewGuest* guest) {
852 // Grab the initial |options| parameter, and parse out the arguments.
853 base::DictionaryValue* options;
854 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options));
855 DCHECK(options);
857 // If |ms_since_epoch| isn't set, default it to 0.
858 double ms_since_epoch;
859 if (!options->GetDouble(kSinceKey, &ms_since_epoch)) {
860 ms_since_epoch = 0;
863 // base::Time takes a double that represents seconds since epoch. JavaScript
864 // gives developers milliseconds, so do a quick conversion before populating
865 // the object. Also, Time::FromDoubleT converts double time 0 to empty Time
866 // object. So we need to do special handling here.
867 remove_since_ = (ms_since_epoch == 0)
868 ? base::Time::UnixEpoch()
869 : base::Time::FromDoubleT(ms_since_epoch / 1000.0);
871 remove_mask_ = GetRemovalMask();
872 if (bad_message_)
873 return false;
875 AddRef(); // Balanced below or in WebViewInternalClearDataFunction::Done().
877 bool scheduled = false;
878 if (remove_mask_) {
879 scheduled = guest->ClearData(
880 remove_since_,
881 remove_mask_,
882 base::Bind(&WebViewInternalClearDataFunction::ClearDataDone, this));
884 if (!remove_mask_ || !scheduled) {
885 SendResponse(false);
886 Release(); // Balanced above.
887 return false;
890 // Will finish asynchronously.
891 return true;
894 void WebViewInternalClearDataFunction::ClearDataDone() {
895 Release(); // Balanced in RunAsync().
896 SendResponse(true);
899 } // namespace extensions