Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / android / preferences / website_preference_bridge.cc
bloba82ee7513e878fd26f14a3488a0f5a7b5ec3a0a8
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 case CONTENT_SETTINGS_TYPE_FULLSCREEN:
115 Java_WebsitePreferenceBridge_insertFullscreenInfoIntoList(
116 env, list, jorigin.obj(), jembedder.obj());
117 break;
118 default:
119 DCHECK(false);
120 break;
125 static jint GetSettingForOrigin(JNIEnv* env,
126 ContentSettingsType content_type,
127 jstring origin,
128 jstring embedder) {
129 GURL url(ConvertJavaStringToUTF8(env, origin));
130 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
131 ContentSetting setting = GetHostContentSettingsMap()->GetContentSetting(
132 url,
133 embedder_url,
134 content_type,
135 std::string());
136 return setting;
139 static void SetSettingForOrigin(JNIEnv* env,
140 ContentSettingsType content_type,
141 jstring origin,
142 ContentSettingsPattern secondary_pattern,
143 jint value) {
144 GURL url(ConvertJavaStringToUTF8(env, origin));
145 ContentSetting setting = CONTENT_SETTING_DEFAULT;
146 switch (value) {
147 case -1: break;
148 case 0: setting = CONTENT_SETTING_DEFAULT; break;
149 case 1: setting = CONTENT_SETTING_ALLOW; break;
150 case 2: setting = CONTENT_SETTING_BLOCK; break;
151 default:
152 // Note: CONTENT_SETTINGS_ASK is not and should not be supported.
153 NOTREACHED();
155 GetHostContentSettingsMap()->SetContentSetting(
156 ContentSettingsPattern::FromURLNoWildcard(url),
157 secondary_pattern,
158 content_type,
159 std::string(),
160 setting);
161 WebSiteSettingsUmaUtil::LogPermissionChange(content_type, setting);
164 static void GetFullscreenOrigins(JNIEnv* env,
165 jclass clazz,
166 jobject list,
167 jboolean managedOnly) {
168 GetOrigins(env, CONTENT_SETTINGS_TYPE_FULLSCREEN, list, managedOnly);
171 static jint GetFullscreenSettingForOrigin(JNIEnv* env, jclass clazz,
172 jstring origin, jstring embedder) {
173 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_FULLSCREEN,
174 origin, embedder);
177 static void SetFullscreenSettingForOrigin(JNIEnv* env, jclass clazz,
178 jstring origin, jstring embedder, jint value) {
179 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
180 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_FULLSCREEN,
181 origin, ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
184 static void GetGeolocationOrigins(JNIEnv* env,
185 jclass clazz,
186 jobject list,
187 jboolean managedOnly) {
188 GetOrigins(env, CONTENT_SETTINGS_TYPE_GEOLOCATION, list, managedOnly);
191 static jint GetGeolocationSettingForOrigin(JNIEnv* env, jclass clazz,
192 jstring origin, jstring embedder) {
193 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_GEOLOCATION,
194 origin, embedder);
197 static void SetGeolocationSettingForOrigin(JNIEnv* env, jclass clazz,
198 jstring origin, jstring embedder, jint value) {
199 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
200 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_GEOLOCATION,
201 origin, ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
204 static void GetMidiOrigins(JNIEnv* env, jclass clazz, jobject list) {
205 GetOrigins(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, list, false);
208 static jint GetMidiSettingForOrigin(JNIEnv* env, jclass clazz, jstring origin,
209 jstring embedder) {
210 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, origin,
211 embedder);
214 static void SetMidiSettingForOrigin(JNIEnv* env, jclass clazz, jstring origin,
215 jstring embedder, jint value) {
216 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
217 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, origin,
218 ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
221 static void GetProtectedMediaIdentifierOrigins(JNIEnv* env, jclass clazz,
222 jobject list) {
223 GetOrigins(env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, list,
224 false);
227 static jint GetProtectedMediaIdentifierSettingForOrigin(JNIEnv* env,
228 jclass clazz, jstring origin, jstring embedder) {
229 return GetSettingForOrigin(
230 env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, origin, embedder);
233 static void SetProtectedMediaIdentifierSettingForOrigin(JNIEnv* env,
234 jclass clazz, jstring origin, jstring embedder, jint value) {
235 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
236 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
237 origin, ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
240 static void GetPushNotificationOrigins(JNIEnv* env,
241 jclass clazz,
242 jobject list) {
243 GetOrigins(env, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, list, false);
246 static jint GetPushNotificationSettingForOrigin(JNIEnv* env, jclass clazz,
247 jstring origin, jstring embedder) {
248 return DesktopNotificationProfileUtil::GetContentSetting(
249 ProfileManager::GetActiveUserProfile(),
250 GURL(ConvertJavaStringToUTF8(env, origin)));
253 static void SetPushNotificationSettingForOrigin(JNIEnv* env, jclass clazz,
254 jstring origin, jstring embedder, jint value) {
255 // TODO(peter): Web Notification permission behaves differently from all other
256 // permission types. See https://crbug.com/416894.
257 Profile* profile = ProfileManager::GetActiveUserProfile();
258 GURL url = GURL(ConvertJavaStringToUTF8(env, origin));
259 ContentSetting setting = CONTENT_SETTING_DEFAULT;
260 switch (value) {
261 case -1:
262 DesktopNotificationProfileUtil::ClearSetting(
263 profile, ContentSettingsPattern::FromURLNoWildcard(url));
264 break;
265 case 1:
266 DesktopNotificationProfileUtil::GrantPermission(profile, url);
267 setting = CONTENT_SETTING_ALLOW;
268 break;
269 case 2:
270 DesktopNotificationProfileUtil::DenyPermission(profile, url);
271 setting = CONTENT_SETTING_BLOCK;
272 break;
273 default:
274 NOTREACHED();
276 WebSiteSettingsUmaUtil::LogPermissionChange(
277 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting);
280 static void GetVoiceAndVideoCaptureOrigins(JNIEnv* env,
281 jclass clazz,
282 jobject list,
283 jboolean managedOnly) {
284 GetOrigins(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, list, managedOnly);
285 GetOrigins(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, list, managedOnly);
288 static jint GetVoiceCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
289 jstring origin, jstring embedder) {
290 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
291 origin, embedder);
294 static jint GetVideoCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
295 jstring origin, jstring embedder) {
296 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
297 origin, embedder);
300 static void SetVoiceCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
301 jstring origin, jstring embedder, jint value) {
302 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
303 origin, ContentSettingsPattern::Wildcard(), value);
306 static void SetVideoCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
307 jstring origin, jstring embedder, jint value) {
308 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
309 origin, ContentSettingsPattern::Wildcard(), value);
312 static scoped_refptr<CookieSettings> GetCookieSettings() {
313 Profile* profile = ProfileManager::GetActiveUserProfile();
314 return CookieSettings::Factory::GetForProfile(profile);
317 static void GetCookieOrigins(JNIEnv* env,
318 jclass clazz,
319 jobject list,
320 jboolean managedOnly) {
321 ContentSettingsForOneType all_settings;
322 GetCookieSettings()->GetCookieSettings(&all_settings);
323 const ContentSetting default_setting =
324 GetCookieSettings()->GetDefaultCookieSetting(nullptr);
325 for (const auto& settings_it : all_settings) {
326 if (settings_it.setting == default_setting)
327 continue;
328 if (managedOnly &&
329 HostContentSettingsMap::GetProviderTypeFromSource(settings_it.source) !=
330 HostContentSettingsMap::ProviderType::POLICY_PROVIDER) {
331 continue;
333 const std::string& origin = settings_it.primary_pattern.ToString();
334 const std::string& embedder = settings_it.secondary_pattern.ToString();
335 ScopedJavaLocalRef<jstring> jorigin = ConvertUTF8ToJavaString(env, origin);
336 ScopedJavaLocalRef<jstring> jembedder;
337 if (embedder != origin)
338 jembedder = ConvertUTF8ToJavaString(env, embedder);
339 Java_WebsitePreferenceBridge_insertCookieInfoIntoList(env, list,
340 jorigin.obj(), jembedder.obj());
344 static jint GetCookieSettingForOrigin(JNIEnv* env, jclass clazz,
345 jstring origin, jstring embedder) {
346 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_COOKIES, origin,
347 embedder);
350 static void SetCookieSettingForOrigin(JNIEnv* env, jclass clazz,
351 jstring origin, jstring embedder, jint value) {
352 GURL url(ConvertJavaStringToUTF8(env, origin));
353 ContentSettingsPattern primary_pattern(
354 ContentSettingsPattern::FromURLNoWildcard(url));
355 ContentSettingsPattern secondary_pattern(ContentSettingsPattern::Wildcard());
356 ContentSetting setting = CONTENT_SETTING_DEFAULT;
357 if (value == -1) {
358 GetCookieSettings()->ResetCookieSetting(primary_pattern, secondary_pattern);
359 } else {
360 setting = value ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK;
361 GetCookieSettings()->SetCookieSetting(primary_pattern, secondary_pattern,
362 setting);
364 WebSiteSettingsUmaUtil::LogPermissionChange(
365 CONTENT_SETTINGS_TYPE_NOTIFICATIONS, setting);
368 static jboolean IsContentSettingsPatternValid(JNIEnv* env, jclass clazz,
369 jstring pattern) {
370 return ContentSettingsPattern::FromString(
371 ConvertJavaStringToUTF8(env, pattern)).IsValid();
374 namespace {
376 class SiteDataDeleteHelper :
377 public base::RefCountedThreadSafe<SiteDataDeleteHelper>,
378 public CookiesTreeModel::Observer {
379 public:
380 SiteDataDeleteHelper(Profile* profile, const GURL& domain)
381 : profile_(profile), domain_(domain), ending_batch_processing_(false) {
384 void Run() {
385 AddRef(); // Balanced in TreeModelEndBatch.
387 content::StoragePartition* storage_partition =
388 content::BrowserContext::GetDefaultStoragePartition(profile_);
389 content::IndexedDBContext* indexed_db_context =
390 storage_partition->GetIndexedDBContext();
391 content::ServiceWorkerContext* service_worker_context =
392 storage_partition->GetServiceWorkerContext();
393 storage::FileSystemContext* file_system_context =
394 storage_partition->GetFileSystemContext();
395 LocalDataContainer* container = new LocalDataContainer(
396 new BrowsingDataCookieHelper(profile_->GetRequestContext()),
397 new BrowsingDataDatabaseHelper(profile_),
398 new BrowsingDataLocalStorageHelper(profile_),
399 NULL,
400 new BrowsingDataAppCacheHelper(profile_),
401 new BrowsingDataIndexedDBHelper(indexed_db_context),
402 BrowsingDataFileSystemHelper::Create(file_system_context),
403 BrowsingDataQuotaHelper::Create(profile_),
404 BrowsingDataChannelIDHelper::Create(profile_->GetRequestContext()),
405 new BrowsingDataServiceWorkerHelper(service_worker_context),
406 NULL);
408 cookies_tree_model_.reset(new CookiesTreeModel(
409 container, profile_->GetExtensionSpecialStoragePolicy(), false));
410 cookies_tree_model_->AddCookiesTreeObserver(this);
413 // TreeModelObserver:
414 void TreeNodesAdded(ui::TreeModel* model,
415 ui::TreeModelNode* parent,
416 int start,
417 int count) override {}
418 void TreeNodesRemoved(ui::TreeModel* model,
419 ui::TreeModelNode* parent,
420 int start,
421 int count) override {}
423 // CookiesTreeModel::Observer:
424 void TreeNodeChanged(ui::TreeModel* model, ui::TreeModelNode* node) override {
427 void TreeModelBeginBatch(CookiesTreeModel* model) override {
428 DCHECK(!ending_batch_processing_); // Extra batch-start sent.
431 void TreeModelEndBatch(CookiesTreeModel* model) override {
432 DCHECK(!ending_batch_processing_); // Already in end-stage.
433 ending_batch_processing_ = true;
435 RecursivelyFindSiteAndDelete(cookies_tree_model_->GetRoot());
437 // This will result in this class getting deleted.
438 Release();
441 void RecursivelyFindSiteAndDelete(CookieTreeNode* node) {
442 CookieTreeNode::DetailedInfo info = node->GetDetailedInfo();
443 for (int i = node->child_count(); i > 0; --i)
444 RecursivelyFindSiteAndDelete(node->GetChild(i - 1));
446 if (info.node_type == CookieTreeNode::DetailedInfo::TYPE_COOKIE &&
447 info.cookie &&
448 domain_.DomainIs(info.cookie->Domain().c_str()))
449 cookies_tree_model_->DeleteCookieNode(node);
452 private:
453 friend class base::RefCountedThreadSafe<SiteDataDeleteHelper>;
455 ~SiteDataDeleteHelper() override {}
457 Profile* profile_;
459 // The domain we want to delete data for.
460 GURL domain_;
462 // Keeps track of when we're ready to close batch processing.
463 bool ending_batch_processing_;
465 scoped_ptr<CookiesTreeModel> cookies_tree_model_;
467 DISALLOW_COPY_AND_ASSIGN(SiteDataDeleteHelper);
470 class StorageInfoFetcher :
471 public base::RefCountedThreadSafe<StorageInfoFetcher> {
472 public:
473 StorageInfoFetcher(storage::QuotaManager* quota_manager,
474 const JavaRef<jobject>& java_callback)
475 : env_(base::android::AttachCurrentThread()),
476 quota_manager_(quota_manager),
477 java_callback_(java_callback) {
480 void Run() {
481 // QuotaManager must be called on IO thread, but java_callback must then be
482 // called back on UI thread.
483 BrowserThread::PostTask(
484 BrowserThread::IO, FROM_HERE,
485 base::Bind(&StorageInfoFetcher::GetUsageInfo, this));
488 protected:
489 virtual ~StorageInfoFetcher() {}
491 private:
492 friend class base::RefCountedThreadSafe<StorageInfoFetcher>;
494 void GetUsageInfo() {
495 // We will have no explicit owner as soon as we leave this method.
496 AddRef();
497 quota_manager_->GetUsageInfo(
498 base::Bind(&StorageInfoFetcher::OnGetUsageInfo, this));
501 void OnGetUsageInfo(const storage::UsageInfoEntries& entries) {
502 entries_.insert(entries_.begin(), entries.begin(), entries.end());
503 BrowserThread::PostTask(
504 BrowserThread::UI, FROM_HERE,
505 base::Bind(&StorageInfoFetcher::InvokeCallback, this));
506 Release();
509 void InvokeCallback() {
510 ScopedJavaLocalRef<jobject> list =
511 Java_WebsitePreferenceBridge_createStorageInfoList(env_);
513 storage::UsageInfoEntries::const_iterator i;
514 for (i = entries_.begin(); i != entries_.end(); ++i) {
515 if (i->usage <= 0) continue;
516 ScopedJavaLocalRef<jstring> host =
517 ConvertUTF8ToJavaString(env_, i->host);
519 Java_WebsitePreferenceBridge_insertStorageInfoIntoList(
520 env_, list.obj(), host.obj(), i->type, i->usage);
522 Java_StorageInfoReadyCallback_onStorageInfoReady(
523 env_, java_callback_.obj(), list.obj());
526 JNIEnv* env_;
527 storage::QuotaManager* quota_manager_;
528 ScopedJavaGlobalRef<jobject> java_callback_;
529 storage::UsageInfoEntries entries_;
531 DISALLOW_COPY_AND_ASSIGN(StorageInfoFetcher);
534 class StorageDataDeleter :
535 public base::RefCountedThreadSafe<StorageDataDeleter> {
536 public:
537 StorageDataDeleter(storage::QuotaManager* quota_manager,
538 const std::string& host,
539 storage::StorageType type,
540 const JavaRef<jobject>& java_callback)
541 : env_(base::android::AttachCurrentThread()),
542 quota_manager_(quota_manager),
543 host_(host),
544 type_(type),
545 java_callback_(java_callback) {
548 void Run() {
549 // QuotaManager must be called on IO thread, but java_callback must then be
550 // called back on UI thread. Grant ourself an extra reference to avoid
551 // being deleted after DeleteHostData will return.
552 AddRef();
553 BrowserThread::PostTask(
554 BrowserThread::IO, FROM_HERE,
555 base::Bind(&storage::QuotaManager::DeleteHostData,
556 quota_manager_,
557 host_,
558 type_,
559 storage::QuotaClient::kAllClientsMask,
560 base::Bind(&StorageDataDeleter::OnHostDataDeleted,
561 this)));
564 protected:
565 virtual ~StorageDataDeleter() {}
567 private:
568 friend class base::RefCountedThreadSafe<StorageDataDeleter>;
570 void OnHostDataDeleted(storage::QuotaStatusCode) {
571 DCHECK_CURRENTLY_ON(BrowserThread::IO);
572 quota_manager_->ResetUsageTracker(type_);
573 BrowserThread::PostTask(
574 BrowserThread::UI, FROM_HERE,
575 base::Bind(&StorageDataDeleter::InvokeCallback, this));
576 Release();
579 void InvokeCallback() {
580 Java_StorageInfoClearedCallback_onStorageInfoCleared(
581 env_, java_callback_.obj());
584 JNIEnv* env_;
585 storage::QuotaManager* quota_manager_;
586 std::string host_;
587 storage::StorageType type_;
588 ScopedJavaGlobalRef<jobject> java_callback_;
591 class LocalStorageInfoReadyCallback {
592 public:
593 LocalStorageInfoReadyCallback(
594 const ScopedJavaLocalRef<jobject>& java_callback)
595 : env_(base::android::AttachCurrentThread()),
596 java_callback_(java_callback) {
599 void OnLocalStorageModelInfoLoaded(
600 const std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>&
601 local_storage_info) {
602 ScopedJavaLocalRef<jobject> map =
603 Java_WebsitePreferenceBridge_createLocalStorageInfoMap(env_);
605 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::const_iterator
607 for (i = local_storage_info.begin(); i != local_storage_info.end(); ++i) {
608 ScopedJavaLocalRef<jstring> full_origin =
609 ConvertUTF8ToJavaString(env_, i->origin_url.spec());
610 ScopedJavaLocalRef<jstring> origin =
611 ConvertUTF8ToJavaString(env_, i->origin_url.GetOrigin().spec());
612 Java_WebsitePreferenceBridge_insertLocalStorageInfoIntoMap(
613 env_, map.obj(), origin.obj(), full_origin.obj(), i->size);
616 Java_LocalStorageInfoReadyCallback_onLocalStorageInfoReady(
617 env_, java_callback_.obj(), map.obj());
618 delete this;
621 private:
622 JNIEnv* env_;
623 ScopedJavaGlobalRef<jobject> java_callback_;
626 } // anonymous namespace
628 // TODO(jknotten): These methods should not be static. Instead we should
629 // expose a class to Java so that the fetch requests can be cancelled,
630 // and manage the lifetimes of the callback (and indirectly the helper
631 // by having a reference to it).
633 // The helper methods (StartFetching, DeleteLocalStorageFile, DeleteDatabase)
634 // are asynchronous. A "use after free" error is not possible because the
635 // helpers keep a reference to themselves for the duration of their tasks,
636 // which includes callback invocation.
638 static void FetchLocalStorageInfo(JNIEnv* env, jclass clazz,
639 jobject java_callback) {
640 Profile* profile = ProfileManager::GetActiveUserProfile();
641 scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper(
642 new BrowsingDataLocalStorageHelper(profile));
643 // local_storage_callback will delete itself when it is run.
644 LocalStorageInfoReadyCallback* local_storage_callback =
645 new LocalStorageInfoReadyCallback(
646 ScopedJavaLocalRef<jobject>(env, java_callback));
647 local_storage_helper->StartFetching(
648 base::Bind(&LocalStorageInfoReadyCallback::OnLocalStorageModelInfoLoaded,
649 base::Unretained(local_storage_callback)));
652 static void FetchStorageInfo(JNIEnv* env, jclass clazz, jobject java_callback) {
653 Profile* profile = ProfileManager::GetActiveUserProfile();
654 scoped_refptr<StorageInfoFetcher> storage_info_fetcher(new StorageInfoFetcher(
655 content::BrowserContext::GetDefaultStoragePartition(
656 profile)->GetQuotaManager(),
657 ScopedJavaLocalRef<jobject>(env, java_callback)));
658 storage_info_fetcher->Run();
661 static void ClearLocalStorageData(JNIEnv* env, jclass clazz, jstring jorigin) {
662 Profile* profile = ProfileManager::GetActiveUserProfile();
663 scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper =
664 new BrowsingDataLocalStorageHelper(profile);
665 GURL origin_url = GURL(ConvertJavaStringToUTF8(env, jorigin));
666 local_storage_helper->DeleteOrigin(origin_url);
669 static void ClearStorageData(JNIEnv* env,
670 jclass clazz,
671 jstring jhost,
672 jint type,
673 jobject java_callback) {
674 Profile* profile = ProfileManager::GetActiveUserProfile();
675 std::string host = ConvertJavaStringToUTF8(env, jhost);
676 scoped_refptr<StorageDataDeleter> storage_data_deleter(new StorageDataDeleter(
677 content::BrowserContext::GetDefaultStoragePartition(
678 profile)->GetQuotaManager(),
679 host,
680 static_cast<storage::StorageType>(type),
681 ScopedJavaLocalRef<jobject>(env, java_callback)));
682 storage_data_deleter->Run();
685 static void ClearCookieData(JNIEnv* env, jclass clazz, jstring jorigin) {
686 Profile* profile = ProfileManager::GetActiveUserProfile();
687 GURL url(ConvertJavaStringToUTF8(env, jorigin));
688 scoped_refptr<SiteDataDeleteHelper> site_data_deleter(
689 new SiteDataDeleteHelper(profile, url));
690 site_data_deleter->Run();
693 // Register native methods
694 bool RegisterWebsitePreferenceBridge(JNIEnv* env) {
695 return RegisterNativesImpl(env);