Add testing/scripts/OWNERS
[chromium-blink-merge.git] / extensions / browser / api / web_view / web_view_internal_api.cc
blob0c5adfda63cf7208737816f835ca35f348dd8114
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 WebViewInternalCaptureVisibleRegionFunction::
157 WebViewInternalCaptureVisibleRegionFunction() {
160 WebViewInternalCaptureVisibleRegionFunction::
161 ~WebViewInternalCaptureVisibleRegionFunction() {
164 bool WebViewInternalCaptureVisibleRegionFunction::IsScreenshotEnabled() {
165 return true;
168 WebContents* WebViewInternalCaptureVisibleRegionFunction::GetWebContentsForID(
169 int instance_id) {
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) {
177 SendResponse(false);
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);
191 SendResponse(true);
192 return true;
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);
209 SendResponse(true);
210 return true;
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);
225 SendResponse(true);
226 return true;
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));
242 SendResponse(true);
243 return true;
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;
259 base::UTF8ToUTF16(
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) {
265 options.forward =
266 params->options->backward ? !*params->options->backward : true;
267 options.matchCase =
268 params->options->match_case ? *params->options->match_case : false;
271 guest->StartFinding(search_text, options, this);
272 return true;
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;
291 break;
292 case webview::StopFinding::Params::ACTION_KEEP:
293 action = content::STOP_FIND_ACTION_KEEP_SELECTION;
294 break;
295 case webview::StopFinding::Params::ACTION_ACTIVATE:
296 action = content::STOP_FIND_ACTION_ACTIVATE_SELECTION;
297 break;
298 default:
299 action = content::STOP_FIND_ACTION_KEEP_SELECTION;
302 guest->StopFinding(action);
303 return true;
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
321 // the data URL.
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);
328 return 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));
343 SendResponse(true);
344 return true;
347 WebViewInternalReloadFunction::WebViewInternalReloadFunction() {
350 WebViewInternalReloadFunction::~WebViewInternalReloadFunction() {
353 bool WebViewInternalReloadFunction::RunAsyncSafe(WebViewGuest* guest) {
354 guest->Reload();
355 return true;
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;
374 break;
375 case Params::ACTION_DENY:
376 action = WebViewPermissionHelper::DENY;
377 break;
378 case Params::ACTION_DEFAULT:
379 break;
380 default:
381 NOTREACHED();
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));
400 SendResponse(true);
401 return true;
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);
419 return true;
422 WebViewInternalStopFunction::WebViewInternalStopFunction() {
425 WebViewInternalStopFunction::~WebViewInternalStopFunction() {
428 bool WebViewInternalStopFunction::RunAsyncSafe(WebViewGuest* guest) {
429 guest->Stop();
430 return true;
433 WebViewInternalTerminateFunction::WebViewInternalTerminateFunction() {
436 WebViewInternalTerminateFunction::~WebViewInternalTerminateFunction() {
439 bool WebViewInternalTerminateFunction::RunAsyncSafe(WebViewGuest* guest) {
440 guest->Terminate();
441 return true;
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)) {
457 bad_message_ = true;
458 return 0;
461 uint32 remove_mask = 0;
462 for (base::DictionaryValue::Iterator i(*data_to_remove); !i.IsAtEnd();
463 i.Advance()) {
464 bool selected = false;
465 if (!i.value().GetAsBoolean(&selected)) {
466 bad_message_ = true;
467 return 0;
469 if (selected)
470 remove_mask |= MaskForKey(i.key().c_str());
473 return remove_mask;
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));
482 DCHECK(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)) {
487 ms_since_epoch = 0;
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();
499 if (bad_message_)
500 return false;
502 AddRef(); // Balanced below or in WebViewInternalClearDataFunction::Done().
504 bool scheduled = false;
505 if (remove_mask_) {
506 scheduled = guest->ClearData(
507 remove_since_,
508 remove_mask_,
509 base::Bind(&WebViewInternalClearDataFunction::ClearDataDone, this));
511 if (!remove_mask_ || !scheduled) {
512 SendResponse(false);
513 Release(); // Balanced above.
514 return false;
517 // Will finish asynchronously.
518 return true;
521 void WebViewInternalClearDataFunction::ClearDataDone() {
522 Release(); // Balanced in RunAsync().
523 SendResponse(true);
526 } // namespace extensions