Add more checks to investigate SupervisedUserPrefStore crash at startup.
[chromium-blink-merge.git] / extensions / browser / api / web_view / web_view_internal_api.cc
blob4b041e911764efabd574034f0e175b015ffebd65
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;
22 namespace {
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;
45 return 0;
48 } // namespace
50 namespace extensions {
52 bool WebViewInternalExtensionFunction::RunAsync() {
53 int instance_id = 0;
54 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
55 WebViewGuest* guest = WebViewGuest::From(
56 render_view_host()->GetProcess()->GetID(), instance_id);
57 if (!guest)
58 return false;
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 */);
69 return true;
72 WebViewInternalExecuteCodeFunction::WebViewInternalExecuteCodeFunction()
73 : guest_instance_id_(0), guest_src_(GURL::EmptyGURL()) {
76 WebViewInternalExecuteCodeFunction::~WebViewInternalExecuteCodeFunction() {
79 bool WebViewInternalExecuteCodeFunction::Init() {
80 if (details_.get())
81 return true;
83 if (!args_->GetInteger(0, &guest_instance_id_))
84 return false;
86 if (!guest_instance_id_)
87 return false;
89 std::string src;
90 if (!args_->GetString(1, &src))
91 return false;
93 guest_src_ = GURL(src);
94 if (!guest_src_.is_valid())
95 return false;
97 base::DictionaryValue* details_value = NULL;
98 if (!args_->GetDictionary(2, &details_value))
99 return false;
100 scoped_ptr<InjectDetails> details(new InjectDetails());
101 if (!InjectDetails::Populate(*details_value, details.get()))
102 return false;
104 details_ = details.Pass();
105 return true;
108 bool WebViewInternalExecuteCodeFunction::ShouldInsertCSS() const {
109 return false;
112 bool WebViewInternalExecuteCodeFunction::CanExecuteScriptOnPage() {
113 return true;
116 extensions::ScriptExecutor*
117 WebViewInternalExecuteCodeFunction::GetScriptExecutor() {
118 if (!render_view_host() || !render_view_host()->GetProcess())
119 return NULL;
120 WebViewGuest* guest = WebViewGuest::From(
121 render_view_host()->GetProcess()->GetID(), guest_instance_id_);
122 if (!guest)
123 return NULL;
125 return guest->script_executor();
128 bool WebViewInternalExecuteCodeFunction::IsWebView() const {
129 return true;
132 const GURL& WebViewInternalExecuteCodeFunction::GetWebViewSrc() const {
133 return guest_src_;
136 WebViewInternalExecuteScriptFunction::WebViewInternalExecuteScriptFunction() {
139 void WebViewInternalExecuteScriptFunction::OnExecuteCodeFinished(
140 const std::string& error,
141 const GURL& on_url,
142 const base::ListValue& result) {
143 if (error.empty())
144 SetResult(result.DeepCopy());
145 WebViewInternalExecuteCodeFunction::OnExecuteCodeFinished(
146 error, on_url, result);
149 WebViewInternalInsertCSSFunction::WebViewInternalInsertCSSFunction() {
152 bool WebViewInternalInsertCSSFunction::ShouldInsertCSS() const {
153 return true;
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);
167 SendResponse(true);
168 return true;
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);
185 SendResponse(true);
186 return true;
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);
202 SendResponse(true);
203 return true;
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);
218 SendResponse(true);
219 return true;
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));
235 SendResponse(true);
236 return true;
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;
252 base::UTF8ToUTF16(
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) {
258 options.forward =
259 params->options->backward ? !*params->options->backward : true;
260 options.matchCase =
261 params->options->match_case ? *params->options->match_case : false;
264 guest->StartFindInternal(search_text, options, this);
265 return true;
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;
284 break;
285 case webview::StopFinding::Params::ACTION_KEEP:
286 action = content::STOP_FIND_ACTION_KEEP_SELECTION;
287 break;
288 case webview::StopFinding::Params::ACTION_ACTIVATE:
289 action = content::STOP_FIND_ACTION_ACTIVATE_SELECTION;
290 break;
291 default:
292 action = content::STOP_FIND_ACTION_KEEP_SELECTION;
295 guest->StopFindingInternal(action);
296 return true;
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
314 // the data URL.
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);
321 return 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));
336 SendResponse(true);
337 return true;
340 WebViewInternalReloadFunction::WebViewInternalReloadFunction() {
343 WebViewInternalReloadFunction::~WebViewInternalReloadFunction() {
346 bool WebViewInternalReloadFunction::RunAsyncSafe(WebViewGuest* guest) {
347 guest->Reload();
348 return true;
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;
367 break;
368 case Params::ACTION_DENY:
369 action = WebViewPermissionHelper::DENY;
370 break;
371 case Params::ACTION_DEFAULT:
372 break;
373 default:
374 NOTREACHED();
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));
393 SendResponse(true);
394 return true;
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);
412 return true;
415 WebViewInternalStopFunction::WebViewInternalStopFunction() {
418 WebViewInternalStopFunction::~WebViewInternalStopFunction() {
421 bool WebViewInternalStopFunction::RunAsyncSafe(WebViewGuest* guest) {
422 guest->Stop();
423 return true;
426 WebViewInternalTerminateFunction::WebViewInternalTerminateFunction() {
429 WebViewInternalTerminateFunction::~WebViewInternalTerminateFunction() {
432 bool WebViewInternalTerminateFunction::RunAsyncSafe(WebViewGuest* guest) {
433 guest->Terminate();
434 return true;
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)) {
450 bad_message_ = true;
451 return 0;
454 uint32 remove_mask = 0;
455 for (base::DictionaryValue::Iterator i(*data_to_remove); !i.IsAtEnd();
456 i.Advance()) {
457 bool selected = false;
458 if (!i.value().GetAsBoolean(&selected)) {
459 bad_message_ = true;
460 return 0;
462 if (selected)
463 remove_mask |= MaskForKey(i.key().c_str());
466 return remove_mask;
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));
475 DCHECK(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)) {
480 ms_since_epoch = 0;
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();
492 if (bad_message_)
493 return false;
495 AddRef(); // Balanced below or in WebViewInternalClearDataFunction::Done().
497 bool scheduled = false;
498 if (remove_mask_) {
499 scheduled = guest->ClearData(
500 remove_since_,
501 remove_mask_,
502 base::Bind(&WebViewInternalClearDataFunction::ClearDataDone, this));
504 if (!remove_mask_ || !scheduled) {
505 SendResponse(false);
506 Release(); // Balanced above.
507 return false;
510 // Will finish asynchronously.
511 return true;
514 void WebViewInternalClearDataFunction::ClearDataDone() {
515 Release(); // Balanced in RunAsync().
516 SendResponse(true);
519 } // namespace extensions