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

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: use sequenced task runner 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(const GURL& url,
55 const base::Callback<void(bool)>& callback,
56 const scoped_refptr<base::TaskRunner>& callback_runner,
57 ContentResolverWebRestrictionsProvider* provider);
58 void RequestSuccess(bool request_success);
59 void ShouldProceed(bool should_proceed,
60 const base::android::JavaRef<jstring>& 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::TaskRunner> callback_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::TaskRunner>& callback_runner,
79 ContentResolverWebRestrictionsProvider* provider)
80 : url_(url),
81 callback_(callback),
82 callback_runner_(callback_runner),
83 provider_(provider) {}
84
85 void SelfDeletingCallback::ShouldProceed(
86 bool should_proceed,
87 const base::android::JavaRef<jstring>& error_page) {
88 provider_->UpdateCache(url_, should_proceed, error_page);
Bernhard Bauer 2016/02/02 15:03:56 We call this on the background thread, but we read
knn 2016/02/03 15:47:18 Done.
89 callback_runner_->PostTask(FROM_HERE, base::Bind(callback_, should_proceed));
90 delete this;
91 }
92
93 void SelfDeletingCallback::RequestSuccess(bool request_success) {
94 callback_runner_->PostTask(FROM_HERE, base::Bind(callback_, request_success));
95 delete this;
96 }
97
98 // static
99 bool ContentResolverWebRestrictionsProvider::Register(JNIEnv* env) {
100 return RegisterNativesImpl(env);
101 }
102
103 ContentResolverWebRestrictionsProvider::ContentResolverWebRestrictionsProvider()
104 : initialized_(false), supports_request_(false) {
105 base::SequencedWorkerPool* worker_pool =
106 content::BrowserThread::GetBlockingPool();
107 cache_update_task_runner_ =
108 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
109 worker_pool->GetSequenceToken(),
110 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
111 }
112
113 ContentResolverWebRestrictionsProvider::
114 ~ContentResolverWebRestrictionsProvider() {}
115
116 void ContentResolverWebRestrictionsProvider::SetAuthority(
117 const std::string& content_provider_authority) {
118 // Destroy any existing content resolver.
119 JNIEnv* env = base::android::AttachCurrentThread();
120 if (!java_provider_.is_null()) {
121 Java_ContentResolverWebRestrictionsProvider_onDestroy(env,
Bernhard Bauer 2016/02/02 15:03:56 Call this in the destructor as well?
knn 2016/02/03 15:47:18 Done.
122 java_provider_.obj());
123 java_provider_.Reset();
124 }
125 ClearCache();
126
127 // Initialize the content resolver.
128 initialized_ = !content_provider_authority.empty();
129 if (!initialized_)
130 return;
131 java_provider_.Reset(Java_ContentResolverWebRestrictionsProvider_create(
132 env,
133 base::android::ConvertUTF8ToJavaString(env, content_provider_authority)
134 .obj(),
135 reinterpret_cast<jlong>(this)));
136 supports_request_ = false;
137 base::PostTaskAndReplyWithResult(
138 content::BrowserThread::GetBlockingPool(), FROM_HERE,
139 base::Bind(&AsyncCheckSupportsRequest, java_provider_),
140 base::Bind(&ContentResolverWebRestrictionsProvider::RequestSupportKnown,
141 base::Unretained(this)));
142 }
143
144 UrlAccess ContentResolverWebRestrictionsProvider::ShouldProceed(
145 bool is_main_frame,
146 const GURL& url,
147 const base::Callback<void(bool)>& callback) {
148 if (!initialized_)
149 return ALLOW;
150 auto iter = url_access_cache_.find(url);
151 if (iter != url_access_cache_.end()) {
152 RecordURLAccess(url);
153 return iter->second ? ALLOW : DISALLOW;
154 }
155 scoped_refptr<base::SingleThreadTaskRunner> callback_runner =
156 base::ThreadTaskRunnerHandle::Get();
157 SelfDeletingCallback* wrapped_callback =
158 new SelfDeletingCallback(url, callback, callback_runner, this);
159 cache_update_task_runner_->PostTask(
160 FROM_HERE,
161 base::Bind(&AsyncShouldProceed, url,
162 reinterpret_cast<jlong>(wrapped_callback), java_provider_));
163 return PENDING;
164 }
165
166 bool ContentResolverWebRestrictionsProvider::SupportsRequest() const {
167 return initialized_ && supports_request_;
168 }
169
170 bool ContentResolverWebRestrictionsProvider::GetErrorHtml(
171 const GURL& url,
172 std::string* error_page) const {
173 if (!initialized_)
174 return false;
175 auto iter = error_page_cache_.find(url);
176 if (iter == error_page_cache_.end())
177 return false;
178 *error_page = iter->second;
179 return true;
180 }
181
182 void ContentResolverWebRestrictionsProvider::RequestPermission(
183 const GURL& url,
184 const base::Callback<void(bool)>& request_success) {
185 if (!initialized_) {
186 request_success.Run(false);
187 return;
188 }
189 scoped_refptr<base::SingleThreadTaskRunner> callback_runner =
190 base::ThreadTaskRunnerHandle::Get();
191 SelfDeletingCallback* wrapped_callback =
192 new SelfDeletingCallback(url, request_success, callback_runner, this);
193 cache_update_task_runner_->PostTask(
194 FROM_HERE,
195 base::Bind(&AsyncRequestPermission, url,
196 reinterpret_cast<jlong>(wrapped_callback), java_provider_));
197 }
198
199 void ContentResolverWebRestrictionsProvider::OnWebRestrictionsChanged() {
200 cache_update_task_runner_->PostTask(
201 FROM_HERE, base::Bind(&ContentResolverWebRestrictionsProvider::ClearCache,
202 base::Unretained(this)));
203 }
204
205 void ContentResolverWebRestrictionsProvider::RecordURLAccess(const GURL& url) {
206 // Move the URL to the front of the cache.
207 recent_urls_.remove(url);
208 recent_urls_.push_front(url);
209 }
210
211 void ContentResolverWebRestrictionsProvider::UpdateCache(
212 const GURL& url,
213 bool should_proceed,
214 const base::android::JavaRef<jstring>& j_error_page) {
215 RecordURLAccess(url);
216 if (recent_urls_.size() >= kMaxCacheSize) {
217 url_access_cache_.erase(recent_urls_.back());
218 error_page_cache_.erase(recent_urls_.back());
219 recent_urls_.pop_back();
220 }
221 url_access_cache_[url] = should_proceed;
222 if (!j_error_page.is_null()) {
223 error_page_cache_[url] =
224 base::android::ConvertJavaStringToUTF8(j_error_page);
225 } else {
226 error_page_cache_.erase(url);
227 }
228 }
229
230 void ContentResolverWebRestrictionsProvider::RequestSupportKnown(
231 bool supports_request) {
232 // supports_request_ is initialized to false.
Bernhard Bauer 2016/02/02 15:03:56 Wrap this in |pipe symbols|?
knn 2016/02/03 15:47:18 Done.
233 DCHECK(!supports_request_);
234 supports_request_ = supports_request;
235 }
236
237 void ContentResolverWebRestrictionsProvider::ClearCache() {
238 error_page_cache_.clear();
239 url_access_cache_.clear();
240 recent_urls_.clear();
241 }
242
243 void ShouldProceed(JNIEnv* env,
244 const base::android::JavaParamRef<jclass>& clazz,
245 jlong callback_ptr,
246 jboolean should_proceed,
247 const base::android::JavaParamRef<jstring>& error_page) {
248 SelfDeletingCallback* callback =
249 reinterpret_cast<SelfDeletingCallback*>(callback_ptr);
250 callback->ShouldProceed(should_proceed, error_page);
251 }
252
253 void RequestSuccess(JNIEnv* env,
254 const base::android::JavaParamRef<jclass>& clazz,
255 jlong callback_ptr,
256 jboolean request_success) {
257 SelfDeletingCallback* callback =
258 reinterpret_cast<SelfDeletingCallback*>(callback_ptr);
259 callback->RequestSuccess(request_success);
260 }
261
262 void NotifyWebRestrictionsChanged(
263 JNIEnv* env,
264 const base::android::JavaParamRef<jclass>& clazz,
265 jlong provider_ptr) {
266 ContentResolverWebRestrictionsProvider* provider =
267 reinterpret_cast<ContentResolverWebRestrictionsProvider*>(provider_ptr);
268 // TODO(knn): Also reload existing interstitials/error pages.
269 provider->OnWebRestrictionsChanged();
270 }
271
272 } // namespace web_restrictions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698