From a8366e78b58aeb392a9dcc7301183e881d99c783 Mon Sep 17 00:00:00 2001 From: Gustav Sennton Date: Fri, 17 Apr 2015 11:24:07 +0100 Subject: [PATCH] Fix loading of null webview if there is no webview package. In the change in go/ag/672863 we throw an AndroidRuntimeException instead of a PackageManager.NameNotFoundException when no webview package exists. This should break devices not using webview since the NameNotFoundException is used to detect webview not being present (so that the null webview can be loaded instead). In this patch we create a new type of exception and look for that one instead when we want to determine whether the device should or should not have webview installed. Change-Id: Ia75dec718d7a5b2c3517671c54be3950badb8bba --- core/java/android/webkit/WebViewFactory.java | 85 ++++++++++++-------- 1 file changed, 50 insertions(+), 35 deletions(-) diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java index 4d8dce1f121e2..3340c73c32db3 100644 --- a/core/java/android/webkit/WebViewFactory.java +++ b/core/java/android/webkit/WebViewFactory.java @@ -76,6 +76,11 @@ public final class WebViewFactory { private static boolean sAddressSpaceReserved = false; private static PackageInfo sPackageInfo; + private static class MissingWebViewPackageException extends AndroidRuntimeException { + public MissingWebViewPackageException(String message) { super(message); } + public MissingWebViewPackageException(Exception e) { super(e); } + } + /** @hide */ public static String[] getWebViewPackageNames() { return AppGlobals.getInitialApplication().getResources().getStringArray( @@ -110,9 +115,10 @@ public final class WebViewFactory { } catch (PackageManager.NameNotFoundException e) { } } - throw new AndroidRuntimeException("Could not find a loadable WebView package"); + throw new MissingWebViewPackageException("Could not find a loadable WebView package"); } + // throws MissingWebViewPackageException private static ApplicationInfo getWebViewApplicationInfo() { if (sPackageInfo == null) return findPreferredWebViewPackage().applicationInfo; @@ -144,25 +150,7 @@ public final class WebViewFactory { Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()"); try { - // First fetch the package info so we can log the webview package version. - sPackageInfo = findPreferredWebViewPackage(); - Log.i(LOGTAG, "Loading " + sPackageInfo.packageName + " version " + - sPackageInfo.versionName + " (code " + sPackageInfo.versionCode + ")"); - - Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()"); - loadNativeLibrary(); - Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); - - Class providerClass; - Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getFactoryClass()"); - try { - providerClass = getFactoryClass(); - } catch (ClassNotFoundException e) { - Log.e(LOGTAG, "error loading provider", e); - throw new AndroidRuntimeException(e); - } finally { - Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); - } + Class providerClass = getProviderClass(); StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()"); @@ -184,7 +172,44 @@ public final class WebViewFactory { } } - private static Class getFactoryClass() throws ClassNotFoundException { + private static Class getProviderClass() { + try { + // First fetch the package info so we can log the webview package version. + sPackageInfo = findPreferredWebViewPackage(); + Log.i(LOGTAG, "Loading " + sPackageInfo.packageName + " version " + + sPackageInfo.versionName + " (code " + sPackageInfo.versionCode + ")"); + + Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()"); + loadNativeLibrary(); + Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); + + Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getChromiumProviderClass()"); + try { + return getChromiumProviderClass(); + } catch (ClassNotFoundException e) { + Log.e(LOGTAG, "error loading provider", e); + throw new AndroidRuntimeException(e); + } finally { + Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); + } + } catch (MissingWebViewPackageException e) { + // If the package doesn't exist, then try loading the null WebView instead. + // If that succeeds, then this is a device without WebView support; if it fails then + // swallow the failure, complain that the real WebView is missing and rethrow the + // original exception. + try { + return (Class) Class.forName(NULL_WEBVIEW_FACTORY); + } catch (ClassNotFoundException e2) { + // Ignore. + } + Log.e(LOGTAG, "Chromium WebView package does not exist", e); + throw new AndroidRuntimeException(e); + } + } + + // throws MissingWebViewPackageException + private static Class getChromiumProviderClass() + throws ClassNotFoundException { Application initialApplication = AppGlobals.getInitialApplication(); try { // Construct a package context to load the Java code into the current app. @@ -202,17 +227,7 @@ public final class WebViewFactory { Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); } } catch (PackageManager.NameNotFoundException e) { - // If the package doesn't exist, then try loading the null WebView instead. - // If that succeeds, then this is a device without WebView support; if it fails then - // swallow the failure, complain that the real WebView is missing and rethrow the - // original exception. - try { - return (Class) Class.forName(NULL_WEBVIEW_FACTORY); - } catch (ClassNotFoundException e2) { - // Ignore. - } - Log.e(LOGTAG, "Chromium WebView package does not exist", e); - throw new AndroidRuntimeException(e); + throw new MissingWebViewPackageException(e); } } @@ -315,8 +330,8 @@ public final class WebViewFactory { prepareWebViewInSystemServer(nativeLibs); } - private static String[] getWebViewNativeLibraryPaths() - throws PackageManager.NameNotFoundException { + // throws MissingWebViewPackageException + private static String[] getWebViewNativeLibraryPaths() { ApplicationInfo ai = getWebViewApplicationInfo(); final String NATIVE_LIB_FILE_NAME = getWebViewLibrary(ai); @@ -443,7 +458,7 @@ public final class WebViewFactory { } else if (DEBUG) { Log.v(LOGTAG, "loaded with relro file"); } - } catch (PackageManager.NameNotFoundException e) { + } catch (MissingWebViewPackageException e) { Log.e(LOGTAG, "Failed to list WebView package libraries for loadNativeLibrary", e); } }