0

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:
Chidera Olibie
2025-02-11 12:08:29 -08:00
committed by Chromium LUCI CQ
parent eb03220c5f
commit b4416887f1
3 changed files with 160 additions and 148 deletions
android_webview
glue
support_library
java
src
org

@ -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;
}
}