Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(241)

Side by Side Diff: chrome/browser/android/preferences/website_preference_bridge.cc

Issue 850813002: Upstream Site Settings. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@location_settings_singleton
Patch Set: use findbugs annotations; fix test Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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.
4
5 #include "chrome/browser/android/preferences/website_preference_bridge.h"
6
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/content_settings/cookie_settings.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/profiles/profile_manager.h"
18 #include "components/content_settings/core/browser/host_content_settings_map.h"
19 #include "content/public/browser/browser_thread.h"
20 #include "content/public/browser/storage_partition.h"
21 #include "jni/WebsitePreferenceBridge_jni.h"
22 #include "storage/browser/quota/quota_client.h"
23 #include "storage/browser/quota/quota_manager.h"
24
25 using base::android::ConvertJavaStringToUTF8;
26 using base::android::ConvertUTF8ToJavaString;
27 using base::android::JavaRef;
28 using base::android::ScopedJavaGlobalRef;
29 using base::android::ScopedJavaLocalRef;
30 using content::BrowserThread;
31
32 static HostContentSettingsMap* GetHostContentSettingsMap() {
33 Profile* profile = ProfileManager::GetActiveUserProfile();
34 return profile->GetHostContentSettingsMap();
35 }
36
37 static void GetOrigins(JNIEnv* env,
38 ContentSettingsType content_type,
39 jobject list,
40 jboolean managedOnly) {
41 ContentSettingsForOneType all_settings;
42 HostContentSettingsMap* content_settings_map = GetHostContentSettingsMap();
43 content_settings_map->GetSettingsForOneType(
44 content_type, std::string(), &all_settings);
45 ContentSetting default_content_setting = content_settings_map->
46 GetDefaultContentSetting(content_type, NULL);
47 // Now add all origins that have a non-default setting to the list.
48 for (const auto& settings_it : all_settings) {
49 if (settings_it.setting == default_content_setting)
50 continue;
51 if (managedOnly &&
52 HostContentSettingsMap::GetProviderTypeFromSource(settings_it.source) !=
53 HostContentSettingsMap::ProviderType::POLICY_PROVIDER) {
54 continue;
55 }
56 const std::string origin = settings_it.primary_pattern.ToString();
57 const std::string embedder = settings_it.secondary_pattern.ToString();
58 ScopedJavaLocalRef<jstring> jorigin = ConvertUTF8ToJavaString(env, origin);
59 ScopedJavaLocalRef<jstring> jembedder;
60 if (embedder != origin)
61 jembedder = ConvertUTF8ToJavaString(env, embedder);
62 switch (content_type) {
63 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC:
64 case CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA:
65 Java_WebsitePreferenceBridge_insertVoiceAndVideoCaptureInfoIntoList(
66 env, list, jorigin.obj(), jembedder.obj());
67 break;
68 case CONTENT_SETTINGS_TYPE_GEOLOCATION:
69 Java_WebsitePreferenceBridge_insertGeolocationInfoIntoList(
70 env, list, jorigin.obj(), jembedder.obj());
71 break;
72 case CONTENT_SETTINGS_TYPE_MIDI_SYSEX:
73 Java_WebsitePreferenceBridge_insertMidiInfoIntoList(
74 env, list, jorigin.obj(), jembedder.obj());
75 break;
76 case CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER:
77 Java_WebsitePreferenceBridge_insertProtectedMediaIdentifierInfoIntoList(
78 env, list, jorigin.obj(), jembedder.obj());
79 break;
80 case CONTENT_SETTINGS_TYPE_NOTIFICATIONS:
81 Java_WebsitePreferenceBridge_insertPushNotificationIntoList(
82 env, list, jorigin.obj(), jembedder.obj());
83 break;
84 default:
85 DCHECK(false);
86 break;
87 }
88 }
89 }
90
91 static jint GetSettingForOrigin(JNIEnv* env,
92 ContentSettingsType content_type,
93 jstring origin,
94 jstring embedder) {
95 GURL url(ConvertJavaStringToUTF8(env, origin));
96 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
97 ContentSetting setting = GetHostContentSettingsMap()->GetContentSetting(
98 url,
99 embedder_url,
100 content_type,
101 std::string());
102 return setting;
103 }
104
105 static void SetSettingForOrigin(JNIEnv* env,
106 ContentSettingsType content_type,
107 jstring origin,
108 ContentSettingsPattern secondary_pattern,
109 jint value) {
110 GURL url(ConvertJavaStringToUTF8(env, origin));
111 ContentSetting setting = CONTENT_SETTING_DEFAULT;
112 switch (value) {
113 case -1: break;
114 case 1: setting = CONTENT_SETTING_ALLOW; break;
115 case 2: setting = CONTENT_SETTING_BLOCK; break;
116 default:
117 NOTREACHED();
118 }
119 GetHostContentSettingsMap()->SetContentSetting(
120 ContentSettingsPattern::FromURLNoWildcard(url),
121 secondary_pattern,
122 content_type,
123 std::string(),
124 setting);
125 }
126
127 static void GetGeolocationOrigins(JNIEnv* env,
128 jclass clazz,
129 jobject list,
130 jboolean managedOnly) {
131 GetOrigins(env, CONTENT_SETTINGS_TYPE_GEOLOCATION, list, managedOnly);
132 }
133
134 static jint GetGeolocationSettingForOrigin(JNIEnv* env, jclass clazz,
135 jstring origin, jstring embedder) {
136 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_GEOLOCATION,
137 origin, embedder);
138 }
139
140 static void SetGeolocationSettingForOrigin(JNIEnv* env, jclass clazz,
141 jstring origin, jstring embedder, jint value) {
142 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
143 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_GEOLOCATION,
144 origin, ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
145 }
146
147 static void GetMidiOrigins(JNIEnv* env, jclass clazz, jobject list) {
148 GetOrigins(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, list, false);
149 }
150
151 static jint GetMidiSettingForOrigin(JNIEnv* env, jclass clazz, jstring origin,
152 jstring embedder) {
153 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, origin,
154 embedder);
155 }
156
157 static void SetMidiSettingForOrigin(JNIEnv* env, jclass clazz, jstring origin,
158 jstring embedder, jint value) {
159 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
160 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MIDI_SYSEX, origin,
161 ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
162 }
163
164 static void GetProtectedMediaIdentifierOrigins(JNIEnv* env, jclass clazz,
165 jobject list) {
166 GetOrigins(env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, list,
167 false);
168 }
169
170 static jint GetProtectedMediaIdentifierSettingForOrigin(JNIEnv* env,
171 jclass clazz, jstring origin, jstring embedder) {
172 return GetSettingForOrigin(
173 env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, origin, embedder);
174 }
175
176 static void SetProtectedMediaIdentifierSettingForOrigin(JNIEnv* env,
177 jclass clazz, jstring origin, jstring embedder, jint value) {
178 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
179 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER,
180 origin, ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
181 }
182
183 static void GetPushNotificationOrigins(JNIEnv* env,
184 jclass clazz,
185 jobject list) {
186 GetOrigins(env, CONTENT_SETTINGS_TYPE_NOTIFICATIONS, list, false);
187 }
188
189 static jint GetPushNotificationSettingForOrigin(JNIEnv* env, jclass clazz,
190 jstring origin, jstring embedder) {
191 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
192 origin, embedder);
193 }
194
195 static void SetPushNotificationSettingForOrigin(JNIEnv* env, jclass clazz,
196 jstring origin, jstring embedder, jint value) {
197 GURL embedder_url(ConvertJavaStringToUTF8(env, embedder));
198 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_NOTIFICATIONS,
199 origin, ContentSettingsPattern::FromURLNoWildcard(embedder_url), value);
200 }
201
202 static void GetVoiceAndVideoCaptureOrigins(JNIEnv* env,
203 jclass clazz,
204 jobject list,
205 jboolean managedOnly) {
206 GetOrigins(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, list, managedOnly);
207 GetOrigins(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, list, managedOnly);
208 }
209
210 static jint GetVoiceCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
211 jstring origin, jstring embedder) {
212 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
213 origin, embedder);
214 }
215
216 static jint GetVideoCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
217 jstring origin, jstring embedder) {
218 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
219 origin, embedder);
220 }
221
222 static void SetVoiceCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
223 jstring origin, jstring embedder, jint value) {
224 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC,
225 origin, ContentSettingsPattern::Wildcard(), value);
226 }
227
228 static void SetVideoCaptureSettingForOrigin(JNIEnv* env, jclass clazz,
229 jstring origin, jstring embedder, jint value) {
230 SetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA,
231 origin, ContentSettingsPattern::Wildcard(), value);
232 }
233
234 static scoped_refptr<CookieSettings> GetCookieSettings() {
235 Profile* profile = ProfileManager::GetActiveUserProfile();
236 return CookieSettings::Factory::GetForProfile(profile);
237 }
238
239 static void GetCookieOrigins(JNIEnv* env,
240 jclass clazz,
241 jobject list,
242 jboolean managedOnly) {
243 ContentSettingsForOneType all_settings;
244 GetCookieSettings()->GetCookieSettings(&all_settings);
245 const ContentSetting default_setting =
246 GetCookieSettings()->GetDefaultCookieSetting(nullptr);
247 for (const auto& settings_it : all_settings) {
248 if (settings_it.setting == default_setting)
249 continue;
250 if (managedOnly &&
251 HostContentSettingsMap::GetProviderTypeFromSource(settings_it.source) !=
252 HostContentSettingsMap::ProviderType::POLICY_PROVIDER) {
253 continue;
254 }
255 const std::string& origin = settings_it.primary_pattern.ToString();
256 const std::string& embedder = settings_it.secondary_pattern.ToString();
257 ScopedJavaLocalRef<jstring> jorigin = ConvertUTF8ToJavaString(env, origin);
258 ScopedJavaLocalRef<jstring> jembedder;
259 if (embedder != origin)
260 jembedder = ConvertUTF8ToJavaString(env, embedder);
261 Java_WebsitePreferenceBridge_insertCookieInfoIntoList(env, list,
262 jorigin.obj(), jembedder.obj());
263 }
264 }
265
266 static jint GetCookieSettingForOrigin(JNIEnv* env, jclass clazz,
267 jstring origin, jstring embedder) {
268 return GetSettingForOrigin(env, CONTENT_SETTINGS_TYPE_COOKIES, origin,
269 embedder);
270 }
271
272 static void SetCookieSettingForOrigin(JNIEnv* env, jclass clazz,
273 jstring origin, jstring embedder, jint value) {
274 GURL url(ConvertJavaStringToUTF8(env, origin));
275 ContentSettingsPattern primary_pattern(
276 ContentSettingsPattern::FromURLNoWildcard(url));
277 ContentSettingsPattern secondary_pattern(ContentSettingsPattern::Wildcard());
278 if (value == -1) {
279 GetCookieSettings()->ResetCookieSetting(primary_pattern, secondary_pattern);
280 } else {
281 GetCookieSettings()->SetCookieSetting(primary_pattern, secondary_pattern,
282 value ? CONTENT_SETTING_ALLOW : CONTENT_SETTING_BLOCK);
283 }
284 }
285
286 namespace {
287
288 class StorageInfoFetcher :
289 public base::RefCountedThreadSafe<StorageInfoFetcher> {
290 public:
291 StorageInfoFetcher(storage::QuotaManager* quota_manager,
292 const JavaRef<jobject>& java_callback)
293 : env_(base::android::AttachCurrentThread()),
294 quota_manager_(quota_manager),
295 java_callback_(java_callback) {
296 }
297
298 void Run() {
299 // QuotaManager must be called on IO thread, but java_callback must then be
300 // called back on UI thread.
301 BrowserThread::PostTask(
302 BrowserThread::IO, FROM_HERE,
303 base::Bind(&StorageInfoFetcher::GetUsageInfo, this));
304 }
305
306 protected:
307 virtual ~StorageInfoFetcher() {}
308
309 private:
310 friend class base::RefCountedThreadSafe<StorageInfoFetcher>;
311
312 void GetUsageInfo() {
313 // We will have no explicit owner as soon as we leave this method.
314 AddRef();
315 quota_manager_->GetUsageInfo(
316 base::Bind(&StorageInfoFetcher::OnGetUsageInfo, this));
317 }
318
319 void OnGetUsageInfo(const storage::UsageInfoEntries& entries) {
320 entries_.insert(entries_.begin(), entries.begin(), entries.end());
321 BrowserThread::PostTask(
322 BrowserThread::UI, FROM_HERE,
323 base::Bind(&StorageInfoFetcher::InvokeCallback, this));
324 Release();
325 }
326
327 void InvokeCallback() {
328 ScopedJavaLocalRef<jobject> list =
329 Java_WebsitePreferenceBridge_createStorageInfoList(env_);
330
331 storage::UsageInfoEntries::const_iterator i;
332 for (i = entries_.begin(); i != entries_.end(); ++i) {
333 if (i->usage <= 0) continue;
334 ScopedJavaLocalRef<jstring> host =
335 ConvertUTF8ToJavaString(env_, i->host);
336
337 Java_WebsitePreferenceBridge_insertStorageInfoIntoList(
338 env_, list.obj(), host.obj(), i->type, i->usage);
339 }
340 Java_StorageInfoReadyCallback_onStorageInfoReady(
341 env_, java_callback_.obj(), list.obj());
342 }
343
344 JNIEnv* env_;
345 storage::QuotaManager* quota_manager_;
346 ScopedJavaGlobalRef<jobject> java_callback_;
347 storage::UsageInfoEntries entries_;
348
349 DISALLOW_COPY_AND_ASSIGN(StorageInfoFetcher);
350 };
351
352 class StorageDataDeleter :
353 public base::RefCountedThreadSafe<StorageDataDeleter> {
354 public:
355 StorageDataDeleter(storage::QuotaManager* quota_manager,
356 const std::string& host,
357 storage::StorageType type,
358 const JavaRef<jobject>& java_callback)
359 : env_(base::android::AttachCurrentThread()),
360 quota_manager_(quota_manager),
361 host_(host),
362 type_(type),
363 java_callback_(java_callback) {
364 }
365
366 void Run() {
367 // QuotaManager must be called on IO thread, but java_callback must then be
368 // called back on UI thread. Grant ourself an extra reference to avoid
369 // being deleted after DeleteHostData will return.
370 AddRef();
371 BrowserThread::PostTask(
372 BrowserThread::IO, FROM_HERE,
373 base::Bind(&storage::QuotaManager::DeleteHostData,
374 quota_manager_,
375 host_,
376 type_,
377 storage::QuotaClient::kAllClientsMask,
378 base::Bind(&StorageDataDeleter::OnHostDataDeleted,
379 this)));
380 }
381
382 protected:
383 virtual ~StorageDataDeleter() {}
384
385 private:
386 friend class base::RefCountedThreadSafe<StorageDataDeleter>;
387
388 void OnHostDataDeleted(storage::QuotaStatusCode) {
389 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
390 quota_manager_->ResetUsageTracker(type_);
391 BrowserThread::PostTask(
392 BrowserThread::UI, FROM_HERE,
393 base::Bind(&StorageDataDeleter::InvokeCallback, this));
394 Release();
395 }
396
397 void InvokeCallback() {
398 Java_StorageInfoClearedCallback_onStorageInfoCleared(
399 env_, java_callback_.obj());
400 }
401
402 JNIEnv* env_;
403 storage::QuotaManager* quota_manager_;
404 std::string host_;
405 storage::StorageType type_;
406 ScopedJavaGlobalRef<jobject> java_callback_;
407 };
408
409 class LocalStorageInfoReadyCallback {
410 public:
411 LocalStorageInfoReadyCallback(
412 const ScopedJavaLocalRef<jobject>& java_callback)
413 : env_(base::android::AttachCurrentThread()),
414 java_callback_(java_callback) {
415 }
416
417 void OnLocalStorageModelInfoLoaded(
418 const std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>&
419 local_storage_info) {
420 ScopedJavaLocalRef<jobject> map =
421 Java_WebsitePreferenceBridge_createLocalStorageInfoMap(env_);
422
423 std::list<BrowsingDataLocalStorageHelper::LocalStorageInfo>::const_iterator
424 i;
425 for (i = local_storage_info.begin(); i != local_storage_info.end(); ++i) {
426 ScopedJavaLocalRef<jstring> full_origin =
427 ConvertUTF8ToJavaString(env_, i->origin_url.spec());
428 ScopedJavaLocalRef<jstring> origin =
429 ConvertUTF8ToJavaString(env_, i->origin_url.GetOrigin().spec());
430 Java_WebsitePreferenceBridge_insertLocalStorageInfoIntoMap(
431 env_, map.obj(), origin.obj(), full_origin.obj(), i->size);
432 }
433
434 Java_LocalStorageInfoReadyCallback_onLocalStorageInfoReady(
435 env_, java_callback_.obj(), map.obj());
436 delete this;
437 }
438
439 private:
440 JNIEnv* env_;
441 ScopedJavaGlobalRef<jobject> java_callback_;
442 };
443
444 } // anonymous namespace
445
446 // TODO(jknotten): These methods should not be static. Instead we should
447 // expose a class to Java so that the fetch requests can be cancelled,
448 // and manage the lifetimes of the callback (and indirectly the helper
449 // by having a reference to it).
450
451 // The helper methods (StartFetching, DeleteLocalStorageFile, DeleteDatabase)
452 // are asynchronous. A "use after free" error is not possible because the
453 // helpers keep a reference to themselves for the duration of their tasks,
454 // which includes callback invocation.
455
456 static void FetchLocalStorageInfo(JNIEnv* env, jclass clazz,
457 jobject java_callback) {
458 Profile* profile = ProfileManager::GetActiveUserProfile();
459 scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper(
460 new BrowsingDataLocalStorageHelper(profile));
461 // local_storage_callback will delete itself when it is run.
462 LocalStorageInfoReadyCallback* local_storage_callback =
463 new LocalStorageInfoReadyCallback(
464 ScopedJavaLocalRef<jobject>(env, java_callback));
465 local_storage_helper->StartFetching(
466 base::Bind(&LocalStorageInfoReadyCallback::OnLocalStorageModelInfoLoaded,
467 base::Unretained(local_storage_callback)));
468 }
469
470 static void FetchStorageInfo(JNIEnv* env, jclass clazz, jobject java_callback) {
471 Profile* profile = ProfileManager::GetActiveUserProfile();
472 scoped_refptr<StorageInfoFetcher> storage_info_fetcher(new StorageInfoFetcher(
473 content::BrowserContext::GetDefaultStoragePartition(
474 profile)->GetQuotaManager(),
475 ScopedJavaLocalRef<jobject>(env, java_callback)));
476 storage_info_fetcher->Run();
477 }
478
479 static void ClearLocalStorageData(JNIEnv* env, jclass clazz, jstring jorigin) {
480 Profile* profile = ProfileManager::GetActiveUserProfile();
481 scoped_refptr<BrowsingDataLocalStorageHelper> local_storage_helper =
482 new BrowsingDataLocalStorageHelper(profile);
483 GURL origin_url = GURL(ConvertJavaStringToUTF8(env, jorigin));
484 local_storage_helper->DeleteOrigin(origin_url);
485 }
486
487 static void ClearStorageData(JNIEnv* env,
488 jclass clazz,
489 jstring jhost,
490 jint type,
491 jobject java_callback) {
492 Profile* profile = ProfileManager::GetActiveUserProfile();
493 std::string host = ConvertJavaStringToUTF8(env, jhost);
494 scoped_refptr<StorageDataDeleter> storage_data_deleter(new StorageDataDeleter(
495 content::BrowserContext::GetDefaultStoragePartition(
496 profile)->GetQuotaManager(),
497 host,
498 static_cast<storage::StorageType>(type),
499 ScopedJavaLocalRef<jobject>(env, java_callback)));
500 storage_data_deleter->Run();
501 }
502
503 // Register native methods
504 bool RegisterWebsitePreferenceBridge(JNIEnv* env) {
505 return RegisterNativesImpl(env);
506 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698