Chromium Code Reviews| Index: components/web_restrictions/java/src/org/chromium/components/webrestrictions/ContentResolverWebRestrictionsProvider.java |
| diff --git a/components/web_restrictions/java/src/org/chromium/components/webrestrictions/ContentResolverWebRestrictionsProvider.java b/components/web_restrictions/java/src/org/chromium/components/webrestrictions/ContentResolverWebRestrictionsProvider.java |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..8aa854bac7b5c48f2cb1318f425eec705e9a7d9b |
| --- /dev/null |
| +++ b/components/web_restrictions/java/src/org/chromium/components/webrestrictions/ContentResolverWebRestrictionsProvider.java |
| @@ -0,0 +1,129 @@ |
| +// 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. |
| + |
| +package org.chromium.components.webrestrictions; |
| + |
| +import android.content.ContentResolver; |
| +import android.content.ContentValues; |
| +import android.database.ContentObserver; |
| +import android.database.Cursor; |
| +import android.net.Uri; |
| +import android.text.TextUtils; |
| + |
| +import org.chromium.base.ContextUtils; |
| +import org.chromium.base.annotations.CalledByNative; |
| +import org.chromium.base.annotations.JNINamespace; |
| + |
| +/** |
| + * This class acts as an interface that talks to the content provider which actually implements the |
| + * web restriction provider. |
| + */ |
| +@JNINamespace("web_restrictions") |
| +public class ContentResolverWebRestrictionsProvider { |
| + private final Uri mQueryUri; |
| + private final Uri mRequestUri; |
| + private final ContentObserver mContentObserver; |
| + private ContentResolver mContentResolver; |
| + |
| + /** |
| + * Start the web restriction provider and setup the content resolver. |
| + */ |
| + private ContentResolverWebRestrictionsProvider(String authority, final long nativeProvider) { |
| + assert !TextUtils.isEmpty(authority); |
| + Uri baseUri = new Uri.Builder().scheme("content").authority(authority).build(); |
| + mQueryUri = Uri.withAppendedPath(baseUri, "authorized"); |
| + mRequestUri = Uri.withAppendedPath(baseUri, "requested"); |
| + mContentResolver = ContextUtils.getApplicationContext().getContentResolver(); |
| + mContentObserver = new ContentObserver(null) { |
| + @Override |
| + public void onChange(boolean selfChange) { |
| + onChange(selfChange, null); |
| + } |
| + |
| + @Override |
| + public void onChange(boolean selfChange, Uri uri) { |
| + nativeNotifyWebRestrictionsChanged(nativeProvider); |
| + } |
| + }; |
| + mContentResolver.registerContentObserver(baseUri, true, mContentObserver); |
| + } |
| + |
| + /** |
| + * Simple helper method to expose the constructor over JNI. |
| + */ |
| + @CalledByNative |
| + private static ContentResolverWebRestrictionsProvider create( |
| + String authority, long nativeProvider) { |
| + return new ContentResolverWebRestrictionsProvider(authority, nativeProvider); |
| + } |
| + |
| + /** |
| + * @return whether the web restriction provider supports requesting access for a blocked url. |
| + */ |
| + @CalledByNative |
| + private boolean supportsRequest() { |
| + synchronized (this) { |
|
aberent
2016/02/04 10:53:58
Nit - I don't think Findbugs will like synchronize
knn
2016/02/04 13:09:27
Removed.
|
| + return mContentResolver != null && mContentResolver.getType(mRequestUri) != null; |
| + } |
| + } |
| + |
| + /** |
| + * Called when the ContentResolverWebRestrictionsProvider is about to be destroyed. |
| + */ |
| + @CalledByNative |
| + private void onDestroy() { |
| + synchronized (this) { |
| + mContentResolver.unregisterContentObserver(mContentObserver); |
| + // Ensure we don't use it any more. |
| + mContentResolver = null; |
| + } |
| + } |
| + |
| + /** |
| + * Whether we can proceed with loading the {@code url}. |
| + * In case the url is not to be loaded, the web restriction provider can return an optional |
| + * error page to show instead. |
| + */ |
| + @CalledByNative |
| + private void shouldProceed(final long nativeCallback, final String url) { |
| + synchronized (this) { |
|
Bernhard Bauer
2016/02/04 11:13:53
Hm... wouldn't this potentially hold the lock for
knn
2016/02/04 13:09:27
We don't even need a synchronized, do we? Finally
Bernhard Bauer
2016/02/04 14:27:21
Hm, if you only ever read the content resolver, it
knn
2016/02/04 15:31:33
I guess volatile was what I was looking for, given
Bernhard Bauer
2016/02/04 22:37:18
Urr, yes.
|
| + if (mContentResolver == null) { |
| + nativeShouldProceed(nativeCallback, false, null); |
| + return; |
| + } |
| + String select = String.format("url = '%s'", url); |
| + Cursor result = mContentResolver.query(mQueryUri, null, select, null, null); |
| + boolean shouldProceed = result == null || result.getInt(0) > 0; |
| + String errorPage = shouldProceed ? null : result.getString(1); |
| + nativeShouldProceed(nativeCallback, shouldProceed, errorPage); |
| + } |
| + } |
| + |
| + /** |
| + * Request permission to load the {@code url}. |
| + * The web restriction provider returns a {@code boolean} variable indicating whether it was |
| + * able to forward the request to the appropriate authority who can approve it. |
| + */ |
| + @CalledByNative |
| + private void requestPermission(final long nativeCallback, final String url) { |
| + synchronized (this) { |
| + if (mContentResolver == null) { |
| + nativeRequestSuccess(nativeCallback, false); |
| + return; |
| + } |
| + ContentValues values = new ContentValues(1); |
| + values.put("url", url); |
| + boolean requestSuccess = mContentResolver.insert(mRequestUri, values) != null; |
| + nativeRequestSuccess(nativeCallback, requestSuccess); |
| + } |
| + } |
| + |
| + private static native void nativeShouldProceed( |
| + long ptrSelfDeletingCallback, boolean shouldProceed, String errorPage); |
| + |
| + private static native void nativeRequestSuccess( |
| + long ptrSelfDeletingCallback, boolean requestSuccess); |
| + |
| + private static native void nativeNotifyWebRestrictionsChanged(long ptrProvider); |
| +} |