From fd07efa44e1337f9b573d977cd3e8d701af8fe48 Mon Sep 17 00:00:00 2001 From: Gustav Sennton Date: Mon, 23 May 2016 13:09:03 +0100 Subject: [PATCH] Load WebView even if WebView relro creation times out. There are cases in which the WebView Update Service can stop switching WebView providers (if the update service is notified about relro creations an incorrect number of times) and in those cases apps will fail to load WebView. In this CL we mitigate this problem by allowing apps to load WebView even if the time-out is reached and we also decrease the time-out so apps are less likely to ANR when waiting for the time-out. This CL does not prevent the update service from ending up in a bad state - so we will still end up crashing apps if the current WebView implementation is uninstalled after relro creation fails. Bug: 28860862 Change-Id: Ib6af3722e17a13db77ef34c37581a6a0e1d045bb --- core/java/android/webkit/WebViewFactory.java | 15 +++++++++++---- .../server/webkit/WebViewUpdateServiceImpl.java | 6 +++++- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 5db0f1659871b..2d1e0bd305907 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -142,13 +142,17 @@ public final class WebViewFactory { public static int loadWebViewNativeLibraryFromPackage(String packageName, ClassLoader clazzLoader) { int ret = waitForProviderAndSetPackageInfo(); - if (ret != LIBLOAD_SUCCESS) { + if (ret != LIBLOAD_SUCCESS && ret != LIBLOAD_FAILED_WAITING_FOR_RELRO) { return ret; } if (!sPackageInfo.packageName.equals(packageName)) return LIBLOAD_WRONG_PACKAGE_NAME; - return loadNativeLibrary(clazzLoader); + int loadNativeRet = loadNativeLibrary(clazzLoader); + // If we failed waiting for relro we want to return that fact even if we successfully load + // the relro file. + if (loadNativeRet == LIBLOAD_SUCCESS) return ret; + return loadNativeRet; } static WebViewFactoryProvider getProvider() { @@ -240,7 +244,8 @@ public final class WebViewFactory { } finally { Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); } - if (response.status != LIBLOAD_SUCCESS) { + if (response.status != LIBLOAD_SUCCESS + && response.status != LIBLOAD_FAILED_WAITING_FOR_RELRO) { throw new MissingWebViewPackageException("Failed to load WebView provider: " + getWebViewPreparationErrorReason(response.status)); } @@ -599,8 +604,10 @@ public final class WebViewFactory { try { response = getUpdateService().waitForAndGetProvider(); - if (response.status == WebViewFactory.LIBLOAD_SUCCESS) + if (response.status == LIBLOAD_SUCCESS + || response.status == LIBLOAD_FAILED_WAITING_FOR_RELRO) { sPackageInfo = response.packageInfo; + } } catch (RemoteException e) { Log.e(LOGTAG, "error waiting for relro creation", e); return LIBLOAD_FAILED_WAITING_FOR_WEBVIEW_REASON_UNKNOWN; diff --git a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java index 91de797cf98c6..ecab009ed12c4 100644 --- a/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java +++ b/services/core/java/com/android/server/webkit/WebViewUpdateServiceImpl.java @@ -217,7 +217,7 @@ public class WebViewUpdateServiceImpl { mSystemInterface = systemInterface; } - private static final int WAIT_TIMEOUT_MS = 4500; // KEY_DISPATCHING_TIMEOUT is 5000. + private static final int WAIT_TIMEOUT_MS = 1000; // KEY_DISPATCHING_TIMEOUT is 5000. // Keeps track of the number of running relro creations private int mNumRelroCreationsStarted = 0; @@ -487,6 +487,10 @@ public class WebViewUpdateServiceImpl { // Either the current relro creation isn't done yet, or the new relro creatioin // hasn't kicked off yet (the last relro creation used an out-of-date WebView). webViewStatus = WebViewFactory.LIBLOAD_FAILED_WAITING_FOR_RELRO; + Slog.e(TAG, "Timed out waiting for relro creation, relros started " + + mNumRelroCreationsStarted + + " relros finished " + mNumRelroCreationsFinished + + " package dirty? " + mWebViewPackageDirty); } } if (!webViewReady) Slog.w(TAG, "creating relro file timed out");