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

Unified 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, 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 side-by-side diff with in-line comments
Download patch
Index: components/web_restrictions/content_resolver_web_restrictions_provider.cc
diff --git a/components/web_restrictions/content_resolver_web_restrictions_provider.cc b/components/web_restrictions/content_resolver_web_restrictions_provider.cc
new file mode 100644
index 0000000000000000000000000000000000000000..b4e750e7dac120f7528fc3f9a1a96e8417df5e54
--- /dev/null
+++ b/components/web_restrictions/content_resolver_web_restrictions_provider.cc
@@ -0,0 +1,247 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "components/web_restrictions/content_resolver_web_restrictions_provider.h"
+
+#include "base/android/jni_string.h"
+#include "base/android/scoped_java_ref.h"
+#include "base/bind.h"
+#include "base/location.h"
+#include "base/thread_task_runner_handle.h"
+#include "content/public/browser/browser_thread.h"
+#include "jni/ContentResolverWebRestrictionsProvider_jni.h"
+
+namespace web_restrictions {
+
+namespace {
+
+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
+
+const size_t kMaxCacheSize = 100;
+
+void RecordAccess(std::list<GURL>* recent_urls, const GURL& url) {
+ // 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.
+ recent_urls->remove(url);
+ recent_urls->push_front(url);
+}
+
+void InsertValue(std::map<GURL, std::string>* error_page_cache,
+ std::map<GURL, bool>* url_access_cache,
+ std::list<GURL>* recent_urls,
+ const GURL& url,
+ bool should_proceed,
+ 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!
+ RecordAccess(recent_urls, url);
+ if (recent_urls->size() >= kMaxCacheSize) {
+ url_access_cache->erase(recent_urls->back());
+ error_page_cache->erase(recent_urls->back());
+ recent_urls->pop_back();
+ }
+ (*url_access_cache)[url] = should_proceed;
+ if (!j_error_page.is_null()) {
+ (*error_page_cache)[url] =
+ base::android::ConvertJavaStringToUTF8(j_error_page);
+ } else {
+ error_page_cache->erase(url);
+ }
+}
+
+} // namespace cache_helper
+
+namespace async_helper {
+
+void ShouldProceed(const GURL& url,
+ jlong callback,
+ const base::android::JavaRef<jobject>& java_provider) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_ContentResolverWebRestrictionsProvider_shouldProceed(
+ env, java_provider.obj(), callback,
+ base::android::ConvertUTF8ToJavaString(env, url.spec()).obj());
+}
+
+void RequestPermission(const GURL& url,
+ jlong callback,
+ const base::android::JavaRef<jobject>& java_provider) {
+ JNIEnv* env = base::android::AttachCurrentThread();
+ Java_ContentResolverWebRestrictionsProvider_requestPermission(
+ env, java_provider.obj(), callback,
+ base::android::ConvertUTF8ToJavaString(env, url.spec()).obj());
+}
+
+} // namespace async_helper
+
+} // namespace
+
+// A wrapper to the callback class to facilitate getting a callback from java
+// into C++. Objects of this class delete itself only when they are called back
+// so we must ensure that happens even for error cases.
+class SelfDeletingCallback {
+ public:
+ SelfDeletingCallback(const GURL& url,
+ const base::Callback<void(bool)>& callback,
+ const scoped_refptr<base::TaskRunner>& callback_runner,
+ ContentResolverWebRestrictionsProvider* provider);
+ void RequestSuccess(bool request_success);
+ void ShouldProceed(bool should_proceed,
+ const base::android::JavaParamRef<jstring>& error_page);
+
+ private:
+ // Only the callback can delete itself. We must ensure it is indeed
+ // called back.
+ ~SelfDeletingCallback() {}
+
+ GURL url_;
+ base::Callback<void(bool)> callback_;
+ scoped_refptr<base::TaskRunner> callback_runner_;
+ ContentResolverWebRestrictionsProvider* provider_;
+
+ DISALLOW_COPY_AND_ASSIGN(SelfDeletingCallback);
+};
+
+SelfDeletingCallback::SelfDeletingCallback(
+ const GURL& url,
+ const base::Callback<void(bool)>& callback,
+ const scoped_refptr<base::TaskRunner>& callback_runner,
+ ContentResolverWebRestrictionsProvider* provider)
+ : url_(url),
+ callback_(callback),
+ callback_runner_(callback_runner),
+ provider_(provider) {}
+
+void SelfDeletingCallback::ShouldProceed(
+ bool should_proceed,
+ const base::android::JavaParamRef<jstring>& error_page) {
+ 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.
+ &provider_->error_page_cache_, &provider_->url_access_cache_,
+ &provider_->recent_urls_, url_, should_proceed, error_page);
+ callback_runner_->PostTask(FROM_HERE, base::Bind(callback_, should_proceed));
+ delete this;
+}
+
+void SelfDeletingCallback::RequestSuccess(bool request_success) {
+ callback_runner_->PostTask(FROM_HERE, base::Bind(callback_, request_success));
+ delete this;
+}
+
+// static
+bool ContentResolverWebRestrictionsProvider::Register(JNIEnv* env) {
+ return RegisterNativesImpl(env);
+}
+
+ContentResolverWebRestrictionsProvider::ContentResolverWebRestrictionsProvider()
+ : initialized_(false), supports_request_(false) {}
+
+ContentResolverWebRestrictionsProvider::
+ ~ContentResolverWebRestrictionsProvider() {}
+
+void ContentResolverWebRestrictionsProvider::Initialize(
+ const std::string& content_provider_authority) {
+ ClearCache();
+ initialized_ = !content_provider_authority.empty();
+ if (!initialized_)
+ return;
+ JNIEnv* env = base::android::AttachCurrentThread();
+ java_provider_.Reset(Java_ContentResolverWebRestrictionsProvider_create(
+ env,
+ base::android::ConvertUTF8ToJavaString(env, content_provider_authority)
+ .obj(),
+ reinterpret_cast<jlong>(this)));
+ supports_request_ =
+ Java_ContentResolverWebRestrictionsProvider_supportsRequest(
+ env, java_provider_.obj());
+}
+
+UrlAccess ContentResolverWebRestrictionsProvider::ShouldProceed(
+ bool is_main_frame,
+ const GURL& url,
+ const base::Callback<void(bool)>& callback) {
+ if (!initialized_)
+ return ALLOW;
+ auto iter = url_access_cache_.find(url);
+ if (iter != url_access_cache_.end()) {
+ cache_helper::RecordAccess(&recent_urls_, url);
+ return iter->second ? ALLOW : DISALLOW;
+ }
+ scoped_refptr<base::SingleThreadTaskRunner> callback_runner =
+ base::ThreadTaskRunnerHandle::Get();
+ SelfDeletingCallback* wrapped_callback =
+ 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
+ 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.
+ FROM_HERE,
+ base::Bind(&async_helper::ShouldProceed, url,
+ reinterpret_cast<jlong>(wrapped_callback), java_provider_),
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+ return PENDING;
+}
+
+bool ContentResolverWebRestrictionsProvider::SupportsRequest() const {
+ return initialized_ && supports_request_;
+}
+
+bool ContentResolverWebRestrictionsProvider::GetErrorHtml(
+ const GURL& url,
+ std::string* error_page) const {
+ if (!initialized_)
+ return false;
+ auto iter = error_page_cache_.find(url);
+ if (iter == error_page_cache_.end())
+ return false;
+ *error_page = iter->second;
+ return true;
+}
+
+void ContentResolverWebRestrictionsProvider::RequestPermission(
+ const GURL& url,
+ const base::Callback<void(bool)>& request_success) {
+ if (!initialized_) {
+ request_success.Run(false);
+ return;
+ }
+ scoped_refptr<base::SingleThreadTaskRunner> callback_runner =
+ base::ThreadTaskRunnerHandle::Get();
+ SelfDeletingCallback* wrapped_callback =
+ new SelfDeletingCallback(url, request_success, callback_runner, this);
+ content::BrowserThread::GetBlockingPool()->PostWorkerTaskWithShutdownBehavior(
+ FROM_HERE,
+ base::Bind(&async_helper::RequestPermission, url,
+ reinterpret_cast<jlong>(wrapped_callback), java_provider_),
+ base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
+}
+
+void ContentResolverWebRestrictionsProvider::ClearCache() {
+ error_page_cache_.clear();
+ url_access_cache_.clear();
+ recent_urls_.clear();
+}
+
+void ShouldProceed(JNIEnv* env,
+ const base::android::JavaParamRef<jclass>& clazz,
+ jlong callback_ptr,
+ jboolean should_proceed,
+ const base::android::JavaParamRef<jstring>& error_page) {
+ SelfDeletingCallback* callback =
+ reinterpret_cast<SelfDeletingCallback*>(callback_ptr);
+ callback->ShouldProceed(should_proceed, error_page);
+}
+
+void RequestSuccess(JNIEnv* env,
+ const base::android::JavaParamRef<jclass>& clazz,
+ jlong callback_ptr,
+ jboolean request_success) {
+ SelfDeletingCallback* callback =
+ reinterpret_cast<SelfDeletingCallback*>(callback_ptr);
+ callback->RequestSuccess(request_success);
+}
+
+void NotifyWebRestrictionsChanged(
+ JNIEnv* env,
+ const base::android::JavaParamRef<jclass>& clazz,
+ jlong provider_ptr) {
+ ContentResolverWebRestrictionsProvider* provider =
+ reinterpret_cast<ContentResolverWebRestrictionsProvider*>(provider_ptr);
+ // TODO(knn): Also reload existing interstitials/error pages.
+ provider->ClearCache();
+}
+
+} // namespace web_restrictions

Powered by Google App Engine
This is Rietveld 408576698