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

Side by Side Diff: components/web_restrictions/content_resolver_web_restrictions_provider.cc

Issue 1631603002: Web restrictions component only. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rm thread_checker Created 4 years, 10 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 "components/web_restrictions/content_resolver_web_restrictions_provider .h"
6
7 #include "base/android/jni_string.h"
8 #include "base/android/scoped_java_ref.h"
9 #include "base/bind.h"
10 #include "base/location.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "content/public/browser/browser_thread.h"
13 #include "jni/ContentResolverWebRestrictionsProvider_jni.h"
14
15 namespace web_restrictions {
16
17 namespace {
18
19 const size_t kMaxCacheSize = 100;
20
21 void AsyncShouldProceed(const GURL& url,
22 jlong callback,
23 const base::android::JavaRef<jobject>& java_provider) {
24 JNIEnv* env = base::android::AttachCurrentThread();
25 Java_ContentResolverWebRestrictionsProvider_shouldProceed(
26 env, java_provider.obj(), callback,
27 base::android::ConvertUTF8ToJavaString(env, url.spec()).obj());
28 }
29
30 void AsyncRequestPermission(
31 const GURL& url,
32 jlong callback,
33 const base::android::JavaRef<jobject>& java_provider) {
34 JNIEnv* env = base::android::AttachCurrentThread();
35 Java_ContentResolverWebRestrictionsProvider_requestPermission(
36 env, java_provider.obj(), callback,
37 base::android::ConvertUTF8ToJavaString(env, url.spec()).obj());
38 }
39
40 bool AsyncCheckSupportsRequest(
41 const base::android::JavaRef<jobject>& java_provider) {
42 JNIEnv* env = base::android::AttachCurrentThread();
43 return Java_ContentResolverWebRestrictionsProvider_supportsRequest(
44 env, java_provider.obj());
45 }
46
47 } // namespace
48
49 // A wrapper to the callback class to facilitate getting a callback from java
50 // into C++. Objects of this class delete itself only when they are called back
51 // so we must ensure that happens even for error cases.
52 class SelfDeletingCallback {
53 public:
54 SelfDeletingCallback(
55 const GURL& url,
56 const base::Callback<void(bool)>& callback,
57 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
58 ContentResolverWebRestrictionsProvider* provider);
59 void RequestSuccess(bool request_success);
60 void ShouldProceed(bool should_proceed, std::string error_page);
61
62 private:
63 // Only the callback can delete itself. We must ensure it is indeed
64 // called back.
65 ~SelfDeletingCallback() {}
66
67 GURL url_;
68 base::Callback<void(bool)> callback_;
69 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
70 ContentResolverWebRestrictionsProvider* provider_;
71
72 DISALLOW_COPY_AND_ASSIGN(SelfDeletingCallback);
73 };
74
75 SelfDeletingCallback::SelfDeletingCallback(
76 const GURL& url,
77 const base::Callback<void(bool)>& callback,
78 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
79 ContentResolverWebRestrictionsProvider* provider)
80 : url_(url),
81 callback_(callback),
82 task_runner_(task_runner),
83 provider_(provider) {}
84
85 void SelfDeletingCallback::ShouldProceed(bool should_proceed,
aberent 2016/02/03 19:26:22 Further to my previous threading comments. I think
knn 2016/02/03 21:23:21 Good catch! Fixed this now.
86 std::string error_page) {
87 task_runner_->PostTask(
88 FROM_HERE,
89 base::Bind(&ContentResolverWebRestrictionsProvider::UpdateCache,
90 base::Unretained(provider_), url_, should_proceed,
91 error_page));
aberent 2016/02/03 19:26:22 Even if we are still using the same authority when
knn 2016/02/03 21:23:21 Fixed.
92 task_runner_->PostTask(FROM_HERE, base::Bind(callback_, should_proceed));
aberent 2016/02/03 19:26:22 And the authority could change between the first a
knn 2016/02/03 21:23:21 So, we probably don't care about requests that wer
93 delete this;
94 }
95
96 void SelfDeletingCallback::RequestSuccess(bool request_success) {
97 task_runner_->PostTask(FROM_HERE, base::Bind(callback_, request_success));
98 delete this;
99 }
100
101 // static
102 bool ContentResolverWebRestrictionsProvider::Register(JNIEnv* env) {
103 return RegisterNativesImpl(env);
104 }
105
106 ContentResolverWebRestrictionsProvider::ContentResolverWebRestrictionsProvider()
107 : initialized_(false), supports_request_(false) {
108 single_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get();
109 base::SequencedWorkerPool* worker_pool =
110 content::BrowserThread::GetBlockingPool();
111 background_task_runner_ =
112 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
113 worker_pool->GetSequenceToken(),
114 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
115 }
116
117 ContentResolverWebRestrictionsProvider::
118 ~ContentResolverWebRestrictionsProvider() {
119 if (java_provider_.is_null())
120 return;
121 JNIEnv* env = base::android::AttachCurrentThread();
122 Java_ContentResolverWebRestrictionsProvider_onDestroy(env,
123 java_provider_.obj());
124 }
125
126 void ContentResolverWebRestrictionsProvider::SetAuthority(
127 const std::string& content_provider_authority) {
128 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
129 // Destroy any existing content resolver.
130 JNIEnv* env = base::android::AttachCurrentThread();
131 if (!java_provider_.is_null()) {
132 Java_ContentResolverWebRestrictionsProvider_onDestroy(env,
133 java_provider_.obj());
134 java_provider_.Reset();
135 }
136 ClearCache();
137
138 // Initialize the content resolver.
139 initialized_ = !content_provider_authority.empty();
140 if (!initialized_)
141 return;
142 java_provider_.Reset(Java_ContentResolverWebRestrictionsProvider_create(
143 env,
144 base::android::ConvertUTF8ToJavaString(env, content_provider_authority)
145 .obj(),
146 reinterpret_cast<jlong>(this)));
147 supports_request_ = false;
148 base::PostTaskAndReplyWithResult(
149 content::BrowserThread::GetBlockingPool(), FROM_HERE,
150 base::Bind(&AsyncCheckSupportsRequest, java_provider_),
151 base::Bind(&ContentResolverWebRestrictionsProvider::RequestSupportKnown,
152 base::Unretained(this)));
153 }
154
155 UrlAccess ContentResolverWebRestrictionsProvider::ShouldProceed(
156 bool is_main_frame,
157 const GURL& url,
158 const base::Callback<void(bool)>& callback) {
159 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
160 if (!initialized_)
161 return ALLOW;
162 auto iter = url_access_cache_.find(url);
163 if (iter != url_access_cache_.end()) {
164 RecordURLAccess(url);
165 return iter->second ? ALLOW : DISALLOW;
166 }
167 SelfDeletingCallback* wrapped_callback =
168 new SelfDeletingCallback(url, callback, single_thread_task_runner_, this);
169 background_task_runner_->PostTask(
170 FROM_HERE,
171 base::Bind(&AsyncShouldProceed, url,
172 reinterpret_cast<jlong>(wrapped_callback), java_provider_));
173 return PENDING;
174 }
175
176 bool ContentResolverWebRestrictionsProvider::SupportsRequest() const {
177 return initialized_ && supports_request_;
178 }
179
180 bool ContentResolverWebRestrictionsProvider::GetErrorHtml(
181 const GURL& url,
182 std::string* error_page) const {
183 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
184 if (!initialized_)
185 return false;
186 auto iter = error_page_cache_.find(url);
187 if (iter == error_page_cache_.end())
188 return false;
189 *error_page = iter->second;
190 return true;
191 }
192
193 void ContentResolverWebRestrictionsProvider::RequestPermission(
194 const GURL& url,
195 const base::Callback<void(bool)>& request_success) {
196 if (!initialized_) {
197 request_success.Run(false);
198 return;
199 }
200 SelfDeletingCallback* wrapped_callback = new SelfDeletingCallback(
201 url, request_success, single_thread_task_runner_, this);
202 background_task_runner_->PostTask(
203 FROM_HERE,
204 base::Bind(&AsyncRequestPermission, url,
205 reinterpret_cast<jlong>(wrapped_callback), java_provider_));
206 }
207
208 void ContentResolverWebRestrictionsProvider::OnWebRestrictionsChanged() {
209 single_thread_task_runner_->PostTask(
210 FROM_HERE, base::Bind(&ContentResolverWebRestrictionsProvider::ClearCache,
211 base::Unretained(this)));
212 }
213
214 void ContentResolverWebRestrictionsProvider::RecordURLAccess(const GURL& url) {
215 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
216 // Move the URL to the front of the cache.
217 recent_urls_.remove(url);
218 recent_urls_.push_front(url);
219 }
220
221 void ContentResolverWebRestrictionsProvider::UpdateCache(
222 const GURL& url,
223 bool should_proceed,
224 std::string error_page) {
225 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
226 RecordURLAccess(url);
227 if (recent_urls_.size() >= kMaxCacheSize) {
228 url_access_cache_.erase(recent_urls_.back());
229 error_page_cache_.erase(recent_urls_.back());
230 recent_urls_.pop_back();
231 }
232 url_access_cache_[url] = should_proceed;
233 if (!error_page.empty()) {
234 error_page_cache_[url] = error_page;
235 } else {
236 error_page_cache_.erase(url);
237 }
238 }
239
240 void ContentResolverWebRestrictionsProvider::RequestSupportKnown(
241 bool supports_request) {
242 // |supports_request_| is initialized to false.
243 DCHECK(!supports_request_);
244 supports_request_ = supports_request;
245 }
246
247 void ContentResolverWebRestrictionsProvider::ClearCache() {
248 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
249 error_page_cache_.clear();
250 url_access_cache_.clear();
251 recent_urls_.clear();
252 }
253
254 void ShouldProceed(JNIEnv* env,
255 const base::android::JavaParamRef<jclass>& clazz,
256 jlong callback_ptr,
257 jboolean should_proceed,
258 const base::android::JavaParamRef<jstring>& j_error_page) {
259 SelfDeletingCallback* callback =
260 reinterpret_cast<SelfDeletingCallback*>(callback_ptr);
261 std::string error_page;
262 if (!j_error_page.is_null())
263 error_page = base::android::ConvertJavaStringToUTF8(j_error_page);
264 callback->ShouldProceed(should_proceed, error_page);
265 }
266
267 void RequestSuccess(JNIEnv* env,
268 const base::android::JavaParamRef<jclass>& clazz,
269 jlong callback_ptr,
270 jboolean request_success) {
271 SelfDeletingCallback* callback =
272 reinterpret_cast<SelfDeletingCallback*>(callback_ptr);
273 callback->RequestSuccess(request_success);
274 }
275
276 void NotifyWebRestrictionsChanged(
277 JNIEnv* env,
278 const base::android::JavaParamRef<jclass>& clazz,
279 jlong provider_ptr) {
280 ContentResolverWebRestrictionsProvider* provider =
281 reinterpret_cast<ContentResolverWebRestrictionsProvider*>(provider_ptr);
282 // TODO(knn): Also reload existing interstitials/error pages.
283 provider->OnWebRestrictionsChanged();
284 }
285
286 } // namespace web_restrictions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698