[M47_2526] Chromium upversion to m47_2526 branch
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / eweb_context.cc
1 // Copyright 2014-2015 Samsung Electronics. 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 "eweb_context.h"
6
7 #include "base/synchronization/waitable_event.h"
8 #include "components/autofill/content/browser/content_autofill_driver.h"
9 #include "content/public/browser/appcache_service.h"
10 #include "content/public/browser/browser_context.h"
11 #include "content/public/browser/browser_thread.h"
12 #include "content/public/browser/storage_partition.h"
13 #include "content/public/browser/render_process_host.h"
14 #include "content/public/browser/local_storage_usage_info.h"
15 #include "content/public/browser/dom_storage_context.h"
16 #include "browser/favicon/favicon_service.h"
17 #include "browser/webdata/web_data_service_factory.h"
18 #include "ui/gl/gl_shared_context_efl.h"
19 #include "net/http/http_cache.h"
20 #include "net/proxy/proxy_config_service_fixed.h"
21 #include "net/proxy/proxy_service.h"
22 #include "storage/browser/database/database_quota_client.h"
23 #include "storage/browser/fileapi/file_system_quota_client.h"
24 #include "storage/browser/quota/quota_manager.h"
25
26 #if defined(ENABLE_PLUGINS)
27 #include "content/common/plugin_list.h"
28 #endif
29
30 #include "browser_context_efl.h"
31 #include "ewk_global_data.h"
32 #include "memory_purger.h"
33 #include "browser/password_manager/password_manager.h"
34 #include "browser/password_manager/password_store_factory.h"
35 #include "browser/browsing_data_remover_efl.h"
36 #include "browser/vibration/vibration_provider_client.h"
37 #include "content/common/render_messages_efl.h"
38 #include "private/ewk_security_origin_private.h"
39 #include "wrt/wrt_widget_host.h"
40
41 using content::BrowserThread;
42 using content::BrowserContext;
43 using content::BrowserContextEfl;
44
45 using std::string;
46 using std::pair;
47 using std::map;
48
49 EWebContext* EWebContext::default_context_ = NULL;
50
51 namespace {
52
53 static const char* tizenExtensibleAPINames[] = {
54     "background,music", "csp", "encrypted,database", "fullscreen",
55     "fullscreen,forbid,auto,exit", "mediastream,record", "media,volume,control",
56     "prerendering,for,rotation", "rotate,camera,view", "rotation,lock",
57     "sound,mode", "support,fullscreen", "visibility,suspend",
58     "xwindow,for,fullscreen,video", "support,multimedia"};
59
60 /**
61  * @brief Helper class for obtaining WebStorage origins
62  */
63 class WebStorageGetAllOriginsDispatcher: public base::RefCountedThreadSafe<WebStorageGetAllOriginsDispatcher> {
64 public:
65   WebStorageGetAllOriginsDispatcher(Ewk_Web_Storage_Origins_Get_Callback callback, void* user_data)
66     : callback_(callback)
67     , user_data_(user_data) {
68     DCHECK(callback_);
69     DCHECK(user_data_);
70   }
71
72   void Dispatch(const std::vector<content::LocalStorageUsageInfo> &local_storage) {
73     DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
74
75     Eina_List* lorigins = NULL;
76
77     std::vector<content::LocalStorageUsageInfo>::const_iterator it;
78
79     for (it = local_storage.begin(); it != local_storage.end(); it++) {
80       _Ewk_Security_Origin* origin = new _Ewk_Security_Origin(it->origin);
81       lorigins = eina_list_append(lorigins, origin);
82     }
83
84     callback_(lorigins, user_data_);
85   }
86
87 private:
88   Ewk_Web_Storage_Origins_Get_Callback callback_;
89   void* user_data_;
90 };
91
92 void SetProxyConfigCallbackOnIOThread(base::WaitableEvent* done,
93                             net::URLRequestContextGetter* url_request_context_getter,
94                             const net::ProxyConfig& proxy_config) {
95   net::ProxyService* proxy_service =
96       url_request_context_getter->GetURLRequestContext()->proxy_service();
97   proxy_service->ResetConfigService(
98       make_scoped_ptr(new net::ProxyConfigServiceFixed(proxy_config)));
99   done->Signal();
100 }
101
102 void OnOriginsWithApplicationCacheObtained(Ewk_Web_Application_Cache_Origins_Get_Callback callback,
103                                            void* user_data,
104                                            scoped_refptr<content::AppCacheInfoCollection> collection,
105                                            int result) {
106   Eina_List* origins = 0;
107   for (map<GURL, content::AppCacheInfoVector>::iterator iter = collection->infos_by_origin.begin();
108       iter != collection->infos_by_origin.end();
109       ++iter) {
110     _Ewk_Security_Origin* origin = new _Ewk_Security_Origin(iter->first);
111     origins = eina_list_append(origins, origin);
112   }
113   callback(origins, user_data);
114 }
115
116 void OnTemporaryUsageAndQuotaObtained(
117     Ewk_Web_Application_Cache_Usage_For_Origin_Get_Callback callback,
118     void* user_data,
119     storage::QuotaStatusCode status_code,
120     int64 usage,
121     int64 quota) {
122   if (status_code != storage::kQuotaStatusOk) {
123     LOG(ERROR) << "Error in retrieving usage information";
124     // We still trigger callback.
125     usage = 0;
126   }
127   BrowserThread::PostTask(BrowserThread::UI,
128                           FROM_HERE,
129                           base::Bind(callback, usage, user_data));
130 }
131
132 void OnGetWebDBOrigins(
133     Ewk_Web_Database_Origins_Get_Callback callback,
134     void* user_data,
135     const std::set<GURL>& origins_ref) {
136   Eina_List* origins = 0;
137   for (std::set<GURL>::iterator iter =
138          origins_ref.begin();
139          iter != origins_ref.end(); ++iter) {
140       _Ewk_Security_Origin* sec_origin = new _Ewk_Security_Origin(*iter);
141       origins = eina_list_append(origins, sec_origin);
142   }
143   BrowserThread::PostTask(BrowserThread::UI,
144                           FROM_HERE,
145                           base::Bind(callback, origins, user_data));
146 }
147
148 void GetWebDBOriginsOnDBThread(Ewk_Web_Database_Origins_Get_Callback callback,
149                                void* user_data,
150                                content::StoragePartition* partition) {
151   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
152   storage::DatabaseQuotaClient client(
153       base::ThreadTaskRunnerHandle::Get().get(),
154       partition->GetDatabaseTracker());
155   client.GetOriginsForType(storage::kStorageTypeTemporary,
156                            base::Bind(&OnGetWebDBOrigins, callback, user_data));
157 }
158
159 void OnGetFileSystemOrigins(
160     Ewk_Local_File_System_Origins_Get_Callback callback,
161     void* user_data,
162     const std::set<GURL>& origins_ref) {
163   Eina_List* origins = 0;
164   for (std::set<GURL>::iterator iter =
165          origins_ref.begin();
166          iter != origins_ref.end(); ++iter) {
167       _Ewk_Security_Origin* sec_origin = new _Ewk_Security_Origin(*iter);
168       origins = eina_list_append(origins, sec_origin);
169   }
170   BrowserThread::PostTask(BrowserThread::UI,
171                           FROM_HERE,
172                           base::Bind(callback, origins, user_data));
173 }
174
175 void GetFileSystemOriginsOnFILEThread(Ewk_Web_Database_Origins_Get_Callback callback,
176                                     void* user_data,
177                                     content::StoragePartition* partition) {
178   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE));
179   scoped_ptr<storage::FileSystemQuotaClient> client( new storage::FileSystemQuotaClient(partition->GetFileSystemContext(), false));
180
181   client->GetOriginsForType(storage::kStorageTypeTemporary,
182                             base::Bind(&OnGetFileSystemOrigins, callback, user_data));
183 }
184
185 } // namespace
186
187 void EwkDidStartDownloadCallback::TriggerCallback(const string& url) {
188   if(callback_)
189     (*callback_)(url.c_str(),user_data_);
190 }
191
192 bool EwkMimeOverrideCallback::TriggerCallback(const std::string& url_spec,
193                                               const std::string& mime_type,
194                                               char** new_mime_type) const {
195   if (!callback_)
196     return false;
197   Eina_Bool result = (*callback_)(url_spec.c_str(), mime_type.c_str(),
198                                   new_mime_type, user_data_);
199   return result;
200 }
201
202 void EWebContext::SendWidgetInfo(const std::string& tizen_id, double scale, const string &theme, const string &encoded_bundle) {
203   tizen_id_ = tizen_id;
204   widget_scale_ = scale;
205   widget_theme_ = theme;
206   widget_encoded_bundle_ = encoded_bundle;
207 }
208
209 void EWebContext::SendWrtMessage(const Ewk_Wrt_Message_Data& data) {
210   WrtWidgetHost::Get()->SendWrtMessage(data);
211 }
212
213 void EWebContext::SetMimeOverrideCallback(
214     Ewk_Context_Override_Mime_For_Url_Callback callback, void* user_data) {
215   mime_override_callback_.reset(new EwkMimeOverrideCallback(callback,
216                                                             user_data));
217 }
218
219 bool EWebContext::OverrideMimeForURL(const std::string& url_spec,
220                                      const std::string& mime_type,
221                                      std::string& new_mime_type) const {
222   if (!mime_override_callback_)
223     return false;
224   char *new_mime_type_string = NULL;
225   bool overridden = mime_override_callback_->TriggerCallback(
226       url_spec, mime_type, &new_mime_type_string);
227   if (overridden) {
228     DCHECK(new_mime_type_string);
229     new_mime_type.assign(new_mime_type_string);
230     ::free(new_mime_type_string);
231     return true;
232   }
233   return false;
234 }
235
236 EWebContext::EWebContext(bool incognito)
237     : m_pixmap(0),
238       inspector_server_(NULL),
239       widget_scale_(0) {
240   CHECK(EwkGlobalData::GetInstance());
241
242   browser_context_.reset(new BrowserContextEfl(this, incognito));
243   // Notification Service gets init in BrowserMainRunner init,
244   // so cache manager can register for notifications only after that.
245   web_cache_manager_.reset(new WebCacheManagerEfl(browser_context_.get()));
246   notification_cb_.reset(
247       new EWebContextNotificationCallback(nullptr, nullptr, nullptr, nullptr));
248 }
249
250 EWebContext::EWebContext(const std::string& injectedBundlePath)
251     : injected_bundle_path_(injectedBundlePath),
252       m_pixmap(0),
253       inspector_server_(NULL) {
254   CHECK(EwkGlobalData::GetInstance());
255
256   // WRT does not really care about incognito, so set it to false
257   browser_context_.reset(new BrowserContextEfl(this, false));
258   web_cache_manager_.reset(new WebCacheManagerEfl(browser_context_.get()));
259   notification_cb_.reset(
260       new EWebContextNotificationCallback(nullptr, nullptr, nullptr, nullptr));
261 }
262
263 EWebContext::~EWebContext() {
264 }
265
266 void EWebContext::ClearNetworkCache() {
267   BrowsingDataRemoverEfl* remover = BrowsingDataRemoverEfl::CreateForUnboundedRange(browser_context_.get());
268   remover->ClearNetworkCache();
269   //remover deletes itself once it is done with clearing operation.
270   return;
271 }
272
273 void EWebContext::ClearWebkitCache() {
274   if (web_cache_manager_)
275     web_cache_manager_->ClearCache();
276 }
277
278 void EWebContext::SetCacheModel(Ewk_Cache_Model model) {
279   if (web_cache_manager_)
280     web_cache_manager_->SetCacheModel(model);
281 }
282
283 Ewk_Cache_Model EWebContext::GetCacheModel() const {
284   return web_cache_manager_->GetCacheModel();
285 }
286
287 void EWebContext::SetNetworkCacheEnable(bool enable) {
288   net::URLRequestContext* url_context = browser_context_->GetRequestContext()->GetURLRequestContext();
289   if (!url_context)
290     return;
291
292   net::HttpTransactionFactory* transaction_factory = url_context->http_transaction_factory();
293   if (!transaction_factory)
294     return;
295
296   net::HttpCache* http_cache = transaction_factory->GetCache();
297   if (!http_cache)
298     return;
299
300   if (enable)
301     http_cache->set_mode(net::HttpCache::NORMAL);
302   else
303     http_cache->set_mode(net::HttpCache::DISABLE);
304 }
305
306 bool EWebContext::GetNetworkCacheEnable() const {
307   net::HttpCache* http_cache = browser_context_->GetRequestContext()->GetURLRequestContext()->
308       http_transaction_factory()->GetCache();
309   if (!http_cache)
310     return false;
311
312   return (http_cache->mode() != net::HttpCache::DISABLE);
313 }
314
315 void EWebContext::AddExtraPluginDir(const char *path) {
316 #if defined(ENABLE_PLUGINS)
317   content::PluginList::Singleton()->AddExtraPluginDir(base::FilePath(path));
318 #endif
319 }
320
321 void EWebContext::SetCertificate(const char* certificate_file) {
322   browser_context_->SetCertificate(certificate_file);
323 }
324
325 void EWebContext::NotifyLowMemory() {
326   MemoryPurger::PurgeAll(browser_context_.get());
327 }
328
329 void EWebContext::SetProxyUri(const char* uri) {
330   proxy_uri_ = string(uri);
331   net::ProxyConfig config;
332   config.proxy_rules().ParseFromString(proxy_uri_);
333   base::WaitableEvent done(false, false);
334   BrowserThread::PostTask(
335       BrowserThread::IO, FROM_HERE,
336       base::Bind(&SetProxyConfigCallbackOnIOThread, &done,
337                  make_scoped_refptr(browser_context()->GetRequestContext()),
338                  config));
339   done.Wait();
340 }
341
342 void EWebContext::SetDidStartDownloadCallback(Ewk_Context_Did_Start_Download_Callback callback,
343                                               void* user_data) {
344   DCHECK(start_download_callback_.get() == NULL);
345   start_download_callback_.reset(new EwkDidStartDownloadCallback(callback,user_data));
346 }
347
348 EwkDidStartDownloadCallback* EWebContext::DidStartDownloadCallback() {
349   return start_download_callback_.get();
350 }
351
352 Ewk_Cookie_Manager* EWebContext::ewkCookieManager() {
353   if (!ewk_cookie_manager_)
354     ewk_cookie_manager_.reset(Ewk_Cookie_Manager::create());
355   return ewk_cookie_manager_.get();
356 }
357
358 void EWebContext::DeleteAllApplicationCache() {
359   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
360     BrowserThread::PostTask(
361         BrowserThread::UI, FROM_HERE,
362         base::Bind(&EWebContext::DeleteAllApplicationCache,
363           base::Unretained(this)));
364     return;
365   }
366   BrowsingDataRemoverEfl* remover = BrowsingDataRemoverEfl::CreateForUnboundedRange(browser_context_.get());
367   remover->RemoveImpl(BrowsingDataRemoverEfl::REMOVE_APPCACHE, GURL());
368 }
369
370 void EWebContext::DeleteApplicationCacheForSite(const GURL& site) {
371   content::StoragePartition* partition = BrowserContext::GetStoragePartitionForSite(browser_context_.get(),
372                                                                                     site);
373   partition->ClearDataForOrigin(content::StoragePartition::REMOVE_DATA_MASK_APPCACHE,
374                                 content::StoragePartition::QUOTA_MANAGED_STORAGE_MASK_ALL,
375                                 site,
376                                 partition->GetURLRequestContext(), base::Bind(&base::DoNothing));
377 }
378
379 void EWebContext::GetAllOriginsWithApplicationCache(Ewk_Web_Application_Cache_Origins_Get_Callback callback,
380                                                     void* user_data) {
381   content::StoragePartition* partition =
382       BrowserContext::GetStoragePartition(browser_context_.get(), NULL);
383
384   scoped_refptr<content::AppCacheInfoCollection> collection(new content::AppCacheInfoCollection());
385   // As per comments on AppCacheService,
386   // there is only one instance of AppCacheService per profile.(i.e. context in our case).
387   // So, we don't need to iterate over all StoragePartitions.
388   partition->GetAppCacheService()->GetAllAppCacheInfo(collection.get(),
389       base::Bind(&OnOriginsWithApplicationCacheObtained, callback, user_data, collection));
390 }
391
392 void EWebContext::GetApplicationCacheUsage(
393     const GURL& url,
394     Ewk_Web_Application_Cache_Usage_For_Origin_Get_Callback callback,
395     void* user_data) {
396   content::StoragePartition* partition =
397         BrowserContext::GetStoragePartition(browser_context_.get(), NULL);
398
399   BrowserThread::PostTask(
400       BrowserThread::IO,
401       FROM_HERE,
402       base::Bind(&storage::QuotaManager::GetUsageAndQuota,
403                  partition->GetQuotaManager(),
404                  url,
405                  storage::kStorageTypeTemporary,
406                  base::Bind(&OnTemporaryUsageAndQuotaObtained, callback, user_data)));
407 }
408
409 void EWebContext::WebStorageDelete() {
410   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
411     BrowserThread::PostTask(
412         BrowserThread::UI, FROM_HERE,
413         base::Bind(&EWebContext::WebStorageDelete,
414           base::Unretained(this)));
415     return;
416   }
417   BrowsingDataRemoverEfl* remover = BrowsingDataRemoverEfl::CreateForUnboundedRange(browser_context_.get());
418   remover->RemoveImpl(BrowsingDataRemoverEfl::REMOVE_LOCAL_STORAGE, GURL());
419 }
420
421 void EWebContext::WebStorageDeleteForOrigin(const GURL& origin) {
422   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
423     BrowserThread::PostTask(
424         BrowserThread::UI, FROM_HERE,
425         base::Bind(&EWebContext::WebStorageDeleteForOrigin,
426           base::Unretained(this), origin));
427     return;
428   }
429   content::StoragePartition* partition =
430       BrowserContext::GetStoragePartition(browser_context_.get(), NULL);
431
432   partition->GetDOMStorageContext()->DeleteLocalStorage(origin);
433 }
434
435 void EWebContext::WebStorageOriginsAllGet(Ewk_Web_Storage_Origins_Get_Callback callback,
436                                                     void* user_data) {
437   content::StoragePartition* partition =
438       BrowserContext::GetStoragePartition(browser_context_.get(), NULL);
439
440   WebStorageGetAllOriginsDispatcher* dispatcher = new WebStorageGetAllOriginsDispatcher(callback, user_data);
441
442   partition->GetDOMStorageContext()->GetLocalStorageUsage(base::Bind(&WebStorageGetAllOriginsDispatcher::Dispatch, dispatcher));
443 }
444
445 void EWebContext::IndexedDBDelete() {
446   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
447     BrowserThread::PostTask(
448         BrowserThread::UI, FROM_HERE,
449         base::Bind(&EWebContext::IndexedDBDelete,
450           base::Unretained(this)));
451     return;
452   }
453   BrowsingDataRemoverEfl* remover = BrowsingDataRemoverEfl::CreateForUnboundedRange(browser_context_.get());
454   remover->RemoveImpl(BrowsingDataRemoverEfl::REMOVE_INDEXEDDB, GURL());
455 }
456
457 void EWebContext::WebDBDelete(const GURL& host) {
458   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
459     BrowserThread::PostTask(
460         BrowserThread::UI, FROM_HERE,
461         base::Bind(&EWebContext::WebDBDelete,
462           base::Unretained(this), host));
463     return;
464   }
465   BrowsingDataRemoverEfl* remover = BrowsingDataRemoverEfl::CreateForUnboundedRange(browser_context_.get());
466   remover->RemoveImpl(BrowsingDataRemoverEfl::REMOVE_WEBSQL, host);
467 }
468
469 void EWebContext::GetAllOriginsWithWebDB(Ewk_Web_Database_Origins_Get_Callback callback, void* user_data) {
470   content::StoragePartition* partition = BrowserContext::GetStoragePartition(browser_context_.get(), NULL);
471   BrowserThread::PostTask(
472       BrowserThread::DB,
473       FROM_HERE,
474       base::Bind(&GetWebDBOriginsOnDBThread,
475                  callback, user_data, partition));
476 }
477
478 void EWebContext::FileSystemDelete(const GURL& host) {
479   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
480     BrowserThread::PostTask(
481         BrowserThread::UI, FROM_HERE,
482         base::Bind(&EWebContext::FileSystemDelete,
483           base::Unretained(this), host));
484     return;
485   }
486   BrowsingDataRemoverEfl* remover = BrowsingDataRemoverEfl::CreateForUnboundedRange(browser_context_.get());
487   remover->RemoveImpl(BrowsingDataRemoverEfl::REMOVE_FILE_SYSTEMS, host);
488 }
489
490 void EWebContext::GetAllOriginsWithFileSystem(Ewk_Local_File_System_Origins_Get_Callback callback, void* user_data) const {
491   content::StoragePartition* partition = BrowserContext::GetStoragePartition(browser_context_.get(), NULL);
492   BrowserThread::PostTask(
493       BrowserThread::FILE,
494       FROM_HERE,
495         base::Bind(&GetFileSystemOriginsOnFILEThread, callback, user_data, partition));
496 }
497
498 bool EWebContext::SetFaviconDatabasePath(const char* path) {
499   FaviconService fs;
500   return fs.SetDatabasePath(path);
501 }
502
503 #if defined(OS_TIZEN_TV)
504 FaviconDatabase* EWebContext::GetFaviconDatabase() {
505   return FaviconService::GetFaviconDatabase();
506 }
507 #endif
508
509 Evas_Object *EWebContext::AddFaviconObject(const char* uri, Evas* canvas) const {
510   if (uri == NULL || canvas == NULL) {
511     return NULL;
512   }
513   FaviconService fs;
514   SkBitmap bitmap = fs.GetBitmapForPageURL(GURL(uri));
515   if (bitmap.isNull()) {
516     return NULL;
517   }
518
519   Evas_Object *favicon = evas_object_image_filled_add(canvas);
520   evas_object_image_size_set(favicon, bitmap.width(), bitmap.height());
521   evas_object_image_colorspace_set(favicon, EVAS_COLORSPACE_ARGB8888);
522   evas_object_image_fill_set(favicon, 0, 0, bitmap.width(), bitmap.height());
523   evas_object_image_filled_set(favicon, EINA_TRUE);
524   evas_object_image_alpha_set(favicon, EINA_TRUE);
525   void* pixels = evas_object_image_data_get(favicon, EINA_TRUE);
526   if (pixels) {
527     bitmap.copyPixelsTo(pixels, bitmap.getSize());
528     evas_object_image_data_set(favicon, pixels);
529   }
530
531   return favicon;
532 }
533
534 void EWebContext::ClearCandidateData() {
535 #if defined(TIZEN_AUTOFILL_SUPPORT)
536   if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) {
537     BrowserThread::PostTask(
538         BrowserThread::UI, FROM_HERE,
539         base::Bind(&EWebContext::ClearCandidateData,
540           base::Unretained(this)));
541     return;
542   }
543   WebDataServiceFactory* webDataServiceInstance =
544       WebDataServiceFactory::GetInstance();
545   scoped_refptr<autofill::AutofillWebDataService> autofillWebDataService =
546       webDataServiceInstance->GetAutofillWebDataForProfile();
547   if (autofillWebDataService.get()) {
548     // RemoveFormElementsAddedBetween will schedule task on proper thread,
549     // it is done in WebDatabaseService::ScheduleDBTask
550     autofillWebDataService->RemoveFormElementsAddedBetween(
551         base::Time(),
552         base::Time::Max());
553   } else {
554     DLOG(WARNING) << "AutofillWebDataService is NULL";
555   }
556 #else
557   DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled";
558 #endif
559 }
560
561 void EWebContext::ClearPasswordData() {
562 #if defined(TIZEN_AUTOFILL_SUPPORT)
563   scoped_refptr<password_manager::PasswordStore> store =
564       password_manager::PasswordStoreFactory::GetPasswordStore();
565   if (store.get())
566     store->RemoveLoginsCreatedBetween(base::Time(), base::Time::Max(), base::Closure());
567 #else
568   DLOG(WARNING) << "TIZEN_AUTOFILL_SUPPORT is not enabled";
569 #endif
570 }
571
572 unsigned int EWebContext::InspectorServerStart(unsigned int port) {
573   InspectorServerStop();
574   inspector_server_ = new devtools_http_handler::DevToolsDelegateEfl(port);
575   return inspector_server_ ? inspector_server_->port() : 0;
576 }
577
578 bool EWebContext::InspectorServerStop() {
579   if (!inspector_server_)
580     return false;
581   // The call below destroys inspector_server_.
582   inspector_server_->Stop();
583   inspector_server_ = NULL;
584   return true;
585 }
586
587 void EWebContext::SetNotificationCallbacks(
588     Ewk_Context* context,
589     Ewk_Context_Notification_Show_Callback show_callback,
590     Ewk_Context_Notification_Cancel_Callback cancel_callback,
591     void* user_data) {
592   notification_cb_.reset(
593       new EWebContextNotificationCallback(
594           context, show_callback, cancel_callback, user_data));
595 }
596
597 bool EWebContext::HasNotificationCallbacks() const {
598   return notification_cb_->HasShowCallback() &&
599       notification_cb_->HasCancelCallback();
600 }
601
602 bool EWebContext::NotificationShowCallback(Ewk_Notification* notification) {
603   return notification_cb_->RunShowCallback(notification);
604 }
605
606 bool EWebContext::NotificationCancelCallback(uint64_t notification_id) {
607   return notification_cb_->RunCancelCallback(notification_id);
608 }
609
610 int EWebContext::GetExtensibleAPIEnumFromName(const char* extensible_api_name) const {
611   if (extensible_api_name == NULL)
612     return -1;
613   string extensible_string(extensible_api_name);
614   std::transform(extensible_string.begin(),
615                  extensible_string.end(),
616                  extensible_string.begin(),
617                  ::tolower);
618   for (int i = 0; i < static_cast<int>(EWK_MAX_EXTENSIBLE_API); ++i) {
619     if (extensible_string.compare(tizenExtensibleAPINames[i]) == 0)
620       return i;
621   }
622   return -1;
623 }
624
625 bool EWebContext::SetExtensibleAPI(int extensible_api, bool enable) {
626   if (!tizen_extensible_)
627     tizen_extensible_.reset(TizenExtensible::create());
628
629   return tizen_extensible_->SetAPI(
630       static_cast<ExtensibleAPI>(extensible_api), enable);
631 }
632
633 bool EWebContext::GetExtensibleAPI(int extensible_api) {
634   if (!tizen_extensible_)
635     tizen_extensible_.reset(TizenExtensible::create());
636
637   return tizen_extensible_->GetAPI(
638       static_cast<ExtensibleAPI>(extensible_api));
639 }