1 // Copyright (c) 2013 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 "chrome/browser/extensions/api/webview/webview_api.h"
7 #include "chrome/browser/extensions/api/browsing_data/browsing_data_api.h"
8 #include "chrome/browser/extensions/tab_helper.h"
9 #include "chrome/common/extensions/api/webview.h"
10 #include "content/public/browser/render_process_host.h"
11 #include "content/public/browser/render_view_host.h"
12 #include "content/public/browser/storage_partition.h"
13 #include "content/public/browser/user_metrics.h"
14 #include "content/public/browser/web_contents.h"
15 #include "extensions/common/error_utils.h"
17 using extensions::api::tabs::InjectDetails;
18 using extensions::api::webview::SetPermission::Params;
19 namespace webview = extensions::api::webview;
21 namespace extensions {
24 int MaskForKey(const char* key) {
25 if (strcmp(key, extension_browsing_data_api_constants::kAppCacheKey) == 0)
26 return content::StoragePartition::REMOVE_DATA_MASK_APPCACHE;
27 if (strcmp(key, extension_browsing_data_api_constants::kCookiesKey) == 0)
28 return content::StoragePartition::REMOVE_DATA_MASK_COOKIES;
29 if (strcmp(key, extension_browsing_data_api_constants::kFileSystemsKey) == 0)
30 return content::StoragePartition::REMOVE_DATA_MASK_FILE_SYSTEMS;
31 if (strcmp(key, extension_browsing_data_api_constants::kIndexedDBKey) == 0)
32 return content::StoragePartition::REMOVE_DATA_MASK_INDEXEDDB;
33 if (strcmp(key, extension_browsing_data_api_constants::kLocalStorageKey) == 0)
34 return content::StoragePartition::REMOVE_DATA_MASK_LOCAL_STORAGE;
35 if (strcmp(key, extension_browsing_data_api_constants::kWebSQLKey) == 0)
36 return content::StoragePartition::REMOVE_DATA_MASK_WEBSQL;
42 bool WebviewExtensionFunction::RunImpl() {
44 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
45 WebViewGuest* guest = WebViewGuest::From(
46 render_view_host()->GetProcess()->GetID(), instance_id);
50 return RunImplSafe(guest);
53 WebviewClearDataFunction::WebviewClearDataFunction()
58 WebviewClearDataFunction::~WebviewClearDataFunction() {
61 // Parses the |dataToRemove| argument to generate the remove mask. Sets
62 // |bad_message_| (like EXTENSION_FUNCTION_VALIDATE would if this were a bool
63 // method) if 'dataToRemove' is not present.
64 uint32 WebviewClearDataFunction::GetRemovalMask() {
65 base::DictionaryValue* data_to_remove;
66 if (!args_->GetDictionary(2, &data_to_remove)) {
71 uint32 remove_mask = 0;
72 for (base::DictionaryValue::Iterator i(*data_to_remove);
75 bool selected = false;
76 if (!i.value().GetAsBoolean(&selected)) {
81 remove_mask |= MaskForKey(i.key().c_str());
87 // TODO(lazyboy): Parameters in this extension function are similar (or a
88 // sub-set) to BrowsingDataRemoverFunction. How can we share this code?
89 bool WebviewClearDataFunction::RunImplSafe(WebViewGuest* guest) {
90 content::RecordAction(content::UserMetricsAction("WebView.ClearData"));
92 // Grab the initial |options| parameter, and parse out the arguments.
93 base::DictionaryValue* options;
94 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options));
97 // If |ms_since_epoch| isn't set, default it to 0.
98 double ms_since_epoch;
99 if (!options->GetDouble(extension_browsing_data_api_constants::kSinceKey,
104 // base::Time takes a double that represents seconds since epoch. JavaScript
105 // gives developers milliseconds, so do a quick conversion before populating
106 // the object. Also, Time::FromDoubleT converts double time 0 to empty Time
107 // object. So we need to do special handling here.
108 remove_since_ = (ms_since_epoch == 0) ?
109 base::Time::UnixEpoch() :
110 base::Time::FromDoubleT(ms_since_epoch / 1000.0);
112 remove_mask_ = GetRemovalMask();
116 AddRef(); // Balanced below or in WebviewClearDataFunction::Done().
118 bool scheduled = false;
120 scheduled = guest->ClearData(
123 base::Bind(&WebviewClearDataFunction::ClearDataDone,
126 if (!remove_mask_ || !scheduled) {
128 Release(); // Balanced above.
132 // Will finish asynchronously.
136 void WebviewClearDataFunction::ClearDataDone() {
137 Release(); // Balanced in RunImpl().
141 WebviewExecuteCodeFunction::WebviewExecuteCodeFunction()
142 : guest_instance_id_(0) {
145 WebviewExecuteCodeFunction::~WebviewExecuteCodeFunction() {
148 bool WebviewExecuteCodeFunction::Init() {
152 if (!args_->GetInteger(0, &guest_instance_id_))
155 if (!guest_instance_id_)
158 base::DictionaryValue* details_value = NULL;
159 if (!args_->GetDictionary(1, &details_value))
161 scoped_ptr<InjectDetails> details(new InjectDetails());
162 if (!InjectDetails::Populate(*details_value, details.get()))
165 details_ = details.Pass();
169 bool WebviewExecuteCodeFunction::ShouldInsertCSS() const {
173 bool WebviewExecuteCodeFunction::CanExecuteScriptOnPage() {
177 extensions::ScriptExecutor* WebviewExecuteCodeFunction::GetScriptExecutor() {
178 WebViewGuest* guest = WebViewGuest::From(
179 render_view_host()->GetProcess()->GetID(), guest_instance_id_);
183 return guest->script_executor();
186 bool WebviewExecuteCodeFunction::IsWebView() const {
190 WebviewExecuteScriptFunction::WebviewExecuteScriptFunction() {
193 void WebviewExecuteScriptFunction::OnExecuteCodeFinished(
194 const std::string& error,
197 const base::ListValue& result) {
198 content::RecordAction(content::UserMetricsAction("WebView.ExecuteScript"));
200 SetResult(result.DeepCopy());
201 WebviewExecuteCodeFunction::OnExecuteCodeFinished(error, on_page_id, on_url,
205 WebviewInsertCSSFunction::WebviewInsertCSSFunction() {
208 bool WebviewInsertCSSFunction::ShouldInsertCSS() const {
212 WebviewGoFunction::WebviewGoFunction() {
215 WebviewGoFunction::~WebviewGoFunction() {
218 bool WebviewGoFunction::RunImplSafe(WebViewGuest* guest) {
219 content::RecordAction(content::UserMetricsAction("WebView.Go"));
220 scoped_ptr<webview::Go::Params> params(webview::Go::Params::Create(*args_));
221 EXTENSION_FUNCTION_VALIDATE(params.get());
223 guest->Go(params->relative_index);
227 WebviewReloadFunction::WebviewReloadFunction() {
230 WebviewReloadFunction::~WebviewReloadFunction() {
233 bool WebviewReloadFunction::RunImplSafe(WebViewGuest* guest) {
234 content::RecordAction(content::UserMetricsAction("WebView.Reload"));
239 WebviewSetPermissionFunction::WebviewSetPermissionFunction() {
242 WebviewSetPermissionFunction::~WebviewSetPermissionFunction() {
245 bool WebviewSetPermissionFunction::RunImplSafe(WebViewGuest* guest) {
246 scoped_ptr<webview::SetPermission::Params> params(
247 webview::SetPermission::Params::Create(*args_));
248 EXTENSION_FUNCTION_VALIDATE(params.get());
250 WebViewGuest::PermissionResponseAction action = WebViewGuest::DEFAULT;
251 switch (params->action) {
252 case Params::ACTION_ALLOW:
253 action = WebViewGuest::ALLOW;
255 case Params::ACTION_DENY:
256 action = WebViewGuest::DENY;
258 case Params::ACTION_DEFAULT:
264 std::string user_input;
265 if (params->user_input)
266 user_input = *params->user_input;
268 WebViewGuest::SetPermissionResult result =
269 guest->SetPermission(params->request_id, action, user_input);
271 EXTENSION_FUNCTION_VALIDATE(result != WebViewGuest::SET_PERMISSION_INVALID);
273 SetResult(base::Value::CreateBooleanValue(
274 result == WebViewGuest::SET_PERMISSION_ALLOWED));
279 WebviewOverrideUserAgentFunction::WebviewOverrideUserAgentFunction() {
282 WebviewOverrideUserAgentFunction::~WebviewOverrideUserAgentFunction() {
285 bool WebviewOverrideUserAgentFunction::RunImplSafe(WebViewGuest* guest) {
286 scoped_ptr<extensions::api::webview::OverrideUserAgent::Params> params(
287 extensions::api::webview::OverrideUserAgent::Params::Create(*args_));
288 EXTENSION_FUNCTION_VALIDATE(params.get());
290 guest->SetUserAgentOverride(params->user_agent_override);
294 WebviewStopFunction::WebviewStopFunction() {
297 WebviewStopFunction::~WebviewStopFunction() {
300 bool WebviewStopFunction::RunImplSafe(WebViewGuest* guest) {
301 content::RecordAction(content::UserMetricsAction("WebView.Stop"));
306 WebviewTerminateFunction::WebviewTerminateFunction() {
309 WebviewTerminateFunction::~WebviewTerminateFunction() {
312 bool WebviewTerminateFunction::RunImplSafe(WebViewGuest* guest) {
313 content::RecordAction(content::UserMetricsAction("WebView.Terminate"));
318 } // namespace extensions