Use newly fetched PackageInfo for loading WebView code.

During a time window between the point at which a webview package
becomes updated and the WebViewUpdateService receiving an intent
declaring this action the WebViewUpdateService APIs will return a
PackageInfo pointing to an old and possibly removed WebView package.
This means that any paths that PackageInfo is referring to could have
been removed.

Currently, we set WebViewFactory.sPackageInfo using one of these APIs
and we might thus try to use deleted paths to to load WebView. This can
cause crashes, so instead fetch a fresh PackageInfo and assign
WebViewFactory.sPackageInfo to that.

Also early-out in loadWebViewNativeLibraryFromPackage if the current
package version doesn't match that of the one fetched from the
WebViewUpdateService.

Bug: 29381682
Change-Id: I2713ce2338a4a96c5317dcdbb363b424513088d5
diff --git a/core/java/android/webkit/WebViewFactory.java b/core/java/android/webkit/WebViewFactory.java
index 2d1e0bd..15eb8de 100644
--- a/core/java/android/webkit/WebViewFactory.java
+++ b/core/java/android/webkit/WebViewFactory.java
@@ -141,17 +141,38 @@
      */
     public static int loadWebViewNativeLibraryFromPackage(String packageName,
                                                           ClassLoader clazzLoader) {
-        int ret = waitForProviderAndSetPackageInfo();
-        if (ret != LIBLOAD_SUCCESS && ret != LIBLOAD_FAILED_WAITING_FOR_RELRO) {
-            return ret;
+        WebViewProviderResponse response = null;
+        try {
+            response = getUpdateService().waitForAndGetProvider();
+        } catch (RemoteException e) {
+            Log.e(LOGTAG, "error waiting for relro creation", e);
+            return LIBLOAD_FAILED_WAITING_FOR_WEBVIEW_REASON_UNKNOWN;
         }
-        if (!sPackageInfo.packageName.equals(packageName))
+
+
+        if (response.status != LIBLOAD_SUCCESS
+                && response.status != LIBLOAD_FAILED_WAITING_FOR_RELRO) {
+            return response.status;
+        }
+        if (!response.packageInfo.packageName.equals(packageName)) {
             return LIBLOAD_WRONG_PACKAGE_NAME;
+        }
+
+        PackageManager packageManager = AppGlobals.getInitialApplication().getPackageManager();
+        PackageInfo packageInfo;
+        try {
+            packageInfo = packageManager.getPackageInfo(packageName,
+                    PackageManager.GET_META_DATA | PackageManager.MATCH_DEBUG_TRIAGED_MISSING);
+        } catch (PackageManager.NameNotFoundException e) {
+            Log.e(LOGTAG, "Couldn't find package " + packageName);
+            return LIBLOAD_WRONG_PACKAGE_NAME;
+        }
+        sPackageInfo = packageInfo;
 
         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;
+        if (loadNativeRet == LIBLOAD_SUCCESS) return response.status;
         return loadNativeRet;
     }
 
@@ -288,7 +309,7 @@
                 Context webViewContext = initialApplication.createApplicationContext(
                         newPackageInfo.applicationInfo,
                         Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
-                sPackageInfo = response.packageInfo;
+                sPackageInfo = newPackageInfo;
                 return webViewContext;
             } finally {
                 Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW);
@@ -599,22 +620,6 @@
         }
     }
 
-    private static int waitForProviderAndSetPackageInfo() {
-        WebViewProviderResponse response = null;
-        try {
-            response =
-                getUpdateService().waitForAndGetProvider();
-            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;
-        }
-        return response.status;
-    }
-
     // Assumes that we have waited for relro creation and set sPackageInfo
     private static int loadNativeLibrary(ClassLoader clazzLoader) {
         if (!sAddressSpaceReserved) {