Revert "[wv] remove mLock"
This reverts commit 96e4719a48
.
Reason for revert: Can cause deadlock: crbug.com/395877483
Original change's description:
> [wv] remove mLock
>
> This is replaced with AtomicReferences and a CountdownLatch.
>
> Follow-up cl to rename from `startChromiumLocked` to just
> `startChromium`
>
> Bug: 389871700
> Change-Id: I0e4214cc9c6335e34d81109d25aebb9f56f19b6f
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6081452
> Reviewed-by: Richard (Torne) Coles <torne@chromium.org>
> Commit-Queue: Chidera Olibie <colibie@google.com>
> Cr-Commit-Position: refs/heads/main@{#1410411}
Bug: 389871700
Change-Id: I35d5e99fe61825e8b5cbbbf122982f5486d57a24
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6253939
Reviewed-by: Richard (Torne) Coles <torne@chromium.org>
Commit-Queue: Chidera Olibie <colibie@google.com>
Cr-Commit-Position: refs/heads/main@{#1418824}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
eb03220c5f
commit
b4416887f1
android_webview
glue
java
src
com
android
support_library
java
src
org
chromium
support_lib_glue
@ -72,7 +72,6 @@ import org.chromium.net.NetworkChangeNotifier;
|
||||
import org.chromium.ui.base.DeviceFormFactor;
|
||||
import org.chromium.ui.base.ResourceBundle;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
/**
|
||||
@ -162,23 +161,19 @@ public class WebViewChromiumAwInit {
|
||||
void onSuccess(WebViewStartUpDiagnostics result);
|
||||
}
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
@GuardedBy("mLock")
|
||||
private CookieManagerAdapter mDefaultCookieManager;
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
@GuardedBy("mLock")
|
||||
private WebIconDatabaseAdapter mWebIconDatabase;
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
@GuardedBy("mLock")
|
||||
private WebViewDatabaseAdapter mDefaultWebViewDatabase;
|
||||
|
||||
// Volatile to guard for incorrectly trying to use this without calling `startChromiumLocked`.
|
||||
// TODO(crbug.com/389871700): Consider hiding the variable where it can't be incorrectly
|
||||
// accessed. See crrev.com/c/6081452/comment/9dff4e5e_c049d778/ for context.
|
||||
private volatile ChromiumStartedGlobals mChromiumStartedGlobals;
|
||||
@GuardedBy("mLock")
|
||||
private ChromiumStartedGlobals mChromiumStartedGlobals;
|
||||
|
||||
private final Object mSeedLoaderLock = new Object();
|
||||
|
||||
@GuardedBy("mSeedLoaderLock")
|
||||
@GuardedBy("mLock")
|
||||
private VariationsSeedLoader mSeedLoader;
|
||||
|
||||
// This is only accessed during WebViewChromiumFactoryProvider.initialize() which is guarded by
|
||||
@ -186,16 +181,17 @@ public class WebViewChromiumAwInit {
|
||||
// which cannot be called before initialize() has completed.
|
||||
private Thread mSetUpResourcesThread;
|
||||
|
||||
// Guards access to fields that are initialized on first use rather than by startChromiumLocked.
|
||||
private final Object mLazyInitLock = new Object();
|
||||
// Guards accees to the other members, and is notifyAll() signalled on the UI thread
|
||||
// when the chromium process has been started.
|
||||
// This member is not private only because the downstream subclass needs to access it,
|
||||
// it shouldn't be accessed from anywhere else.
|
||||
/* package */ final Object mLock = new Object();
|
||||
|
||||
private final Object mThreadSettingLock = new Object();
|
||||
final Object mThreadSettingLock = new Object();
|
||||
|
||||
@GuardedBy("mThreadSettingLock")
|
||||
private boolean mThreadIsSet;
|
||||
|
||||
private final CountDownLatch mStartupFinished = new CountDownLatch(1);
|
||||
|
||||
// mInitState should only transition INIT_NOT_STARTED -> INIT_FINISHED
|
||||
private static final int INIT_NOT_STARTED = 0;
|
||||
private static final int INIT_FINISHED = 1;
|
||||
@ -248,13 +244,21 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
|
||||
public AwTracingController getAwTracingController() {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_AW_TRACING_CONTROLLER);
|
||||
return mChromiumStartedGlobals.mAwTracingController;
|
||||
synchronized (mLock) {
|
||||
if (mChromiumStartedGlobals == null) {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_AW_TRACING_CONTROLLER);
|
||||
}
|
||||
return mChromiumStartedGlobals.mAwTracingController;
|
||||
}
|
||||
}
|
||||
|
||||
public AwProxyController getAwProxyController() {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_AW_PROXY_CONTROLLER);
|
||||
return mChromiumStartedGlobals.mAwProxyController;
|
||||
synchronized (mLock) {
|
||||
if (mChromiumStartedGlobals == null) {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_AW_PROXY_CONTROLLER);
|
||||
}
|
||||
return mChromiumStartedGlobals.mAwProxyController;
|
||||
}
|
||||
}
|
||||
|
||||
public void setProviderInitOnMainLooperLocation(Throwable t) {
|
||||
@ -267,21 +271,21 @@ public class WebViewChromiumAwInit {
|
||||
// lives in the ui/ layer. See ui/base/ui_base_paths.h
|
||||
private static final int DIR_RESOURCE_PAKS_ANDROID = 3003;
|
||||
|
||||
// TODO(crbug.com/389871700): Rename to startChromium because it doesn't need the lock.
|
||||
@GuardedBy("mLock")
|
||||
private void startChromiumLocked(@CallSite int callSite, boolean triggeredFromUIThread) {
|
||||
long startTime = SystemClock.uptimeMillis();
|
||||
try (ScopedSysTraceEvent event =
|
||||
ScopedSysTraceEvent.scoped("WebViewChromiumAwInit.startChromiumLocked")) {
|
||||
assert ThreadUtils.runningOnUiThread();
|
||||
assert Thread.holdsLock(mLock) && ThreadUtils.runningOnUiThread();
|
||||
|
||||
// The post-condition of this method is everything is ready, so notify now to cover all
|
||||
// return paths. (Other threads will not wake-up until we release |mLock|, whatever).
|
||||
mLock.notifyAll();
|
||||
|
||||
if (mInitState.get() == INIT_FINISHED) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (callSite == CallSite.GET_STATICS) {
|
||||
SharedStatics.setStartupTriggered();
|
||||
}
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||
TrackExitReasons.startTrackingStartup();
|
||||
}
|
||||
@ -410,7 +414,6 @@ public class WebViewChromiumAwInit {
|
||||
AwCrashyClassUtils.maybeCrashIfEnabled();
|
||||
// Must happen right after Chromium initialization is complete.
|
||||
mInitState.set(INIT_FINISHED);
|
||||
mStartupFinished.countDown();
|
||||
// This runs all the pending tasks queued for after Chromium init is finished,
|
||||
// so should run after `mInitState` is `INIT_FINISHED`.
|
||||
mFactory.getRunQueue().notifyChromiumStarted();
|
||||
@ -433,9 +436,7 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up resources on a background thread. This method is called once during
|
||||
* WebViewChromiumFactoryProvider initialization which is guaranteed to finish before this field
|
||||
* is accessed by waitUntilSetUpResources.
|
||||
* Set up resources on a background thread.
|
||||
*
|
||||
* @param context The context.
|
||||
*/
|
||||
@ -483,29 +484,28 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
|
||||
void startYourEngines(boolean fromThreadSafeFunction) {
|
||||
// TODO(crbug.com/389871700): Consider inlining this method call. See
|
||||
// crrev.com/c/6081452/comment/96be8119_fedb4983 for reasoning.
|
||||
ensureChromiumStartedLocked(fromThreadSafeFunction, CallSite.WEBVIEW_INSTANCE);
|
||||
synchronized (mLock) {
|
||||
ensureChromiumStartedLocked(fromThreadSafeFunction, CallSite.WEBVIEW_INSTANCE);
|
||||
}
|
||||
}
|
||||
|
||||
// This method is not private only because the downstream subclass needs to access it,
|
||||
// it shouldn't be accessed from anywhere else.
|
||||
// Postcondition: Chromium startup is finished when this method returns.
|
||||
// TODO(crbug.com/389871700): Rename to ensureChromiumStarted because it doesn't need the lock.
|
||||
@GuardedBy("mLock")
|
||||
void ensureChromiumStartedLocked(boolean fromThreadSafeFunction, @CallSite int callSite) {
|
||||
if (triggerChromiumStartupAndReturnTrueIfStartupIsFinished(
|
||||
fromThreadSafeFunction, callSite)) {
|
||||
assert Thread.holdsLock(mLock);
|
||||
ensureChromiumStartupHappensSoon(fromThreadSafeFunction, callSite);
|
||||
if (mInitState.get() == INIT_FINISHED) { // Early-out for the common case.
|
||||
return;
|
||||
}
|
||||
|
||||
try (ScopedSysTraceEvent event =
|
||||
ScopedSysTraceEvent.scoped("WebViewChromiumAwInit.waitForUIThreadInit")) {
|
||||
long startTime = SystemClock.uptimeMillis();
|
||||
// Wait for the UI thread to finish init.
|
||||
while (true) {
|
||||
while (mInitState.get() != INIT_FINISHED) {
|
||||
try {
|
||||
mStartupFinished.await();
|
||||
break;
|
||||
mLock.wait();
|
||||
} catch (InterruptedException e) {
|
||||
// Keep trying; we can't abort init as WebView APIs do not declare that they
|
||||
// throw InterruptedException.
|
||||
@ -517,18 +517,15 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Triggers Chromium startup. Directly runs startup if called from the UI thread, else, posts
|
||||
* startup to the UI thread to be completed in the near future.
|
||||
*
|
||||
* @returns true if Chromium startup if finished, false if startup will be finished in the near
|
||||
* future. If false, caller may choose to wait on the {@code mStartupFinished} latch, or
|
||||
* {@link WebViewStartUpCallback}.
|
||||
*/
|
||||
private boolean triggerChromiumStartupAndReturnTrueIfStartupIsFinished(
|
||||
// Postcondition: Chromium startup will be finished in the near future, but it may or may not be
|
||||
// finished after this method returns.
|
||||
@GuardedBy("mLock")
|
||||
private void ensureChromiumStartupHappensSoon(
|
||||
boolean fromThreadSafeFunction, @CallSite int callSite) {
|
||||
assert Thread.holdsLock(mLock);
|
||||
|
||||
if (mInitState.get() == INIT_FINISHED) { // Early-out for the common case.
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
maybeSetChromiumUiThread(fromThreadSafeFunction);
|
||||
@ -542,39 +539,43 @@ public class WebViewChromiumAwInit {
|
||||
// already a task posted to the UI thread from another thread to do it, it will just
|
||||
// no-op when it runs.
|
||||
startChromiumLocked(callSite, /* triggeredFromUIThread= */ true);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
// If we're not running on the UI thread (because init was triggered by a thread-safe
|
||||
// function), post init to the UI thread, since init is *not* thread-safe.
|
||||
AwThreadUtils.postToUiThreadLooper(
|
||||
() -> startChromiumLocked(callSite, /* triggeredFromUIThread= */ false));
|
||||
return false;
|
||||
new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
synchronized (mLock) {
|
||||
startChromiumLocked(callSite, /* triggeredFromUIThread= */ false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void maybeSetChromiumUiThread(boolean fromThreadSafeFunction) {
|
||||
synchronized (mThreadSettingLock) {
|
||||
if (mThreadIsSet) {
|
||||
return;
|
||||
if (!mThreadIsSet) {
|
||||
// If we're being started from a function that's allowed to be called on any thread,
|
||||
// then we can't just assume the current thread is the UI thread; instead we assume
|
||||
// the process's main looper will be the UI thread, because that's the case for
|
||||
// almost all Android apps.
|
||||
//
|
||||
// If we're being started from a function that must be called from the UI
|
||||
// thread, then by definition the current thread is the UI thread whether it's the
|
||||
// main looper or not.
|
||||
Looper looper = fromThreadSafeFunction ? Looper.getMainLooper() : Looper.myLooper();
|
||||
Log.v(
|
||||
TAG,
|
||||
"Binding Chromium to "
|
||||
+ (Looper.getMainLooper().equals(looper) ? "main" : "background")
|
||||
+ " looper "
|
||||
+ looper);
|
||||
ThreadUtils.setUiThread(looper);
|
||||
mThreadIsSet = true;
|
||||
}
|
||||
|
||||
// If we're being started from a function that's allowed to be called on any thread,
|
||||
// then we can't just assume the current thread is the UI thread; instead we assume
|
||||
// the process's main looper will be the UI thread, because that's the case for
|
||||
// almost all Android apps.
|
||||
//
|
||||
// If we're being started from a function that must be called from the UI
|
||||
// thread, then by definition the current thread is the UI thread whether it's the
|
||||
// main looper or not.
|
||||
Looper looper = fromThreadSafeFunction ? Looper.getMainLooper() : Looper.myLooper();
|
||||
Log.v(
|
||||
TAG,
|
||||
"Binding Chromium to "
|
||||
+ (Looper.getMainLooper().equals(looper) ? "main" : "background")
|
||||
+ " looper "
|
||||
+ looper);
|
||||
ThreadUtils.setUiThread(looper);
|
||||
mThreadIsSet = true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -608,6 +609,9 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
}
|
||||
|
||||
// This is called only on the same thread that initializes the variable, so
|
||||
// no need to hold a lock.
|
||||
@SuppressWarnings("GuardedBy")
|
||||
AwBrowserContext getDefaultBrowserContextOnUiThread() {
|
||||
if (BuildConfig.ENABLE_ASSERTS && !ThreadUtils.runningOnUiThread()) {
|
||||
throw new RuntimeException(
|
||||
@ -616,20 +620,38 @@ public class WebViewChromiumAwInit {
|
||||
return mChromiumStartedGlobals.mDefaultBrowserContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the lock used for guarding chromium initialization.
|
||||
* We make this public to let higher-level classes use this lock to guard variables
|
||||
* dependent on this class, to avoid introducing new locks (which can cause deadlocks).
|
||||
*/
|
||||
public Object getLock() {
|
||||
return mLock;
|
||||
}
|
||||
|
||||
public SharedStatics getStatics() {
|
||||
// TODO: Optimization potential: most of the static methods only need the native
|
||||
// library loaded and initialized, not the entire browser process started.
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_STATICS);
|
||||
return mChromiumStartedGlobals.mSharedStatics;
|
||||
synchronized (mLock) {
|
||||
if (mChromiumStartedGlobals == null) {
|
||||
// TODO: Optimization potential: most of the static methods only need the native
|
||||
// library loaded and initialized, not the entire browser process started.
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_STATICS);
|
||||
SharedStatics.setStartupTriggered();
|
||||
}
|
||||
return mChromiumStartedGlobals.mSharedStatics;
|
||||
}
|
||||
}
|
||||
|
||||
public GeolocationPermissions getDefaultGeolocationPermissions() {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_DEFAULT_GEOLOCATION_PERMISSIONS);
|
||||
return mChromiumStartedGlobals.mDefaultGeolocationPermissions;
|
||||
synchronized (mLock) {
|
||||
if (mChromiumStartedGlobals == null) {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_DEFAULT_GEOLOCATION_PERMISSIONS);
|
||||
}
|
||||
return mChromiumStartedGlobals.mDefaultGeolocationPermissions;
|
||||
}
|
||||
}
|
||||
|
||||
public CookieManager getDefaultCookieManager() {
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mLock) {
|
||||
if (mDefaultCookieManager == null) {
|
||||
mDefaultCookieManager =
|
||||
new CookieManagerAdapter(AwCookieManager.getDefaultCookieManager());
|
||||
@ -639,14 +661,18 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
|
||||
public AwServiceWorkerController getDefaultServiceWorkerController() {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_DEFAULT_SERVICE_WORKER_CONTROLLER);
|
||||
return mChromiumStartedGlobals.mDefaultServiceWorkerController;
|
||||
synchronized (mLock) {
|
||||
if (mChromiumStartedGlobals == null) {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_DEFAULT_SERVICE_WORKER_CONTROLLER);
|
||||
}
|
||||
return mChromiumStartedGlobals.mDefaultServiceWorkerController;
|
||||
}
|
||||
}
|
||||
|
||||
public android.webkit.WebIconDatabase getWebIconDatabase() {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_WEB_ICON_DATABASE);
|
||||
WebViewChromium.recordWebViewApiCall(ApiCall.WEB_ICON_DATABASE_GET_INSTANCE);
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mLock) {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_WEB_ICON_DATABASE);
|
||||
WebViewChromium.recordWebViewApiCall(ApiCall.WEB_ICON_DATABASE_GET_INSTANCE);
|
||||
if (mWebIconDatabase == null) {
|
||||
mWebIconDatabase = new WebIconDatabaseAdapter();
|
||||
}
|
||||
@ -655,13 +681,17 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
|
||||
public WebStorage getDefaultWebStorage() {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_DEFAULT_WEB_STORAGE);
|
||||
return mChromiumStartedGlobals.mDefaultWebStorage;
|
||||
synchronized (mLock) {
|
||||
if (mChromiumStartedGlobals == null) {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_DEFAULT_WEB_STORAGE);
|
||||
}
|
||||
return mChromiumStartedGlobals.mDefaultWebStorage;
|
||||
}
|
||||
}
|
||||
|
||||
public WebViewDatabase getDefaultWebViewDatabase(final Context context) {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_DEFAULT_WEBVIEW_DATABASE);
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mLock) {
|
||||
ensureChromiumStartedLocked(true, CallSite.GET_DEFAULT_WEBVIEW_DATABASE);
|
||||
if (mDefaultWebViewDatabase == null) {
|
||||
mDefaultWebViewDatabase =
|
||||
new WebViewDatabaseAdapter(
|
||||
@ -674,8 +704,8 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
|
||||
// See comments in VariationsSeedLoader.java on when it's safe to call this.
|
||||
void startVariationsInit() {
|
||||
synchronized (mSeedLoaderLock) {
|
||||
public void startVariationsInit() {
|
||||
synchronized (mLock) {
|
||||
if (mSeedLoader == null) {
|
||||
mSeedLoader = new VariationsSeedLoader();
|
||||
mSeedLoader.startVariationsInit();
|
||||
@ -683,17 +713,17 @@ public class WebViewChromiumAwInit {
|
||||
}
|
||||
}
|
||||
|
||||
@GuardedBy("mLock")
|
||||
private void finishVariationsInitLocked() {
|
||||
try (ScopedSysTraceEvent e =
|
||||
ScopedSysTraceEvent.scoped("WebViewChromiumAwInit.finishVariationsInitLocked")) {
|
||||
synchronized (mSeedLoaderLock) {
|
||||
if (mSeedLoader == null) {
|
||||
Log.e(TAG, "finishVariationsInitLocked() called before startVariationsInit()");
|
||||
startVariationsInit();
|
||||
}
|
||||
mSeedLoader.finishVariationsInit();
|
||||
mSeedLoader = null; // Allow this to be GC'd after its background thread finishes.
|
||||
assert Thread.holdsLock(mLock);
|
||||
if (mSeedLoader == null) {
|
||||
Log.e(TAG, "finishVariationsInitLocked() called before startVariationsInit()");
|
||||
startVariationsInit();
|
||||
}
|
||||
mSeedLoader.finishVariationsInit();
|
||||
mSeedLoader = null; // Allow this to be GC'd after its background thread finishes.
|
||||
}
|
||||
}
|
||||
|
||||
@ -738,8 +768,9 @@ public class WebViewChromiumAwInit {
|
||||
// been set.
|
||||
mWebViewStartUpCallbackRunQueue.addTask(
|
||||
() -> callback.onSuccess(mWebViewStartUpDiagnostics));
|
||||
triggerChromiumStartupAndReturnTrueIfStartupIsFinished(
|
||||
true, CallSite.ASYNC_WEBVIEW_STARTUP);
|
||||
synchronized (mLock) {
|
||||
ensureChromiumStartupHappensSoon(true, CallSite.ASYNC_WEBVIEW_STARTUP);
|
||||
}
|
||||
}
|
||||
|
||||
// These are objects that need to be created on the UI thread and after chromium has started.
|
||||
|
@ -32,7 +32,6 @@ import android.webkit.WebViewFactory;
|
||||
import android.webkit.WebViewFactoryProvider;
|
||||
import android.webkit.WebViewProvider;
|
||||
|
||||
import androidx.annotation.GuardedBy;
|
||||
import androidx.annotation.IntDef;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
@ -184,16 +183,13 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
|
||||
|
||||
protected boolean mShouldDisableThreadChecking;
|
||||
|
||||
private final Object mLazyInitLock = new Object();
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
// Initialization guarded by mAwInit.getLock()
|
||||
private Statics mStaticsAdapter;
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
private ServiceWorkerController mServiceWorkerController;
|
||||
|
||||
private boolean mIsSafeModeEnabled;
|
||||
|
||||
private ServiceWorkerController mServiceWorkerController;
|
||||
|
||||
public static class InitInfo {
|
||||
// Timestamp of init start and duration, used in the
|
||||
// 'WebView.Startup.CreationTime.Stage1.FactoryInit' trace event.
|
||||
@ -206,10 +202,10 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
|
||||
public long mTotalFactoryInitStartTime;
|
||||
public long mTotalFactoryInitDuration;
|
||||
}
|
||||
;
|
||||
|
||||
private InitInfo mInitInfo = new InitInfo();
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
@RequiresApi(Build.VERSION_CODES.P)
|
||||
private ObjectHolderForP mObjectHolderForP =
|
||||
Build.VERSION.SDK_INT >= Build.VERSION_CODES.P ? new ObjectHolderForP() : null;
|
||||
@ -701,9 +697,9 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
|
||||
|
||||
@Override
|
||||
public Statics getStatics() {
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.getLock()) {
|
||||
SharedStatics sharedStatics = mAwInit.getStatics();
|
||||
if (mStaticsAdapter == null) {
|
||||
SharedStatics sharedStatics = mAwInit.getStatics();
|
||||
mStaticsAdapter =
|
||||
new WebViewChromiumFactoryProvider.Statics() {
|
||||
@Override
|
||||
@ -769,8 +765,8 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
|
||||
}
|
||||
};
|
||||
}
|
||||
return mStaticsAdapter;
|
||||
}
|
||||
return mStaticsAdapter;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -851,14 +847,14 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
|
||||
|
||||
@Override
|
||||
public ServiceWorkerController getServiceWorkerController() {
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.getLock()) {
|
||||
if (mServiceWorkerController == null) {
|
||||
mServiceWorkerController =
|
||||
new ServiceWorkerControllerAdapter(
|
||||
mAwInit.getDefaultServiceWorkerController());
|
||||
}
|
||||
return mServiceWorkerController;
|
||||
}
|
||||
return mServiceWorkerController;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -917,15 +913,18 @@ public class WebViewChromiumFactoryProvider implements WebViewFactoryProvider {
|
||||
@RequiresApi(Build.VERSION_CODES.P)
|
||||
@Override
|
||||
public TracingController getTracingController() {
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.mLock) {
|
||||
mAwInit.ensureChromiumStartedLocked(
|
||||
true, WebViewChromiumAwInit.CallSite.GET_TRACING_CONTROLLER);
|
||||
// ensureChromiumStartedLocked() can release the lock on first call while
|
||||
// waiting for startup. Hence check the mTracingController here to ensure
|
||||
// the singleton property.
|
||||
if (mObjectHolderForP.mTracingController == null) {
|
||||
mAwInit.ensureChromiumStartedLocked(
|
||||
true, WebViewChromiumAwInit.CallSite.GET_TRACING_CONTROLLER);
|
||||
mObjectHolderForP.mTracingController =
|
||||
GlueApiHelperForP.createTracingControllerAdapter(this, mAwInit);
|
||||
}
|
||||
return mObjectHolderForP.mTracingController;
|
||||
}
|
||||
return mObjectHolderForP.mTracingController;
|
||||
}
|
||||
|
||||
private static class FilteredClassLoader extends ClassLoader {
|
||||
|
@ -9,7 +9,6 @@ import android.net.Uri;
|
||||
import android.webkit.ValueCallback;
|
||||
import android.webkit.WebView;
|
||||
|
||||
import androidx.annotation.GuardedBy;
|
||||
import androidx.annotation.IntDef;
|
||||
|
||||
import com.android.webview.chromium.CallbackConverter;
|
||||
@ -371,24 +370,12 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
"Android.WebView.AndroidX.ApiCall", apiCall, ApiCall.COUNT);
|
||||
}
|
||||
|
||||
private final Object mLazyInitLock = new Object();
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
// Initialization guarded by mAwInit.getLock()
|
||||
private InvocationHandler mStatics;
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
private InvocationHandler mServiceWorkerController;
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
private InvocationHandler mTracingController;
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
private InvocationHandler mProxyController;
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
private InvocationHandler mDropDataProvider;
|
||||
|
||||
@GuardedBy("mLazyInitLock")
|
||||
private InvocationHandler mProfileStore;
|
||||
|
||||
public SupportLibWebViewChromiumFactory() {
|
||||
@ -501,7 +488,7 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
public InvocationHandler getStatics() {
|
||||
try (TraceEvent event = TraceEvent.scoped("WebView.APICall.AndroidX.GET_STATICS")) {
|
||||
recordApiCall(ApiCall.GET_STATICS);
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.getLock()) {
|
||||
if (mStatics == null) {
|
||||
mStatics =
|
||||
BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
|
||||
@ -509,9 +496,8 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
WebkitToSharedGlueConverter.getGlobalAwInit()
|
||||
.getStatics()));
|
||||
}
|
||||
|
||||
return mStatics;
|
||||
}
|
||||
return mStatics;
|
||||
}
|
||||
}
|
||||
|
||||
@ -529,16 +515,15 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
try (TraceEvent event =
|
||||
TraceEvent.scoped("WebView.APICall.AndroidX.GET_SERVICE_WORKER_CONTROLLER")) {
|
||||
recordApiCall(ApiCall.GET_SERVICE_WORKER_CONTROLLER);
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.getLock()) {
|
||||
if (mServiceWorkerController == null) {
|
||||
mServiceWorkerController =
|
||||
BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
|
||||
new SupportLibServiceWorkerControllerAdapter(
|
||||
mAwInit.getDefaultServiceWorkerController()));
|
||||
}
|
||||
|
||||
return mServiceWorkerController;
|
||||
}
|
||||
return mServiceWorkerController;
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,7 +532,7 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
try (TraceEvent event =
|
||||
TraceEvent.scoped("WebView.APICall.AndroidX.GET_TRACING_CONTROLLER")) {
|
||||
recordApiCall(ApiCall.GET_TRACING_CONTROLLER);
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.getLock()) {
|
||||
if (mTracingController == null) {
|
||||
mTracingController =
|
||||
BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
|
||||
@ -556,9 +541,8 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
mAwInit.getRunQueue(),
|
||||
mAwInit.getAwTracingController())));
|
||||
}
|
||||
|
||||
return mTracingController;
|
||||
}
|
||||
return mTracingController;
|
||||
}
|
||||
}
|
||||
|
||||
@ -567,16 +551,15 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
try (TraceEvent event =
|
||||
TraceEvent.scoped("WebView.APICall.AndroidX.GET_PROXY_CONTROLLER")) {
|
||||
recordApiCall(ApiCall.GET_PROXY_CONTROLLER);
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.getLock()) {
|
||||
if (mProxyController == null) {
|
||||
mProxyController =
|
||||
BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
|
||||
new SupportLibProxyControllerAdapter(
|
||||
mAwInit.getRunQueue(), mAwInit.getAwProxyController()));
|
||||
}
|
||||
|
||||
return mProxyController;
|
||||
}
|
||||
return mProxyController;
|
||||
}
|
||||
}
|
||||
|
||||
@ -585,14 +568,14 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
try (TraceEvent event =
|
||||
TraceEvent.scoped("WebView.APICall.AndroidX.GET_IMAGE_DRAG_DROP_IMPLEMENTATION")) {
|
||||
recordApiCall(ApiCall.GET_IMAGE_DRAG_DROP_IMPLEMENTATION);
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.getLock()) {
|
||||
if (mDropDataProvider == null) {
|
||||
mDropDataProvider =
|
||||
BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
|
||||
new SupportLibDropDataContentProviderAdapter());
|
||||
}
|
||||
return mDropDataProvider;
|
||||
}
|
||||
return mDropDataProvider;
|
||||
}
|
||||
}
|
||||
|
||||
@ -600,15 +583,14 @@ public class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryB
|
||||
public InvocationHandler getProfileStore() {
|
||||
try (TraceEvent event = TraceEvent.scoped("WebView.APICall.AndroidX.GET_PROFILE_STORE")) {
|
||||
recordApiCall(ApiCall.GET_PROFILE_STORE);
|
||||
synchronized (mLazyInitLock) {
|
||||
synchronized (mAwInit.getLock()) {
|
||||
if (mProfileStore == null) {
|
||||
mProfileStore =
|
||||
BoundaryInterfaceReflectionUtil.createInvocationHandlerFor(
|
||||
new SupportLibProfileStore(ProfileStore.getInstance()));
|
||||
}
|
||||
|
||||
return mProfileStore;
|
||||
}
|
||||
return mProfileStore;
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user