diff options
author | michaelbai@chromium.org <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-13 00:17:08 +0000 |
---|---|---|
committer | michaelbai@chromium.org <michaelbai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-05-13 00:17:08 +0000 |
commit | 061b3036f29ebd6d8694e9b81bc8b5c67525032f (patch) | |
tree | 406be2f5b2212ddbd5a6d15a4336c14bd75f0dfa | |
parent | 51698e0c05b1af97ffded65f027c9d91f9a59da1 (diff) | |
download | chromium_src-061b3036f29ebd6d8694e9b81bc8b5c67525032f.zip chromium_src-061b3036f29ebd6d8694e9b81bc8b5c67525032f.tar.gz chromium_src-061b3036f29ebd6d8694e9b81bc8b5c67525032f.tar.bz2 |
Implement PreauthorizePermission
BUG=
Review URL: https://codereview.chromium.org/274443002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269934 0039d316-1c4b-4281-b951-d872f2087c98
6 files changed, 146 insertions, 0 deletions
diff --git a/android_webview/java/src/org/chromium/android_webview/AwContents.java b/android_webview/java/src/org/chromium/android_webview/AwContents.java index 762b4b6..4f14219 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwContents.java +++ b/android_webview/java/src/org/chromium/android_webview/AwContents.java @@ -15,6 +15,7 @@ import android.graphics.Color; import android.graphics.Paint; import android.graphics.Picture; import android.graphics.Rect; +import android.net.Uri; import android.net.http.SslCertificate; import android.os.AsyncTask; import android.os.Build; @@ -1497,6 +1498,14 @@ public class AwContents { } /** + * @see android.webkit.WebView#preauthorizePermission(Uri, long) + */ + public void preauthorizePermission(Uri origin, long resources) { + if (mNativeAwContents == 0) return; + nativePreauthorizePermission(mNativeAwContents, origin.toString(), resources); + } + + /** * @see ContentViewCore.evaluateJavaScript(String, ContentViewCore.JavaScriptCallback) */ public void evaluateJavaScript(String script, final ValueCallback<String> callback) { @@ -2134,4 +2143,7 @@ public class AwContents { private native void nativeTrimMemory(long nativeAwContents, int level, boolean visible); private native void nativeCreatePdfExporter(long nativeAwContents, AwPdfExporter awPdfExporter); + + private native void nativePreauthorizePermission(long nativeAwContents, String origin, + long resources); } diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index 6762e78..78d6a5a 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc @@ -567,6 +567,15 @@ void AwContents::OnPermissionRequestCanceled(AwPermissionRequest* request) { env, j_ref.obj(), j_request.obj()); } +void AwContents::PreauthorizePermission( + JNIEnv* env, + jobject obj, + jstring origin, + jlong resources) { + permission_request_handler_->PreauthorizePermission( + GURL(base::android::ConvertJavaStringToUTF8(env, origin)), resources); +} + void AwContents::FindAllAsync(JNIEnv* env, jobject obj, jstring search_string) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); GetFindHelper()->FindAllAsync(ConvertJavaStringToUTF16(env, search_string)); diff --git a/android_webview/native/aw_contents.h b/android_webview/native/aw_contents.h index e7950ac..3479b45 100644 --- a/android_webview/native/aw_contents.h +++ b/android_webview/native/aw_contents.h @@ -149,6 +149,11 @@ class AwContents : public FindHelper::Listener, return permission_request_handler_.get(); } + void PreauthorizePermission(JNIEnv* env, + jobject obj, + jstring origin, + jlong resources); + // Find-in-page API and related methods. void FindAllAsync(JNIEnv* env, jobject obj, jstring search_string); void FindNext(JNIEnv* env, jobject obj, jboolean forward); diff --git a/android_webview/native/permission/permission_request_handler.cc b/android_webview/native/permission/permission_request_handler.cc index 08b7431..20cc748 100644 --- a/android_webview/native/permission/permission_request_handler.cc +++ b/android_webview/native/permission/permission_request_handler.cc @@ -26,6 +26,11 @@ PermissionRequestHandler::~PermissionRequestHandler() { void PermissionRequestHandler::SendRequest( scoped_ptr<AwPermissionRequestDelegate> request) { + if (Preauthorized(request->GetOrigin(), request->GetResources())) { + request->NotifyRequestResult(true); + return; + } + AwPermissionRequest* aw_request = new AwPermissionRequest(request.Pass()); requests_.push_back( base::WeakPtr<AwPermissionRequest>(aw_request->GetWeakPtr())); @@ -45,6 +50,20 @@ void PermissionRequestHandler::CancelRequest(const GURL& origin, } } +void PermissionRequestHandler::PreauthorizePermission(const GURL& origin, + int64 resources) { + if (!resources) + return; + + std::string key = origin.GetOrigin().spec(); + if (key.empty()) { + LOG(ERROR) << "The origin of preauthorization is empty, ignore it."; + return; + } + + preauthorized_permission_[key] |= resources; +} + PermissionRequestHandler::RequestIterator PermissionRequestHandler::FindRequest(const GURL& origin, int64 resources) { @@ -77,4 +96,13 @@ void PermissionRequestHandler::PruneRequests() { } } +bool PermissionRequestHandler::Preauthorized(const GURL& origin, + int64 resources) { + std::map<std::string, int64>::iterator i = + preauthorized_permission_.find(origin.GetOrigin().spec()); + + return i != preauthorized_permission_.end() && + (resources & i->second) == resources; +} + } // namespace android_webivew diff --git a/android_webview/native/permission/permission_request_handler.h b/android_webview/native/permission/permission_request_handler.h index d4d91b6..3acb497 100644 --- a/android_webview/native/permission/permission_request_handler.h +++ b/android_webview/native/permission/permission_request_handler.h @@ -5,6 +5,7 @@ #ifndef ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_H #define ANDROID_WEBVIEW_NATIVE_PERMISSION_PERMISSION_REQUEST_HANDLER_H +#include <map> #include <vector> #include "base/memory/scoped_ptr.h" @@ -32,6 +33,9 @@ class PermissionRequestHandler { // Cancel the ongoing request initiated by |origin| for accessing |resources|. void CancelRequest(const GURL& origin, int64 resources); + // Allow |origin| to access the |resources|. + void PreauthorizePermission(const GURL& origin, int64 resources); + private: friend class TestPermissionRequestHandler; @@ -47,11 +51,16 @@ class PermissionRequestHandler { // Remove the invalid requests from requests_. void PruneRequests(); + // Return true if |origin| were preauthorized to access |resources|. + bool Preauthorized(const GURL& origin, int64 resources); + PermissionRequestHandlerClient* client_; // A list of ongoing requests. std::vector<base::WeakPtr<AwPermissionRequest> > requests_; + std::map<std::string, int64> preauthorized_permission_; + DISALLOW_COPY_AND_ASSIGN(PermissionRequestHandler); }; diff --git a/android_webview/native/permission/permission_request_handler_unittest.cc b/android_webview/native/permission/permission_request_handler_unittest.cc index 2948dd9..981170c 100644 --- a/android_webview/native/permission/permission_request_handler_unittest.cc +++ b/android_webview/native/permission/permission_request_handler_unittest.cc @@ -54,6 +54,9 @@ class TestPermissionRequestHandlerClient : int64 resources; }; + TestPermissionRequestHandlerClient() + : request_(NULL) {} + virtual void OnPermissionRequest(AwPermissionRequest* request) OVERRIDE { request_ = request; requested_permission_ = @@ -88,6 +91,12 @@ class TestPermissionRequestHandlerClient : request_ = NULL; } + void Reset() { + request_ = NULL; + requested_permission_ = Permission(); + canceled_permission_ = Permission(); + } + private: AwPermissionRequest* request_; Permission requested_permission_; @@ -266,4 +275,78 @@ TEST_F(PermissionRequestHandlerTest, TestMultiplePermissionRequest) { EXPECT_EQ(resources1, handler()->requests()[0]->GetResources()); } +TEST_F(PermissionRequestHandlerTest, TestPreauthorizePermission) { + handler()->PreauthorizePermission(origin(), resources()); + + // Permission should granted without asking PermissionRequestHandlerClient. + handler()->SendRequest(delegate().Pass()); + EXPECT_TRUE(allowed()); + EXPECT_EQ(NULL, client()->request()); + + // Only ask one preauthorized resource, permission should granted + // without asking PermissionRequestHandlerClient. + scoped_ptr<AwPermissionRequestDelegate> delegate; + delegate.reset(new TestAwPermissionRequestDelegate( + origin(), AwPermissionRequest::AudioCapture, + base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult, + base::Unretained(this)))); + client()->Reset(); + handler()->SendRequest(delegate.Pass()); + EXPECT_TRUE(allowed()); + EXPECT_EQ(NULL, client()->request()); +} + +TEST_F(PermissionRequestHandlerTest, TestOriginNotPreauthorized) { + handler()->PreauthorizePermission(origin(), resources()); + + // Ask the origin which wasn't preauthorized. + GURL origin ("http://a.google.com/a/b"); + scoped_ptr<AwPermissionRequestDelegate> delegate; + int64 requested_resources = AwPermissionRequest::AudioCapture; + delegate.reset(new TestAwPermissionRequestDelegate( + origin, requested_resources, + base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult, + base::Unretained(this)))); + handler()->SendRequest(delegate.Pass()); + EXPECT_EQ(origin, handler()->requests()[0]->GetOrigin()); + EXPECT_EQ(requested_resources, handler()->requests()[0]->GetResources()); + client()->Grant(); + EXPECT_TRUE(allowed()); +} + +TEST_F(PermissionRequestHandlerTest, TestResourcesNotPreauthorized) { + handler()->PreauthorizePermission(origin(), resources()); + + // Ask the resources which weren't preauthorized. + scoped_ptr<AwPermissionRequestDelegate> delegate; + int64 requested_resources = AwPermissionRequest::AudioCapture + | AwPermissionRequest::Geolocation; + delegate.reset(new TestAwPermissionRequestDelegate( + origin(), requested_resources, + base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult, + base::Unretained(this)))); + + handler()->SendRequest(delegate.Pass()); + EXPECT_EQ(origin(), handler()->requests()[0]->GetOrigin()); + EXPECT_EQ(requested_resources, handler()->requests()[0]->GetResources()); + client()->Deny(); + EXPECT_FALSE(allowed()); +} + +TEST_F(PermissionRequestHandlerTest, TestPreauthorizeMultiplePermission) { + handler()->PreauthorizePermission(origin(), resources()); + // Preauthorize another permission. + GURL origin ("http://a.google.com/a/b"); + handler()->PreauthorizePermission(origin, AwPermissionRequest::Geolocation); + GURL origin_hostname ("http://a.google.com/"); + scoped_ptr<AwPermissionRequestDelegate> delegate; + delegate.reset(new TestAwPermissionRequestDelegate( + origin_hostname, AwPermissionRequest::Geolocation, + base::Bind(&PermissionRequestHandlerTest::NotifyRequestResult, + base::Unretained(this)))); + handler()->SendRequest(delegate.Pass()); + EXPECT_TRUE(allowed()); + EXPECT_EQ(NULL, client()->request()); +} + } // android_webview |