- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / webview / webview_api.cc
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.
4
5 #include "chrome/browser/extensions/api/webview/webview_api.h"
6
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"
16
17 using extensions::api::tabs::InjectDetails;
18 using extensions::api::webview::SetPermission::Params;
19 namespace webview = extensions::api::webview;
20
21 namespace extensions {
22
23 namespace {
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;
37   return 0;
38 }
39
40 }  // namespace
41
42 bool WebviewExtensionFunction::RunImpl() {
43   int instance_id = 0;
44   EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &instance_id));
45   WebViewGuest* guest = WebViewGuest::From(
46       render_view_host()->GetProcess()->GetID(), instance_id);
47   if (!guest)
48     return false;
49
50   return RunImplSafe(guest);
51 }
52
53 WebviewClearDataFunction::WebviewClearDataFunction()
54     : remove_mask_(0),
55       bad_message_(false) {
56 };
57
58 WebviewClearDataFunction::~WebviewClearDataFunction() {
59 };
60
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)) {
67     bad_message_ = true;
68     return 0;
69   }
70
71   uint32 remove_mask = 0;
72   for (base::DictionaryValue::Iterator i(*data_to_remove);
73        !i.IsAtEnd();
74        i.Advance()) {
75     bool selected = false;
76     if (!i.value().GetAsBoolean(&selected)) {
77       bad_message_ = true;
78       return 0;
79     }
80     if (selected)
81       remove_mask |= MaskForKey(i.key().c_str());
82   }
83
84   return remove_mask;
85 }
86
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"));
91
92   // Grab the initial |options| parameter, and parse out the arguments.
93   base::DictionaryValue* options;
94   EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &options));
95   DCHECK(options);
96
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,
100                           &ms_since_epoch)) {
101     ms_since_epoch = 0;
102   }
103
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);
111
112   remove_mask_ = GetRemovalMask();
113   if (bad_message_)
114     return false;
115
116   AddRef();  // Balanced below or in WebviewClearDataFunction::Done().
117
118   bool scheduled = false;
119   if (remove_mask_) {
120     scheduled = guest->ClearData(
121         remove_since_,
122         remove_mask_,
123         base::Bind(&WebviewClearDataFunction::ClearDataDone,
124                    this));
125   }
126   if (!remove_mask_ || !scheduled) {
127     SendResponse(false);
128     Release();  // Balanced above.
129     return false;
130   }
131
132   // Will finish asynchronously.
133   return true;
134 }
135
136 void WebviewClearDataFunction::ClearDataDone() {
137   Release();  // Balanced in RunImpl().
138   SendResponse(true);
139 }
140
141 WebviewExecuteCodeFunction::WebviewExecuteCodeFunction()
142     : guest_instance_id_(0) {
143 }
144
145 WebviewExecuteCodeFunction::~WebviewExecuteCodeFunction() {
146 }
147
148 bool WebviewExecuteCodeFunction::Init() {
149   if (details_.get())
150     return true;
151
152   if (!args_->GetInteger(0, &guest_instance_id_))
153     return false;
154
155   if (!guest_instance_id_)
156     return false;
157
158   base::DictionaryValue* details_value = NULL;
159   if (!args_->GetDictionary(1, &details_value))
160     return false;
161   scoped_ptr<InjectDetails> details(new InjectDetails());
162   if (!InjectDetails::Populate(*details_value, details.get()))
163     return false;
164
165   details_ = details.Pass();
166   return true;
167 }
168
169 bool WebviewExecuteCodeFunction::ShouldInsertCSS() const {
170   return false;
171 }
172
173 bool WebviewExecuteCodeFunction::CanExecuteScriptOnPage() {
174   return true;
175 }
176
177 extensions::ScriptExecutor* WebviewExecuteCodeFunction::GetScriptExecutor() {
178   WebViewGuest* guest = WebViewGuest::From(
179       render_view_host()->GetProcess()->GetID(), guest_instance_id_);
180   if (!guest)
181     return NULL;
182
183   return guest->script_executor();
184 }
185
186 bool WebviewExecuteCodeFunction::IsWebView() const {
187   return true;
188 }
189
190 WebviewExecuteScriptFunction::WebviewExecuteScriptFunction() {
191 }
192
193 void WebviewExecuteScriptFunction::OnExecuteCodeFinished(
194     const std::string& error,
195     int32 on_page_id,
196     const GURL& on_url,
197     const base::ListValue& result) {
198   content::RecordAction(content::UserMetricsAction("WebView.ExecuteScript"));
199   if (error.empty())
200     SetResult(result.DeepCopy());
201   WebviewExecuteCodeFunction::OnExecuteCodeFinished(error, on_page_id, on_url,
202                                                     result);
203 }
204
205 WebviewInsertCSSFunction::WebviewInsertCSSFunction() {
206 }
207
208 bool WebviewInsertCSSFunction::ShouldInsertCSS() const {
209   return true;
210 }
211
212 WebviewGoFunction::WebviewGoFunction() {
213 }
214
215 WebviewGoFunction::~WebviewGoFunction() {
216 }
217
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());
222
223   guest->Go(params->relative_index);
224   return true;
225 }
226
227 WebviewReloadFunction::WebviewReloadFunction() {
228 }
229
230 WebviewReloadFunction::~WebviewReloadFunction() {
231 }
232
233 bool WebviewReloadFunction::RunImplSafe(WebViewGuest* guest) {
234   content::RecordAction(content::UserMetricsAction("WebView.Reload"));
235   guest->Reload();
236   return true;
237 }
238
239 WebviewSetPermissionFunction::WebviewSetPermissionFunction() {
240 }
241
242 WebviewSetPermissionFunction::~WebviewSetPermissionFunction() {
243 }
244
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());
249
250   WebViewGuest::PermissionResponseAction action = WebViewGuest::DEFAULT;
251   switch (params->action) {
252     case Params::ACTION_ALLOW:
253       action = WebViewGuest::ALLOW;
254       break;
255     case Params::ACTION_DENY:
256       action = WebViewGuest::DENY;
257       break;
258     case Params::ACTION_DEFAULT:
259       break;
260     default:
261       NOTREACHED();
262   }
263
264   std::string user_input;
265   if (params->user_input)
266     user_input = *params->user_input;
267
268   WebViewGuest::SetPermissionResult result =
269       guest->SetPermission(params->request_id, action, user_input);
270
271   EXTENSION_FUNCTION_VALIDATE(result != WebViewGuest::SET_PERMISSION_INVALID);
272
273   SetResult(base::Value::CreateBooleanValue(
274       result == WebViewGuest::SET_PERMISSION_ALLOWED));
275   SendResponse(true);
276   return true;
277 }
278
279 WebviewOverrideUserAgentFunction::WebviewOverrideUserAgentFunction() {
280 }
281
282 WebviewOverrideUserAgentFunction::~WebviewOverrideUserAgentFunction() {
283 }
284
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());
289
290   guest->SetUserAgentOverride(params->user_agent_override);
291   return true;
292 }
293
294 WebviewStopFunction::WebviewStopFunction() {
295 }
296
297 WebviewStopFunction::~WebviewStopFunction() {
298 }
299
300 bool WebviewStopFunction::RunImplSafe(WebViewGuest* guest) {
301   content::RecordAction(content::UserMetricsAction("WebView.Stop"));
302   guest->Stop();
303   return true;
304 }
305
306 WebviewTerminateFunction::WebviewTerminateFunction() {
307 }
308
309 WebviewTerminateFunction::~WebviewTerminateFunction() {
310 }
311
312 bool WebviewTerminateFunction::RunImplSafe(WebViewGuest* guest) {
313   content::RecordAction(content::UserMetricsAction("WebView.Terminate"));
314   guest->Terminate();
315   return true;
316 }
317
318 }  // namespace extensions