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

Side by Side Diff: components/web_restrictions/browser/web_restrictions_client.cc

Issue 1890203002: Implement Web Restrictions in WebView. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix final nits Created 4 years, 4 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
1 // Copyright 2015 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/web_restrictions/browser/web_restrictions_client.h" 5 #include "components/web_restrictions/browser/web_restrictions_client.h"
6 6
7 #include "base/android/jni_string.h" 7 #include "base/android/jni_string.h"
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/logging.h"
10 #include "base/threading/thread_task_runner_handle.h" 11 #include "base/threading/thread_task_runner_handle.h"
11 #include "content/public/browser/browser_thread.h" 12 #include "content/public/browser/browser_thread.h"
12 #include "jni/WebRestrictionsClient_jni.h" 13 #include "jni/WebRestrictionsClient_jni.h"
13 14
14 using base::android::ScopedJavaGlobalRef; 15 using base::android::ScopedJavaGlobalRef;
15 16
16 namespace web_restrictions { 17 namespace web_restrictions {
17 18
18 namespace { 19 namespace {
19 20
20 const size_t kMaxCacheSize = 100; 21 const size_t kMaxCacheSize = 100;
21 22
22 bool RequestPermissionTask( 23 bool RequestPermissionTask(
23 const GURL& url, 24 const std::string& url,
24 const base::android::JavaRef<jobject>& java_provider) { 25 const base::android::JavaRef<jobject>& java_provider) {
25 JNIEnv* env = base::android::AttachCurrentThread(); 26 JNIEnv* env = base::android::AttachCurrentThread();
26 return Java_WebRestrictionsClient_requestPermission( 27 return Java_WebRestrictionsClient_requestPermission(
27 env, java_provider, 28 env, java_provider,
28 base::android::ConvertUTF8ToJavaString(env, url.spec())); 29 base::android::ConvertUTF8ToJavaString(env, url));
29 } 30 }
30 31
31 bool CheckSupportsRequestTask( 32 bool CheckSupportsRequestTask(
32 const base::android::JavaRef<jobject>& java_provider) { 33 const base::android::JavaRef<jobject>& java_provider) {
33 JNIEnv* env = base::android::AttachCurrentThread(); 34 JNIEnv* env = base::android::AttachCurrentThread();
34 return Java_WebRestrictionsClient_supportsRequest(env, java_provider); 35 return Java_WebRestrictionsClient_supportsRequest(env, java_provider);
35 } 36 }
36 37
37 } // namespace 38 } // namespace
38 39
39 // static 40 // static
40 bool WebRestrictionsClient::Register(JNIEnv* env) { 41 bool WebRestrictionsClient::Register(JNIEnv* env) {
41 return RegisterNativesImpl(env); 42 return RegisterNativesImpl(env);
42 } 43 }
43 44
44 WebRestrictionsClient::WebRestrictionsClient() 45 WebRestrictionsClient::WebRestrictionsClient()
45 : initialized_(false), supports_request_(false) { 46 : initialized_(false), supports_request_(false) {
46 single_thread_task_runner_ = base::ThreadTaskRunnerHandle::Get();
47 base::SequencedWorkerPool* worker_pool = 47 base::SequencedWorkerPool* worker_pool =
48 content::BrowserThread::GetBlockingPool(); 48 content::BrowserThread::GetBlockingPool();
49 background_task_runner_ = 49 background_task_runner_ =
50 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior( 50 worker_pool->GetSequencedTaskRunnerWithShutdownBehavior(
51 worker_pool->GetSequenceToken(), 51 worker_pool->GetSequenceToken(),
52 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); 52 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
53 } 53 }
54 54
55 WebRestrictionsClient::~WebRestrictionsClient() { 55 WebRestrictionsClient::~WebRestrictionsClient() {
56 if (java_provider_.is_null()) 56 if (java_provider_.is_null())
57 return; 57 return;
58 JNIEnv* env = base::android::AttachCurrentThread(); 58 JNIEnv* env = base::android::AttachCurrentThread();
59 Java_WebRestrictionsClient_onDestroy(env, java_provider_); 59 Java_WebRestrictionsClient_onDestroy(env, java_provider_);
60 java_provider_.Reset(); 60 java_provider_.Reset();
61 } 61 }
62 62
63 void WebRestrictionsClient::SetAuthority( 63 void WebRestrictionsClient::SetAuthority(
64 const std::string& content_provider_authority) { 64 const std::string& content_provider_authority) {
65 DCHECK(single_thread_task_runner_->BelongsToCurrentThread()); 65 // This is called from the UI thread, but class members should only be
66 // accessed from the IO thread.
67 content::BrowserThread::PostTask(
68 content::BrowserThread::IO, FROM_HERE,
69 base::Bind(&WebRestrictionsClient::SetAuthorityTask,
70 base::Unretained(this), content_provider_authority));
71 }
72
73 void WebRestrictionsClient::SetAuthorityTask(
74 const std::string& content_provider_authority) {
75 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
66 // Destroy any existing content resolver. 76 // Destroy any existing content resolver.
67 JNIEnv* env = base::android::AttachCurrentThread(); 77 JNIEnv* env = base::android::AttachCurrentThread();
68 if (!java_provider_.is_null()) { 78 if (!java_provider_.is_null()) {
69 Java_WebRestrictionsClient_onDestroy(env, java_provider_); 79 Java_WebRestrictionsClient_onDestroy(env, java_provider_);
70 java_provider_.Reset(); 80 java_provider_.Reset();
71 } 81 }
72 ClearCache(); 82 ClearCache();
73 provider_authority_ = content_provider_authority; 83 provider_authority_ = content_provider_authority;
74 84
75 // Initialize the content resolver. 85 // Initialize the content resolver.
76 initialized_ = !content_provider_authority.empty(); 86 initialized_ = !content_provider_authority.empty();
77 if (!initialized_) 87 if (!initialized_)
78 return; 88 return;
79 java_provider_.Reset(Java_WebRestrictionsClient_create( 89 java_provider_.Reset(Java_WebRestrictionsClient_create(
80 env, 90 env,
81 base::android::ConvertUTF8ToJavaString(env, content_provider_authority), 91 base::android::ConvertUTF8ToJavaString(env, content_provider_authority),
82 reinterpret_cast<jlong>(this))); 92 reinterpret_cast<jlong>(this)));
83 supports_request_ = false; 93 supports_request_ = false;
84 base::PostTaskAndReplyWithResult( 94 base::PostTaskAndReplyWithResult(
85 content::BrowserThread::GetBlockingPool(), FROM_HERE, 95 content::BrowserThread::GetBlockingPool(), FROM_HERE,
86 base::Bind(&CheckSupportsRequestTask, java_provider_), 96 base::Bind(&CheckSupportsRequestTask, java_provider_),
87 base::Bind(&WebRestrictionsClient::RequestSupportKnown, 97 base::Bind(&WebRestrictionsClient::RequestSupportKnown,
88 base::Unretained(this), provider_authority_)); 98 base::Unretained(this), provider_authority_));
89 } 99 }
90 100
91 UrlAccess WebRestrictionsClient::ShouldProceed( 101 UrlAccess WebRestrictionsClient::ShouldProceed(
92 bool is_main_frame, 102 bool is_main_frame,
93 const GURL& url, 103 const std::string& url,
94 const base::Callback<void(bool)>& callback) { 104 const base::Callback<void(bool)>& callback) {
95 DCHECK(single_thread_task_runner_->BelongsToCurrentThread()); 105 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
96 if (!initialized_) 106 if (!initialized_)
97 return ALLOW; 107 return ALLOW;
98 auto iter = cache_.find(url); 108
99 if (iter != cache_.end()) { 109 std::unique_ptr<const WebRestrictionsClientResult> result =
110 cache_.GetCacheEntry(url);
111 if (result) {
100 RecordURLAccess(url); 112 RecordURLAccess(url);
101 JNIEnv* env = base::android::AttachCurrentThread(); 113 return result->ShouldProceed() ? ALLOW : DISALLOW;
102 return Java_ShouldProceedResult_shouldProceed(env, iter->second) ? ALLOW
103 : DISALLOW;
104 } 114 }
105 base::PostTaskAndReplyWithResult( 115 base::PostTaskAndReplyWithResult(
106 background_task_runner_.get(), FROM_HERE, 116 background_task_runner_.get(), FROM_HERE,
107 base::Bind(&WebRestrictionsClient::ShouldProceedTask, url, 117 base::Bind(&WebRestrictionsClient::ShouldProceedTask, url,
108 java_provider_), 118 java_provider_),
109 base::Bind(&WebRestrictionsClient::OnShouldProceedComplete, 119 base::Bind(&WebRestrictionsClient::OnShouldProceedComplete,
110 base::Unretained(this), provider_authority_, url, callback)); 120 base::Unretained(this), provider_authority_, url, callback));
111 121
112 return PENDING; 122 return PENDING;
113 } 123 }
114 124
115 bool WebRestrictionsClient::SupportsRequest() const { 125 bool WebRestrictionsClient::SupportsRequest() const {
116 return initialized_ && supports_request_; 126 return initialized_ && supports_request_;
117 } 127 }
118 128
119 int WebRestrictionsClient::GetResultColumnCount(const GURL& url) const {
120 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
121 if (!initialized_)
122 return 0;
123 auto iter = cache_.find(url);
124 if (iter == cache_.end())
125 return 0;
126 return Java_ShouldProceedResult_getColumnCount(
127 base::android::AttachCurrentThread(), iter->second);
128 }
129
130 std::string WebRestrictionsClient::GetResultColumnName(const GURL& url,
131 int column) const {
132 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
133 if (!initialized_)
134 return std::string();
135 auto iter = cache_.find(url);
136 if (iter == cache_.end())
137 return std::string();
138
139 JNIEnv* env = base::android::AttachCurrentThread();
140 return base::android::ConvertJavaStringToUTF8(
141 env,
142 Java_ShouldProceedResult_getColumnName(env, iter->second, column).obj());
143 }
144
145 int WebRestrictionsClient::GetResultIntValue(const GURL& url,
146 int column) const {
147 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
148 if (!initialized_)
149 return 0;
150 auto iter = cache_.find(url);
151 if (iter == cache_.end())
152 return 0;
153 return Java_ShouldProceedResult_getInt(base::android::AttachCurrentThread(),
154 iter->second, column);
155 }
156
157 std::string WebRestrictionsClient::GetResultStringValue(const GURL& url,
158 int column) const {
159 DCHECK(single_thread_task_runner_->BelongsToCurrentThread());
160 if (!initialized_)
161 return std::string();
162 auto iter = cache_.find(url);
163 if (iter == cache_.end())
164 return std::string();
165
166 JNIEnv* env = base::android::AttachCurrentThread();
167 return base::android::ConvertJavaStringToUTF8(
168 env, Java_ShouldProceedResult_getString(env, iter->second, column).obj());
169 }
170
171 void WebRestrictionsClient::RequestPermission( 129 void WebRestrictionsClient::RequestPermission(
172 const GURL& url, 130 const std::string& url,
173 const base::Callback<void(bool)>& request_success) { 131 const base::Callback<void(bool)>& request_success) {
174 if (!initialized_) { 132 if (!initialized_) {
175 request_success.Run(false); 133 request_success.Run(false);
176 return; 134 return;
177 } 135 }
178 base::PostTaskAndReplyWithResult( 136 base::PostTaskAndReplyWithResult(
179 background_task_runner_.get(), FROM_HERE, 137 background_task_runner_.get(), FROM_HERE,
180 base::Bind(&RequestPermissionTask, url, java_provider_), request_success); 138 base::Bind(&RequestPermissionTask, url, java_provider_), request_success);
181 } 139 }
182 140
183 void WebRestrictionsClient::OnWebRestrictionsChanged() { 141 void WebRestrictionsClient::OnWebRestrictionsChanged(
184 single_thread_task_runner_->PostTask( 142 JNIEnv* env,
185 FROM_HERE, 143 const base::android::JavaParamRef<jobject>& obj) {
144 content::BrowserThread::PostTask(
145 content::BrowserThread::IO, FROM_HERE,
186 base::Bind(&WebRestrictionsClient::ClearCache, base::Unretained(this))); 146 base::Bind(&WebRestrictionsClient::ClearCache, base::Unretained(this)));
187 } 147 }
188 148
189 void WebRestrictionsClient::RecordURLAccess(const GURL& url) { 149 void WebRestrictionsClient::RecordURLAccess(const std::string& url) {
190 DCHECK(single_thread_task_runner_->BelongsToCurrentThread()); 150 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
191 // Move the URL to the front of the cache. 151 // Move the URL to the front of the cache.
192 recent_urls_.remove(url); 152 recent_urls_.remove(url);
193 recent_urls_.push_front(url); 153 recent_urls_.push_front(url);
194 } 154 }
195 155
196 void WebRestrictionsClient::UpdateCache(std::string provider_authority, 156 void WebRestrictionsClient::UpdateCache(const std::string& provider_authority,
197 GURL url, 157 const std::string& url,
198 ScopedJavaGlobalRef<jobject> result) { 158 ScopedJavaGlobalRef<jobject> result) {
199 DCHECK(single_thread_task_runner_->BelongsToCurrentThread()); 159 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
200 // If the webrestrictions provider changed when the old one was being queried, 160 // If the webrestrictions provider changed when the old one was being queried,
201 // do not update the cache for the new provider. 161 // do not update the cache for the new provider.
202 if (provider_authority != provider_authority_) 162 if (provider_authority != provider_authority_)
203 return; 163 return;
204 RecordURLAccess(url); 164 RecordURLAccess(url);
205 if (recent_urls_.size() >= kMaxCacheSize) { 165 if (recent_urls_.size() >= kMaxCacheSize) {
206 cache_.erase(recent_urls_.back()); 166 cache_.RemoveCacheEntry(recent_urls_.back());
207 recent_urls_.pop_back(); 167 recent_urls_.pop_back();
208 } 168 }
209 cache_[url] = result; 169 cache_.SetCacheEntry(url, WebRestrictionsClientResult(result));
210 } 170 }
211 171
212 void WebRestrictionsClient::RequestSupportKnown(std::string provider_authority, 172 void WebRestrictionsClient::RequestSupportKnown(
213 bool supports_request) { 173 const std::string& provider_authority,
174 bool supports_request) {
214 // |supports_request_| is initialized to false. 175 // |supports_request_| is initialized to false.
215 DCHECK(!supports_request_); 176 DCHECK(!supports_request_);
216 DCHECK(single_thread_task_runner_->BelongsToCurrentThread()); 177 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
217 // If the webrestrictions provider changed when the old one was being queried, 178 // If the webrestrictions provider changed when the old one was being queried,
218 // ignore the result. 179 // ignore the result.
219 if (provider_authority != provider_authority_) 180 if (provider_authority != provider_authority_)
220 return; 181 return;
221 supports_request_ = supports_request; 182 supports_request_ = supports_request;
222 } 183 }
223 184
224 void WebRestrictionsClient::OnShouldProceedComplete( 185 void WebRestrictionsClient::OnShouldProceedComplete(
225 std::string provider_authority, 186 std::string provider_authority,
226 const GURL& url, 187 const std::string& url,
227 const base::Callback<void(bool)>& callback, 188 const base::Callback<void(bool)>& callback,
228 const ScopedJavaGlobalRef<jobject>& result) { 189 const ScopedJavaGlobalRef<jobject>& result) {
229 UpdateCache(provider_authority, url, result); 190 UpdateCache(provider_authority, url, result);
230 JNIEnv* env = base::android::AttachCurrentThread(); 191 callback.Run(cache_.GetCacheEntry(url)->ShouldProceed());
231 callback.Run(Java_ShouldProceedResult_shouldProceed(env, result));
232 } 192 }
233 193
234 void WebRestrictionsClient::ClearCache() { 194 void WebRestrictionsClient::ClearCache() {
235 DCHECK(single_thread_task_runner_->BelongsToCurrentThread()); 195 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
236 cache_.clear(); 196 cache_.Clear();
237 recent_urls_.clear(); 197 recent_urls_.clear();
238 } 198 }
239 199
200 std::unique_ptr<WebRestrictionsClientResult>
201 WebRestrictionsClient::GetCachedWebRestrictionsResult(const std::string& url) {
202 return cache_.GetCacheEntry(url);
203 }
204
240 // static 205 // static
241 ScopedJavaGlobalRef<jobject> WebRestrictionsClient::ShouldProceedTask( 206 ScopedJavaGlobalRef<jobject> WebRestrictionsClient::ShouldProceedTask(
242 const GURL& url, 207 const std::string& url,
243 const base::android::JavaRef<jobject>& java_provider) { 208 const base::android::JavaRef<jobject>& java_provider) {
244 JNIEnv* env = base::android::AttachCurrentThread(); 209 JNIEnv* env = base::android::AttachCurrentThread();
245 base::android::ScopedJavaGlobalRef<jobject> result( 210 base::android::ScopedJavaGlobalRef<jobject> result(
246 Java_WebRestrictionsClient_shouldProceed( 211 Java_WebRestrictionsClient_shouldProceed(
247 env, java_provider, 212 env, java_provider,
248 base::android::ConvertUTF8ToJavaString(env, url.spec()))); 213 base::android::ConvertUTF8ToJavaString(env, url)));
249 return result; 214 return result;
250 } 215 }
251 216
252 void NotifyWebRestrictionsChanged( 217 WebRestrictionsClient::Cache::Cache() = default;
253 JNIEnv* env, 218
254 const base::android::JavaParamRef<jobject>& clazz, 219 WebRestrictionsClient::Cache::~Cache() = default;
255 jlong provider_ptr) { 220
256 WebRestrictionsClient* provider = 221 std::unique_ptr<WebRestrictionsClientResult>
257 reinterpret_cast<WebRestrictionsClient*>(provider_ptr); 222 WebRestrictionsClient::Cache::GetCacheEntry(const std::string& url) {
258 // TODO(knn): Also reload existing interstitials/error pages. 223 base::AutoLock lock(lock_);
259 provider->OnWebRestrictionsChanged(); 224 auto iter = cache_data_.find(url);
225 if (iter == cache_data_.end())
226 return nullptr;
227 // This has to be thread-safe, so copy the data.
228 return std::unique_ptr<WebRestrictionsClientResult>(
229 new WebRestrictionsClientResult(iter->second));
230 }
231
232 void WebRestrictionsClient::Cache::SetCacheEntry(
233 const std::string& url,
234 const WebRestrictionsClientResult& entry) {
235 base::AutoLock lock(lock_);
236 cache_data_.emplace(url, entry);
237 }
238
239 void WebRestrictionsClient::Cache::RemoveCacheEntry(const std::string& url) {
240 base::AutoLock lock(lock_);
241 cache_data_.erase(url);
242 }
243
244 void WebRestrictionsClient::Cache::Clear() {
245 base::AutoLock lock(lock_);
246 cache_data_.clear();
260 } 247 }
261 248
262 } // namespace web_restrictions 249 } // namespace web_restrictions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698