ozone: evdev: Sync caps lock LED state to evdev
[chromium-blink-merge.git] / chrome / browser / android / preferences / website_preference_bridge.cc
blobf5429b1581ad863d1a0e0c5ab35cf72e94b59d56
1 // Copyright 2015 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/android/preferences/website_preference_bridge.h"
7 #include "base/android/jni_android.h"
8 #include "base/android/jni_string.h"
9 #include "base/android/scoped_java_ref.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/files/file_path.h"
13 #include "chrome/browser/browser_process.h"
14 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h"
15 #include "chrome/browser/browsing_data/cookies_tree_model.h"
16 #include "chrome/browser/browsing_data/local_data_container.h"
17 #include "chrome/browser/content_settings/cookie_settings.h"
18 #include "chrome/browser/content_settings/web_site_settings_uma_util.h"
19 #include "chrome/browser/notifications/desktop_notification_profile_util.h"
20 #include "chrome/browser/profiles/profile.h"
21 #include "chrome/browser/profiles/profile_manager.h"
22 #include "components/content_settings/core/browser/host_content_settings_map.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/storage_partition.h"
25 #include "jni/WebsitePreferenceBridge_jni.h"
26 #include "storage/browser/quota/quota_client.h"
27 #include "storage/browser/quota/quota_manager.h"
28 #include "url/url_constants.h"
30 using base::android::ConvertJavaStringToUTF8;
31 using base::android::ConvertUTF8ToJavaString;
32 using base::android::JavaRef;
33 using base::android::ScopedJavaGlobalRef;
34 using base::android::ScopedJavaLocalRef;
35 using content::BrowserThread;
37 static HostContentSettingsMap* GetHostContentSettingsMap() {
38 Profile* profile = ProfileManager::GetActiveUserProfile();
39 return profile->GetHostContentSettingsMap();
42 static void GetOrigins(JNIEnv* env,
43 ContentSettingsType content_type,
44 jobject list,
45 jboolean managedOnly) {
46 ContentSettingsForOneType all_settings;
47 HostContentSettingsMap* content_settings_map = GetHostContentSettingsMap();
48 content_settings_map->GetSettingsForOneType(
49 content_type, std::string(), &all_settings);
50 ContentSetting default_content_setting = content_settings_map->
51 GetDefaultContentSetting(content_type, NULL);
52 // Now add all origins that have a non-default setting to the list.
53 for (const auto& settings_it : all_settings) {
54 if (settings_it.setting == default_content_setting)
55 continue;
56 if (managedOnly &&
57 HostContentSettingsMap::GetProviderTypeFromSource(settings_it.source) !=
58 HostContentSettingsMap::ProviderType::POLICY_PROVIDER) {
59 continue;
61 const std::string origin = settings_it.primary_pattern.ToString();
62 const std::string embedder = settings_it.secondary_pattern.ToString();
64 // The string |jorigin| is used to group permissions together in the Site
65 // Settings list. In order to group sites with the same origin, remove any
66 // standard port from the end of the URL if it's present (i.e. remove :443
67 // for HTTPS sites and :80 for HTTP sites).
68 // TODO(sashab,lgarron): Find out which settings are being saved with the
69 // port and omit it if it's the standard port.
70 // TODO(mvanouwerkerk): Remove all this logic and take two passes through
71 // HostContentSettingsMap: once to get all the 'interesting' hosts, and once
72 // (on SingleWebsitePreferences) to find permission patterns which match
73 // each of these hosts.
74 const char* kHttpPortSuffix = ":80";
75 const char* kHttpsPortSuffix = ":443";
76 ScopedJavaLocalRef<jstring> jorigin;
77 if (StartsWithASCII(origin, url::kHttpsScheme, false) &&
78 EndsWith(origin, kHttpsPortSuffix, false)) {
79 jorigin = ConvertUTF8ToJavaString(
80 env, origin.substr(0, origin.size() - strlen(kHttpsPortSuffix)));
81 } else if (StartsWithASCII(origin, url::kHttpScheme, false) &&
82 EndsWith(origin, kHttpPortSuffix, false)) {
83 jorigin = ConvertUTF8ToJavaString(
84 env, origin.substr(0, origin.size() - strlen(kHttpPortSuffix)));
85 } else {
86 jorigin = ConvertUTF8ToJavaString(env, origin);
89 ScopedJavaLocalRef<jstring> jembedder;
90 if (embedder != origin)
91 jembedder = ConvertUTF8ToJavaString(env, embedder);
92 switch (content_type) {
93 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
94 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
95 Java_WebsitePreferenceBridge_insertVoiceAndVideoCaptureInfoIntoList(
96 env, list, jorigin.obj(), jembedder.obj());
97 break;
98 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
99 Java_WebsitePreferenceBridge_insertGeolocationInfoIntoList(
100 env, list, jorigin.obj(), jembedder.obj());
101 break;
102 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
103 Java_WebsitePreferenceBridge_insertMidiInfoIntoList(
104 env, list, jorigin.obj(), jembedder.obj());
105 break;
106 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
107 Java_WebsitePreferenceBridge_insertProtectedMediaIdentifierInfoIntoList(
108 env, list, jorigin.obj(), jembedder.obj());
109 break;
110 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
111 Java_WebsitePreferenceBridge_insertPushNotificationIntoList(
112 env, list, jorigin.obj(), jembedder.obj());
113 break;
114 default:
115 DCHECK(false);
116 break;
121 static jint GetSettingForOrigin(JNIEnv* env,
122 ContentSettingsType content_type,
123 jstring origin,
124 jstring embedder) {
125 GURL url(ConvertJavaStringToUTF8(env, origin));
126 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
127 ContentSetting setting = GetHostContentSettingsMap()->GetContentSetting(
128 url,
129 embedder_url,
130 content_type,
131 std::string());
132 return setting;
135 static void SetSettingForOrigin(JNIEnv* env,
136 ContentSettingsType content_type,
137 jstring origin,
138 ContentSettingsPattern secondary_pattern,
139 jint value) {
140 GURL url(ConvertJavaStringToUTF8(env, origin));
141 ContentSetting setting = CONTENT_SETTING_DEFAULT;
142 switch (value) {
143 case -1: break;
144 case 0: setting = CONTENT_SETTING_DEFAULT; break;
145 case 1: setting = CONTENT_SETTING_ALLOW; break;
146 case 2: setting = CONTENT_SETTING_BLOCK; break;
147 default:
148 NOTREACHED();
150 GetHostContentSettingsMap()->SetContentSetting(
151 ContentSettingsPattern::FromURLNoWildcard(url),
152 secondary_pattern,
153 content_type,
154 std::string(),
155 setting);
156 WebSiteSettingsUmaUtil::LogPermissionChange(content_type, setting);
159 static void GetGeolocationOrigins(JNIEnv* env,
160 jclass clazz,
161 jobject list,
162 jboolean managedOnly) {
163 GetOrigins(env, CONTENT_SETTINGS_TYPE_GEOLOCATION, list, managedOnly);
166 static jint GetGeolocationSettingForOrigin(JNIEnv* env, jclass clazz,
167 jstring origin, jstring embedder) {
168 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_GEOLOCATION,
169 origin, embedder);
172 static void SetGeolocationSettingForOrigin(JNIEnv* env, jclass clazz,
173 jstring origin, jstring embedder, jint value) {
174 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
175 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_GEOLOCATION,
176 origin, ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
179 static void GetMidiOrigins(JNIEnv* env, jclass clazz, jobject list) {
180 GetOrigins(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, list, false);
183 static jint GetMidiSettingForOrigin(JNIEnv* env, jclass clazz, jstring origin,
184 jstring embedder) {
185 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, origin,
186 embedder);
189 static void SetMidiSettingForOrigin(JNIEnv* env, jclass clazz, jstring origin,
190 jstring embedder, jint value) {
191 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
192 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, origin,
193 ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
196 static void GetProtectedMediaIdentifierOrigins(JNIEnv* env, jclass clazz,
197 jobject list) {
198 GetOrigins(env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, list,
199 false);
202 static jint GetProtectedMediaIdentifierSettingForOrigin(JNIEnv* env,
203 jclass clazz, jstring origin, jstring embedder) {
204 return GetSettingForOrigin(
205 env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, origin, embedder);
208 static void SetProtectedMediaIdentifierSettingForOrigin(JNIEnv* env,
209 jclass clazz, jstring origin, jstring embedder, jint value) {
210 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
211 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
212 origin, ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
215 static void GetPushNotificationOrigins(JNIEnv* env,
216 jclass clazz,
217 jobject list) {
218 GetOrigins(env, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, list, false);
221 static jint GetPushNotificationSettingForOrigin(JNIEnv* env, jclass clazz,
222 jstring origin, jstring embedder) {
223 return DesktopNotificationProfileUtil::GetContentSetting(
224 ProfileManager::GetActiveUserProfile(),
225 GURL(ConvertJavaStringToUTF8(env, origin)));
228 static void SetPushNotificationSettingForOrigin(JNIEnv* env, jclass clazz,
229 jstring origin, jstring embedder, jint value) {
230 // TODO(peter): Web Notification permission behaves differently from all other
231 // permission types. See https://crbug.com/416894.
232 Profile* profile = ProfileManager::GetActiveUserProfile();
233 GURL url = GURL(ConvertJavaStringToUTF8(env, origin));
234 ContentSetting setting = CONTENT_SETTING_DEFAULT;
235 switch (value) {
236 case -1:
237 DesktopNotificationProfileUtil::ClearSetting(
238 profile, ContentSettingsPattern::FromURLNoWildcard(url));
239 break;
240 case 1:
241 DesktopNotificationProfileUtil::GrantPermission(profile, url);
242 setting = CONTENT_SETTING_ALLOW;
243 break;
244 case 2:
245 DesktopNotificationProfileUtil::DenyPermission(profile, url);
246 setting = CONTENT_SETTING_BLOCK;
247 break;
248 default:
249 NOTREACHED();
251 WebSiteSettingsUmaUtil::LogPermissionChange(
252 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting);
255 static void GetVoiceAndVideoCaptureOrigins(JNIEnv* env,
256 jclass clazz,
257 jobject list,
258 jboolean managedOnly) {
259 GetOrigins(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, list, managedOnly);
260 GetOrigins(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, list, managedOnly);
263 static jint GetVoiceCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
264 jstring origin, jstring embedder) {
265 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
266 origin, embedder);
269 static jint GetVideoCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
270 jstring origin, jstring embedder) {
271 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
272 origin, embedder);
275 static void SetVoiceCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
276 jstring origin, jstring embedder, jint value) {
277 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
278 origin, ContentSettingsPattern::Wildcard(), value);
281 static void SetVideoCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
282 jstring origin, jstring embedder, jint value) {
283 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
284 origin, ContentSettingsPattern::Wildcard(), value);
287 static scoped_refptr<CookieSettings> GetCookieSettings() {
288 Profile* profile = ProfileManager::GetActiveUserProfile();
289 return CookieSettings::Factory::GetForProfile(profile);
292 static void GetCookieOrigins(JNIEnv* env,
293 jclass clazz,
294 jobject list,
295 jboolean managedOnly) {
296 ContentSettingsForOneType all_settings;
297 GetCookieSettings()->GetCookieSettings(&all_settings);
298 const ContentSetting default_setting =
299 GetCookieSettings()->GetDefaultCookieSetting(nullptr);
300 for (const auto& settings_it : all_settings) {
301 if (settings_it.setting == default_setting)
302 continue;
303 if (managedOnly &&
304 HostContentSettingsMap::GetProviderTypeFromSource(settings_it.source) !=
305 HostContentSettingsMap::ProviderType::POLICY_PROVIDER) {
306 continue;
308 const std::string& origin = settings_it.primary_pattern.ToString();
309 const std::string& embedder = settings_it.secondary_pattern.ToString();
310 ScopedJavaLocalRef<jstring> jorigin = ConvertUTF8ToJavaString(env, origin);
311 ScopedJavaLocalRef<jstring> jembedder;
312 if (embedder != origin)
313 jembedder = ConvertUTF8ToJavaString(env, embedder);
314 Java_WebsitePreferenceBridge_insertCookieInfoIntoList(env, list,
315 jorigin.obj(), jembedder.obj());
319 static jint GetCookieSettingForOrigin(JNIEnv* env, jclass clazz,
320 jstring origin, jstring embedder) {
321 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_COOKIES, origin,
322 embedder);
325 static void SetCookieSettingForOrigin(JNIEnv* env, jclass clazz,
326 jstring origin, jstring embedder, jint value) {
327 GURL url(ConvertJavaStringToUTF8(env, origin));
328 ContentSettingsPattern primary_pattern(
329 ContentSettingsPattern::FromURLNoWildcard(url));
330 ContentSettingsPattern secondary_pattern(ContentSettingsPattern::Wildcard());
331 ContentSetting setting = CONTENT_SETTING_DEFAULT;
332 if (value == -1) {
333 GetCookieSettings()->ResetCookieSetting(primary_pattern, secondary_pattern);
334 } else {
335 setting = value ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
336 GetCookieSettings()->SetCookieSetting(primary_pattern, secondary_pattern,
337 setting);
339 WebSiteSettingsUmaUtil::LogPermissionChange(
340 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting);
343 static jboolean IsContentSettingsPatternValid(JNIEnv* env, jclass clazz,
344 jstring pattern) {
345 return ContentSettingsPattern::FromString(
346 ConvertJavaStringToUTF8(env, pattern)).IsValid();
349 namespace {
351 class SiteDataDeleteHelper :
352 public base::RefCountedThreadSafe<SiteDataDeleteHelper>,
353 public CookiesTreeModel::Observer {
354 public:
355 SiteDataDeleteHelper(Profile* profile, const GURL& domain)
356 : profile_(profile), domain_(domain), ending_batch_processing_(false) {
359 void Run() {
360 AddRef(); // Balanced in TreeModelEndBatch.
362 content::StoragePartition* storage_partition =
363 content::BrowserContext::GetDefaultStoragePartition(profile_);
364 content::IndexedDBContext* indexed_db_context =
365 storage_partition->GetIndexedDBContext();
366 content::ServiceWorkerContext* service_worker_context =
367 storage_partition->GetServiceWorkerContext();
368 storage::FileSystemContext* file_system_context =
369 storage_partition->GetFileSystemContext();
370 LocalDataContainer* container = new LocalDataContainer(
371 new BrowsingDataCookieHelper(profile_->GetRequestContext()),
372 new BrowsingDataDatabaseHelper(profile_),
373 new BrowsingDataLocalStorageHelper(profile_),
374 NULL,
375 new BrowsingDataAppCacheHelper(profile_),
376 new BrowsingDataIndexedDBHelper(indexed_db_context),
377 BrowsingDataFileSystemHelper::Create(file_system_context),
378 BrowsingDataQuotaHelper::Create(profile_),
379 BrowsingDataChannelIDHelper::Create(profile_->GetRequestContext()),
380 new BrowsingDataServiceWorkerHelper(service_worker_context),
381 NULL);
383 cookies_tree_model_.reset(new CookiesTreeModel(
384 container, profile_->GetExtensionSpecialStoragePolicy(), false));
385 cookies_tree_model_->AddCookiesTreeObserver(this);
388 // TreeModelObserver:
389 void TreeNodesAdded(ui::TreeModel* model,
390 ui::TreeModelNode* parent,
391 int start,
392 int count) override {}
393 void TreeNodesRemoved(ui::TreeModel* model,
394 ui::TreeModelNode* parent,
395 int start,
396 int count) override {}
398 // CookiesTreeModel::Observer:
399 void TreeNodeChanged(ui::TreeModel* model, ui::TreeModelNode* node) override {
402 void TreeModelBeginBatch(CookiesTreeModel* model) override {
403 DCHECK(!ending_batch_processing_); // Extra batch-start sent.
406 void TreeModelEndBatch(CookiesTreeModel* model) override {
407 DCHECK(!ending_batch_processing_); // Already in end-stage.
408 ending_batch_processing_ = true;
410 RecursivelyFindSiteAndDelete(cookies_tree_model_->GetRoot());
412 // This will result in this class getting deleted.
413 Release();
416 void RecursivelyFindSiteAndDelete(CookieTreeNode* node) {
417 CookieTreeNode::DetailedInfo info = node->GetDetailedInfo();
418 for (int i = node->child_count(); i > 0; --i)
419 RecursivelyFindSiteAndDelete(node->GetChild(i - 1));
421 if (info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE &&
422 info.cookie &&
423 domain_.DomainIs(info.cookie->Domain().c_str()))
424 cookies_tree_model_->DeleteCookieNode(node);
427 private:
428 friend class base::RefCountedThreadSafe<SiteDataDeleteHelper>;
430 ~SiteDataDeleteHelper() override {}
432 Profile* profile_;
434 // The domain we want to delete data for.
435 GURL domain_;
437 // Keeps track of when we're ready to close batch processing.
438 bool ending_batch_processing_;
440 scoped_ptr<CookiesTreeModel> cookies_tree_model_;
442 DISALLOW_COPY_AND_ASSIGN(SiteDataDeleteHelper);
445 class StorageInfoFetcher :
446 public base::RefCountedThreadSafe<StorageInfoFetcher> {
447 public:
448 StorageInfoFetcher(storage::QuotaManager* quota_manager,
449 const JavaRef<jobject>& java_callback)
450 : env_(base::android::AttachCurrentThread()),
451 quota_manager_(quota_manager),
452 java_callback_(java_callback) {
455 void Run() {
456 // QuotaManager must be called on IO thread, but java_callback must then be
457 // called back on UI thread.
458 BrowserThread::PostTask(
459 BrowserThread::IO, FROM_HERE,
460 base::Bind(&StorageInfoFetcher::GetUsageInfo, this));
463 protected:
464 virtual ~StorageInfoFetcher() {}
466 private:
467 friend class base::RefCountedThreadSafe<StorageInfoFetcher>;
469 void GetUsageInfo() {
470 // We will have no explicit owner as soon as we leave this method.
471 AddRef();
472 quota_manager_->GetUsageInfo(
473 base::Bind(&StorageInfoFetcher::OnGetUsageInfo, this));
476 void OnGetUsageInfo(const storage::UsageInfoEntries& entries) {
477 entries_.insert(entries_.begin(), entries.begin(), entries.end());
478 BrowserThread::PostTask(
479 BrowserThread::UI, FROM_HERE,
480 base::Bind(&StorageInfoFetcher::InvokeCallback, this));
481 Release();
484 void InvokeCallback() {
485 ScopedJavaLocalRef<jobject> list =
486 Java_WebsitePreferenceBridge_createStorageInfoList(env_);
488 storage::UsageInfoEntries::const_iterator i;
489 for (i = entries_.begin(); i != entries_.end(); ++i) {
490 if (i->usage <= 0) continue;
491 ScopedJavaLocalRef<jstring> host =
492 ConvertUTF8ToJavaString(env_, i->host);
494 Java_WebsitePreferenceBridge_insertStorageInfoIntoList(
495 env_, list.obj(), host.obj(), i->type, i->usage);
497 Java_StorageInfoReadyCallback_onStorageInfoReady(
498 env_, java_callback_.obj(), list.obj());
501 JNIEnv* env_;
502 storage::QuotaManager* quota_manager_;
503 ScopedJavaGlobalRef<jobject> java_callback_;
504 storage::UsageInfoEntries entries_;
506 DISALLOW_COPY_AND_ASSIGN(StorageInfoFetcher);
509 class StorageDataDeleter :
510 public base::RefCountedThreadSafe<StorageDataDeleter> {
511 public:
512 StorageDataDeleter(storage::QuotaManager* quota_manager,
513 const std::string& host,
514 storage::StorageType type,
515 const JavaRef<jobject>& java_callback)
516 : env_(base::android::AttachCurrentThread()),
517 quota_manager_(quota_manager),
518 host_(host),
519 type_(type),
520 java_callback_(java_callback) {
523 void Run() {
524 // QuotaManager must be called on IO thread, but java_callback must then be
525 // called back on UI thread. Grant ourself an extra reference to avoid
526 // being deleted after DeleteHostData will return.
527 AddRef();
528 BrowserThread::PostTask(
529 BrowserThread::IO, FROM_HERE,
530 base::Bind(&storage::QuotaManager::DeleteHostData,
531 quota_manager_,
532 host_,
533 type_,
534 storage::QuotaClient::kAllClientsMask,
535 base::Bind(&StorageDataDeleter::OnHostDataDeleted,
536 this)));
539 protected:
540 virtual ~StorageDataDeleter() {}
542 private:
543 friend class base::RefCountedThreadSafe<StorageDataDeleter>;
545 void OnHostDataDeleted(storage::QuotaStatusCode) {
546 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
547 quota_manager_->ResetUsageTracker(type_);
548 BrowserThread::PostTask(
549 BrowserThread::UI, FROM_HERE,
550 base::Bind(&StorageDataDeleter::InvokeCallback, this));
551 Release();
554 void InvokeCallback() {
555 Java_StorageInfoClearedCallback_onStorageInfoCleared(
556 env_, java_callback_.obj());
559 JNIEnv* env_;
560 storage::QuotaManager* quota_manager_;
561 std::string host_;
562 storage::StorageType type_;
563 ScopedJavaGlobalRef<jobject> java_callback_;
566 class LocalStorageInfoReadyCallback {
567 public:
568 LocalStorageInfoReadyCallback(
569 const ScopedJavaLocalRef<jobject>& java_callback)
570 : env_(base::android::AttachCurrentThread()),
571 java_callback_(java_callback) {
574 void OnLocalStorageModelInfoLoaded(
575 const std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>&
576 local_storage_info) {
577 ScopedJavaLocalRef<jobject> map =
578 Java_WebsitePreferenceBridge_createLocalStorageInfoMap(env_);
580 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::const_iterator
582 for (i = local_storage_info.begin(); i != local_storage_info.end(); ++i) {
583 ScopedJavaLocalRef<jstring> full_origin =
584 ConvertUTF8ToJavaString(env_, i->origin_url.spec());
585 ScopedJavaLocalRef<jstring> origin =
586 ConvertUTF8ToJavaString(env_, i->origin_url.GetOrigin().spec());
587 Java_WebsitePreferenceBridge_insertLocalStorageInfoIntoMap(
588 env_, map.obj(), origin.obj(), full_origin.obj(), i->size);
591 Java_LocalStorageInfoReadyCallback_onLocalStorageInfoReady(
592 env_, java_callback_.obj(), map.obj());
593 delete this;
596 private:
597 JNIEnv* env_;
598 ScopedJavaGlobalRef<jobject> java_callback_;
601 } // anonymous namespace
603 // TODO(jknotten): These methods should not be static. Instead we should
604 // expose a class to Java so that the fetch requests can be cancelled,
605 // and manage the lifetimes of the callback (and indirectly the helper
606 // by having a reference to it).
608 // The helper methods (StartFetching, DeleteLocalStorageFile, DeleteDatabase)
609 // are asynchronous. A "use after free" error is not possible because the
610 // helpers keep a reference to themselves for the duration of their tasks,
611 // which includes callback invocation.
613 static void FetchLocalStorageInfo(JNIEnv* env, jclass clazz,
614 jobject java_callback) {
615 Profile* profile = ProfileManager::GetActiveUserProfile();
616 scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper(
617 new BrowsingDataLocalStorageHelper(profile));
618 // local_storage_callback will delete itself when it is run.
619 LocalStorageInfoReadyCallback* local_storage_callback =
620 new LocalStorageInfoReadyCallback(
621 ScopedJavaLocalRef<jobject>(env, java_callback));
622 local_storage_helper->StartFetching(
623 base::Bind(&LocalStorageInfoReadyCallback::OnLocalStorageModelInfoLoaded,
624 base::Unretained(local_storage_callback)));
627 static void FetchStorageInfo(JNIEnv* env, jclass clazz, jobject java_callback) {
628 Profile* profile = ProfileManager::GetActiveUserProfile();
629 scoped_refptr<StorageInfoFetcher> storage_info_fetcher(new StorageInfoFetcher(
630 content::BrowserContext::GetDefaultStoragePartition(
631 profile)->GetQuotaManager(),
632 ScopedJavaLocalRef<jobject>(env, java_callback)));
633 storage_info_fetcher->Run();
636 static void ClearLocalStorageData(JNIEnv* env, jclass clazz, jstring jorigin) {
637 Profile* profile = ProfileManager::GetActiveUserProfile();
638 scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper =
639 new BrowsingDataLocalStorageHelper(profile);
640 GURL origin_url = GURL(ConvertJavaStringToUTF8(env, jorigin));
641 local_storage_helper->DeleteOrigin(origin_url);
644 static void ClearStorageData(JNIEnv* env,
645 jclass clazz,
646 jstring jhost,
647 jint type,
648 jobject java_callback) {
649 Profile* profile = ProfileManager::GetActiveUserProfile();
650 std::string host = ConvertJavaStringToUTF8(env, jhost);
651 scoped_refptr<StorageDataDeleter> storage_data_deleter(new StorageDataDeleter(
652 content::BrowserContext::GetDefaultStoragePartition(
653 profile)->GetQuotaManager(),
654 host,
655 static_cast<storage::StorageType>(type),
656 ScopedJavaLocalRef<jobject>(env, java_callback)));
657 storage_data_deleter->Run();
660 static void ClearCookieData(JNIEnv* env, jclass clazz, jstring jorigin) {
661 Profile* profile = ProfileManager::GetActiveUserProfile();
662 GURL url(ConvertJavaStringToUTF8(env, jorigin));
663 scoped_refptr<SiteDataDeleteHelper> site_data_deleter(
664 new SiteDataDeleteHelper(profile, url));
665 site_data_deleter->Run();
668 // Register native methods
669 bool RegisterWebsitePreferenceBridge(JNIEnv* env) {
670 return RegisterNativesImpl(env);