| Index: chrome/android/java/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProvider.java
|
| diff --git a/chrome/android/java/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProvider.java b/chrome/android/java/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProvider.java
|
| index 5d46b9af41313935c1badb72270086742d22208b..762c67a6aede4d825335fa5c9721cdcdeb2de7b8 100644
|
| --- a/chrome/android/java/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProvider.java
|
| +++ b/chrome/android/java/src/org/chromium/chrome/browser/superviseduser/SupervisedUserContentProvider.java
|
| @@ -11,31 +11,37 @@ import android.content.Intent;
|
| import android.content.IntentFilter;
|
| import android.os.Build;
|
| import android.os.Bundle;
|
| +import android.os.SystemClock;
|
| import android.os.UserManager;
|
|
|
| import org.chromium.base.ThreadUtils;
|
| import org.chromium.base.VisibleForTesting;
|
| import org.chromium.base.annotations.CalledByNative;
|
| +import org.chromium.base.library_loader.LibraryLoader;
|
| import org.chromium.base.library_loader.ProcessInitException;
|
| +import org.chromium.base.metrics.RecordHistogram;
|
| import org.chromium.chrome.browser.init.ChromeBrowserInitializer;
|
| -import org.chromium.components.webrestrictions.WebRestrictionsContentProvider;
|
| +import org.chromium.components.webrestrictions.browser.WebRestrictionsContentProvider;
|
|
|
| -import java.util.concurrent.CountDownLatch;
|
| +import java.util.concurrent.ArrayBlockingQueue;
|
| +import java.util.concurrent.BlockingQueue;
|
| +import java.util.concurrent.TimeUnit;
|
|
|
| /**
|
| - * Content provider for telling other apps (e.g. WebView apps) about the
|
| - * supervised user URL filter.
|
| + * Content provider for telling other apps (e.g. WebView apps) about the supervised user URL filter.
|
| */
|
| public class SupervisedUserContentProvider extends WebRestrictionsContentProvider {
|
| private static final String SUPERVISED_USER_CONTENT_PROVIDER_ENABLED =
|
| "SupervisedUserContentProviderEnabled";
|
| private long mNativeSupervisedUserContentProvider = 0;
|
| + private boolean mChromeAlreadyStarted;
|
| private static Object sEnabledLock = new Object();
|
|
|
| // Three value "boolean" caching enabled state, null if not yet known.
|
| private static Boolean sEnabled = null;
|
|
|
| private long getSupervisedUserContentProvider() throws ProcessInitException {
|
| + mChromeAlreadyStarted = LibraryLoader.isInitialized();
|
| if (mNativeSupervisedUserContentProvider != 0) {
|
| return mNativeSupervisedUserContentProvider;
|
| }
|
| @@ -50,25 +56,32 @@ public class SupervisedUserContentProvider extends WebRestrictionsContentProvide
|
| mNativeSupervisedUserContentProvider = nativeProvider;
|
| }
|
|
|
| - static class SupervisedUserQueryReply {
|
| - final CountDownLatch mLatch = new CountDownLatch(1);
|
| - private WebRestrictionsResult mResult;
|
| + static class SupervisedUserReply<T> {
|
| + private static final long RESULT_TIMEOUT_SECONDS = 10;
|
| + final BlockingQueue<T> mQueue = new ArrayBlockingQueue<>(1);
|
|
|
| + void onQueryFinished(T reply) {
|
| + // This must be called precisely once per query.
|
| + mQueue.add(reply);
|
| + }
|
| +
|
| + T getResult() throws InterruptedException {
|
| + return mQueue.poll(RESULT_TIMEOUT_SECONDS, TimeUnit.SECONDS);
|
| + }
|
| + }
|
| +
|
| + static class SupervisedUserQueryReply extends SupervisedUserReply<WebRestrictionsResult> {
|
| // One of the following three functions must be called precisely once per query.
|
|
|
| @CalledByNative("SupervisedUserQueryReply")
|
| void onQueryComplete() {
|
| - assert mResult == null;
|
| -
|
| - mResult = new WebRestrictionsResult(true, null, null);
|
| - mLatch.countDown();
|
| + onQueryFinished(new WebRestrictionsResult(true, null, null));
|
| }
|
|
|
| @CalledByNative("SupervisedUserQueryReply")
|
| void onQueryFailed(int reason, int allowAccessRequests, int isChildAccount,
|
| String profileImageUrl, String profileImageUrl2, String custodian,
|
| String custodianEmail, String secondCustodian, String secondCustodianEmail) {
|
| - assert mResult == null;
|
| int errorInt[] = new int[] {reason, allowAccessRequests, isChildAccount};
|
| String errorString[] = new String[] {
|
| profileImageUrl,
|
| @@ -78,20 +91,11 @@ public class SupervisedUserContentProvider extends WebRestrictionsContentProvide
|
| secondCustodian,
|
| secondCustodianEmail
|
| };
|
| - mResult = new WebRestrictionsResult(false, errorInt, errorString);
|
| - mLatch.countDown();
|
| + onQueryFinished(new WebRestrictionsResult(false, errorInt, errorString));
|
| }
|
|
|
| void onQueryFailedNoErrorData() {
|
| - assert mResult == null;
|
| -
|
| - mResult = new WebRestrictionsResult(false, null, null);
|
| - mLatch.countDown();
|
| - }
|
| -
|
| - WebRestrictionsResult getResult() throws InterruptedException {
|
| - mLatch.await();
|
| - return mResult;
|
| + onQueryFinished(new WebRestrictionsResult(false, null, null));
|
| }
|
| }
|
|
|
| @@ -103,6 +107,7 @@ public class SupervisedUserContentProvider extends WebRestrictionsContentProvide
|
| // As such it needs to correctly match the replies to the calls. It does this by creating a
|
| // reply object for each query, and passing this through the callback structure. The reply
|
| // object also handles waiting for the reply.
|
| + long startTimeMs = SystemClock.elapsedRealtime();
|
| final SupervisedUserQueryReply queryReply = new SupervisedUserQueryReply();
|
| ThreadUtils.runOnUiThread(new Runnable() {
|
| @Override
|
| @@ -117,7 +122,16 @@ public class SupervisedUserContentProvider extends WebRestrictionsContentProvide
|
| try {
|
| // This will block until an onQueryComplete call on a different thread adds
|
| // something to the queue.
|
| - return queryReply.getResult();
|
| + WebRestrictionsResult result = queryReply.getResult();
|
| + String histogramName = mChromeAlreadyStarted
|
| + ? "SupervisedUserContentProvider.ChromeStartedRequestTime"
|
| + : "SupervisedUserContentProvider.ChromeNotStartedRequestTime";
|
| + RecordHistogram.recordTimesHistogram(histogramName,
|
| + SystemClock.elapsedRealtime() - startTimeMs, TimeUnit.MILLISECONDS);
|
| + RecordHistogram.recordBooleanHistogram(
|
| + "SupervisedUserContentProvider.RequestTimedOut", result == null);
|
| + if (result == null) return new WebRestrictionsResult(false, null, null);
|
| + return result;
|
| } catch (InterruptedException e) {
|
| return new WebRestrictionsResult(false, null, null);
|
| }
|
| @@ -129,21 +143,10 @@ public class SupervisedUserContentProvider extends WebRestrictionsContentProvide
|
| return true;
|
| }
|
|
|
| - static class SupervisedUserInsertReply {
|
| - final CountDownLatch mLatch = new CountDownLatch(1);
|
| - boolean mResult;
|
| -
|
| + static class SupervisedUserInsertReply extends SupervisedUserReply<Boolean> {
|
| @CalledByNative("SupervisedUserInsertReply")
|
| void onInsertRequestSendComplete(boolean result) {
|
| - // This must be called precisely once per query.
|
| - assert mLatch.getCount() == 1;
|
| - mResult = result;
|
| - mLatch.countDown();
|
| - }
|
| -
|
| - boolean getResult() throws InterruptedException {
|
| - mLatch.await();
|
| - return mResult;
|
| + onQueryFinished(result);
|
| }
|
| }
|
|
|
| @@ -167,7 +170,9 @@ public class SupervisedUserContentProvider extends WebRestrictionsContentProvide
|
| }
|
| });
|
| try {
|
| - return insertReply.getResult();
|
| + Boolean result = insertReply.getResult();
|
| + if (result == null) return false;
|
| + return result;
|
| } catch (InterruptedException e) {
|
| return false;
|
| }
|
|
|