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

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: comments 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 namespace cache_helper {
Bernhard Bauer 2016/01/28 12:15:14 I don't think this namespace is necessary, as all
knn 2016/01/28 18:10:37 More for structure but redundant now, I have made
20
21 const size_t kMaxCacheSize = 100;
22
23 void RecordAccess(std::list<GURL>* recent_urls, const GURL& url) {
24 // Move the url to the front of the cache.
Bernhard Bauer 2016/01/28 12:15:14 Nit: URL
knn 2016/01/28 18:10:37 Done.
25 recent_urls->remove(url);
26 recent_urls->push_front(url);
27 }
28
29 void InsertValue(std::map<GURL, std::string>* error_page_cache,
30 std::map<GURL, bool>* url_access_cache,
31 std::list<GURL>* recent_urls,
32 const GURL& url,
33 bool should_proceed,
34 const base::android::JavaParamRef<jstring>& j_error_page) {
Bernhard Bauer 2016/01/28 12:15:14 Use JavaRef (JavaParamRef is only a temporary thin
knn 2016/01/28 18:10:37 Good catch!
35 RecordAccess(recent_urls, url);
36 if (recent_urls->size() >= kMaxCacheSize) {
37 url_access_cache->erase(recent_urls->back());
38 error_page_cache->erase(recent_urls->back());
39 recent_urls->pop_back();
40 }
41 (*url_access_cache)[url] = should_proceed;
42 if (!j_error_page.is_null()) {
43 (*error_page_cache)[url] =
44 base::android::ConvertJavaStringToUTF8(j_error_page);
45 } else {
46 error_page_cache->erase(url);
47 }
48 }
49
50 } // namespace cache_helper
51
52 namespace async_helper {
53
54 void ShouldProceed(const GURL& url,
55 jlong callback,
56 const base::android::JavaRef<jobject>& java_provider) {
57 JNIEnv* env = base::android::AttachCurrentThread();
58 Java_ContentResolverWebRestrictionsProvider_shouldProceed(
59 env, java_provider.obj(), callback,
60 base::android::ConvertUTF8ToJavaString(env, url.spec()).obj());
61 }
62
63 void RequestPermission(const GURL& url,
64 jlong callback,
65 const base::android::JavaRef<jobject>& java_provider) {
66 JNIEnv* env = base::android::AttachCurrentThread();
67 Java_ContentResolverWebRestrictionsProvider_requestPermission(
68 env, java_provider.obj(), callback,
69 base::android::ConvertUTF8ToJavaString(env, url.spec()).obj());
70 }
71
72 } // namespace async_helper
73
74 } // namespace
75
76 // A wrapper to the callback class to facilitate getting a callback from java
77 // into C++. Objects of this class delete itself only when they are called back
78 // so we must ensure that happens even for error cases.
79 class SelfDeletingCallback {
80 public:
81 SelfDeletingCallback(const GURL& url,
82 const base::Callback<void(bool)>& callback,
83 const scoped_refptr<base::TaskRunner>& callback_runner,
84 ContentResolverWebRestrictionsProvider* provider);
85 void RequestSuccess(bool request_success);
86 void ShouldProceed(bool should_proceed,
87 const base::android::JavaParamRef<jstring>& error_page);
88
89 private:
90 // Only the callback can delete itself. We must ensure it is indeed
91 // called back.
92 ~SelfDeletingCallback() {}
93
94 GURL url_;
95 base::Callback<void(bool)> callback_;
96 scoped_refptr<base::TaskRunner> callback_runner_;
97 ContentResolverWebRestrictionsProvider* provider_;
98
99 DISALLOW_COPY_AND_ASSIGN(SelfDeletingCallback);
100 };
101
102 SelfDeletingCallback::SelfDeletingCallback(
103 const GURL& url,
104 const base::Callback<void(bool)>& callback,
105 const scoped_refptr<base::TaskRunner>& callback_runner,
106 ContentResolverWebRestrictionsProvider* provider)
107 : url_(url),
108 callback_(callback),
109 callback_runner_(callback_runner),
110 provider_(provider) {}
111
112 void SelfDeletingCallback::ShouldProceed(
113 bool should_proceed,
114 const base::android::JavaParamRef<jstring>& error_page) {
115 cache_helper::InsertValue(
Bernhard Bauer 2016/01/28 12:15:14 Just make this a method on |provider_|? That would
knn 2016/01/28 18:10:37 Done.
116 &provider_->error_page_cache_, &provider_->url_access_cache_,
117 &provider_->recent_urls_, url_, should_proceed, error_page);
118 callback_runner_->PostTask(FROM_HERE, base::Bind(callback_, should_proceed));
119 delete this;
120 }
121
122 void SelfDeletingCallback::RequestSuccess(bool request_success) {
123 callback_runner_->PostTask(FROM_HERE, base::Bind(callback_, request_success));
124 delete this;
125 }
126
127 // static
128 bool ContentResolverWebRestrictionsProvider::Register(JNIEnv* env) {
129 return RegisterNativesImpl(env);
130 }
131
132 ContentResolverWebRestrictionsProvider::ContentResolverWebRestrictionsProvider()
133 : initialized_(false), supports_request_(false) {}
134
135 ContentResolverWebRestrictionsProvider::
136 ~ContentResolverWebRestrictionsProvider() {}
137
138 void ContentResolverWebRestrictionsProvider::Initialize(
139 const std::string& content_provider_authority) {
140 ClearCache();
141 initialized_ = !content_provider_authority.empty();
142 if (!initialized_)
143 return;
144 JNIEnv* env = base::android::AttachCurrentThread();
145 java_provider_.Reset(Java_ContentResolverWebRestrictionsProvider_create(
146 env,
147 base::android::ConvertUTF8ToJavaString(env, content_provider_authority)
148 .obj(),
149 reinterpret_cast<jlong>(this)));
150 supports_request_ =
151 Java_ContentResolverWebRestrictionsProvider_supportsRequest(
152 env, java_provider_.obj());
153 }
154
155 UrlAccess ContentResolverWebRestrictionsProvider::ShouldProceed(
156 bool is_main_frame,
157 const GURL& url,
158 const base::Callback<void(bool)>& callback) {
159 if (!initialized_)
160 return ALLOW;
161 auto iter = url_access_cache_.find(url);
162 if (iter != url_access_cache_.end()) {
163 cache_helper::RecordAccess(&recent_urls_, url);
164 return iter->second ? ALLOW : DISALLOW;
165 }
166 scoped_refptr<base::SingleThreadTaskRunner> callback_runner =
167 base::ThreadTaskRunnerHandle::Get();
168 SelfDeletingCallback* wrapped_callback =
169 new SelfDeletingCallback(url, callback, callback_runner, this);
Bernhard Bauer 2016/01/28 12:15:14 I was going to write, "please mention that this de
knn 2016/01/28 18:10:37 Indeed we do not need to make it self deleting giv
170 content::BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior(
Bernhard Bauer 2016/01/28 12:15:14 Speaking of multiple threads, you want to use a Se
knn 2016/01/28 18:10:37 Done.
171 FROM_HERE,
172 base::Bind(&async_helper::ShouldProceed, url,
173 reinterpret_cast<jlong>(wrapped_callback), java_provider_),
174 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
175 return PENDING;
176 }
177
178 bool ContentResolverWebRestrictionsProvider::SupportsRequest() const {
179 return initialized_ && supports_request_;
180 }
181
182 bool ContentResolverWebRestrictionsProvider::GetErrorHtml(
183 const GURL& url,
184 std::string* error_page) const {
185 if (!initialized_)
186 return false;
187 auto iter = error_page_cache_.find(url);
188 if (iter == error_page_cache_.end())
189 return false;
190 *error_page = iter->second;
191 return true;
192 }
193
194 void ContentResolverWebRestrictionsProvider::RequestPermission(
195 const GURL& url,
196 const base::Callback<void(bool)>& request_success) {
197 if (!initialized_) {
198 request_success.Run(false);
199 return;
200 }
201 scoped_refptr<base::SingleThreadTaskRunner> callback_runner =
202 base::ThreadTaskRunnerHandle::Get();
203 SelfDeletingCallback* wrapped_callback =
204 new SelfDeletingCallback(url, request_success, callback_runner, this);
205 content::BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior(
206 FROM_HERE,
207 base::Bind(&async_helper::RequestPermission, url,
208 reinterpret_cast<jlong>(wrapped_callback), java_provider_),
209 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
210 }
211
212 void ContentResolverWebRestrictionsProvider::ClearCache() {
213 error_page_cache_.clear();
214 url_access_cache_.clear();
215 recent_urls_.clear();
216 }
217
218 void ShouldProceed(JNIEnv* env,
219 const base::android::JavaParamRef<jclass>& clazz,
220 jlong callback_ptr,
221 jboolean should_proceed,
222 const base::android::JavaParamRef<jstring>& error_page) {
223 SelfDeletingCallback* callback =
224 reinterpret_cast<SelfDeletingCallback*>(callback_ptr);
225 callback->ShouldProceed(should_proceed, error_page);
226 }
227
228 void RequestSuccess(JNIEnv* env,
229 const base::android::JavaParamRef<jclass>& clazz,
230 jlong callback_ptr,
231 jboolean request_success) {
232 SelfDeletingCallback* callback =
233 reinterpret_cast<SelfDeletingCallback*>(callback_ptr);
234 callback->RequestSuccess(request_success);
235 }
236
237 void NotifyWebRestrictionsChanged(
238 JNIEnv* env,
239 const base::android::JavaParamRef<jclass>& clazz,
240 jlong provider_ptr) {
241 ContentResolverWebRestrictionsProvider* provider =
242 reinterpret_cast<ContentResolverWebRestrictionsProvider*>(provider_ptr);
243 // TODO(knn): Also reload existing interstitials/error pages.
244 provider->ClearCache();
245 }
246
247 } // namespace web_restrictions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698