WebViewFactory.java revision 3822882b32d9b1b803aaff9b657a91d680f1d0f9
1d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon/* 2d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * Copyright (C) 2012 The Android Open Source Project 3d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * 4d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * Licensed under the Apache License, Version 2.0 (the "License"); 5d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * you may not use this file except in compliance with the License. 6d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * You may obtain a copy of the License at 7d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * 8d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * http://www.apache.org/licenses/LICENSE-2.0 9d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * 10d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * Unless required by applicable law or agreed to in writing, software 11d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * distributed under the License is distributed on an "AS IS" BASIS, 12d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * See the License for the specific language governing permissions and 14d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * limitations under the License. 15d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon */ 16d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 17d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonpackage android.webkit; 18d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 19810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucciimport android.app.ActivityManagerInternal; 2063d3d8a458cfc124ebd183994d3d152d3b06c1d8Marcin Kosibaimport android.app.Application; 216c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles)import android.app.AppGlobals; 226c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles)import android.content.Context; 231b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucciimport android.content.pm.ApplicationInfo; 240606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles)import android.content.pm.PackageInfo; 256c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles)import android.content.pm.PackageManager; 2608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)import android.os.Build; 2708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)import android.os.Process; 2808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)import android.os.RemoteException; 2908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)import android.os.ServiceManager; 30e09e976dad1d974ca28381451b0bbbeafbb872d5Ben Murdochimport android.os.StrictMode; 315ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdochimport android.os.SystemProperties; 323822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles)import android.os.Trace; 331b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucciimport android.text.TextUtils; 3403ce9b3e69f1eec85e7e7cbfd65bb9093e74cea8Torne (Richard Coles)import android.util.AndroidRuntimeException; 35d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixonimport android.util.Log; 36810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucciimport com.android.server.LocalServices; 3708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)import dalvik.system.VMRuntime; 3808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 3908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)import java.io.File; 401b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucciimport java.util.Arrays; 4108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 4208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles)import com.android.internal.os.Zygote; 43d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 44d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon/** 45d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon * Top level factory, used creating all the main WebView implementation classes. 46b0e35846b818bdf0db9cafe881a8a535116d596eJared Duke * 47b0e35846b818bdf0db9cafe881a8a535116d596eJared Duke * @hide 48d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon */ 49b0e35846b818bdf0db9cafe881a8a535116d596eJared Dukepublic final class WebViewFactory { 50a7eaa8ee222611c28f050158db4b68c4d893a8a9Jonathan Dixon 51e09e976dad1d974ca28381451b0bbbeafbb872d5Ben Murdoch private static final String CHROMIUM_WEBVIEW_FACTORY = 52a9bbd9439c3043bd76a7474e6dca3c8131b1b258Torne (Richard Coles) "com.android.webview.chromium.WebViewChromiumFactoryProvider"; 53d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 540e04bcfbdc1845c931b45b3498aef438b944e961Ben Murdoch private static final String NULL_WEBVIEW_FACTORY = 550e04bcfbdc1845c931b45b3498aef438b944e961Ben Murdoch "com.android.webview.nullwebview.NullWebViewFactoryProvider"; 560e04bcfbdc1845c931b45b3498aef438b944e961Ben Murdoch 5708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static final String CHROMIUM_WEBVIEW_NATIVE_RELRO_32 = 5808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) "/data/misc/shared_relro/libwebviewchromium32.relro"; 5908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static final String CHROMIUM_WEBVIEW_NATIVE_RELRO_64 = 6008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) "/data/misc/shared_relro/libwebviewchromium64.relro"; 6108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 625ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch public static final String CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY = 635ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch "persist.sys.webview.vmsize"; 645ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch private static final long CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES = 100 * 1024 * 1024; 651b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci 66d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon private static final String LOGTAG = "WebViewFactory"; 67d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 68d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon private static final boolean DEBUG = false; 69d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 70d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon // Cache the factory both for efficiency, and ensure any one process gets all webviews from the 71d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon // same provider. 72d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon private static WebViewFactoryProvider sProviderInstance; 739f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck private static final Object sProviderLock = new Object(); 7408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static boolean sAddressSpaceReserved = false; 75d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 76dc00a84af15ff3594a6dfa512be21095bf9fee82Ben Murdoch public static String getWebViewPackageName() { 775651fc2feeed3af1bd0991e32788a8936d698811Torne (Richard Coles) return AppGlobals.getInitialApplication().getString( 785651fc2feeed3af1bd0991e32788a8936d698811Torne (Richard Coles) com.android.internal.R.string.config_webViewPackageName); 79dc00a84af15ff3594a6dfa512be21095bf9fee82Ben Murdoch } 80dc00a84af15ff3594a6dfa512be21095bf9fee82Ben Murdoch 819f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck static WebViewFactoryProvider getProvider() { 829f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck synchronized (sProviderLock) { 839f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck // For now the main purpose of this function (and the factory abstraction) is to keep 84d892afc88d3c67a7fe1c9550bfa7a452051d031dTorne (Richard Coles) // us honest and minimize usage of WebView internals when binding the proxy. 859f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck if (sProviderInstance != null) return sProviderInstance; 86d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 873822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()"); 8803ce9b3e69f1eec85e7e7cbfd65bb9093e74cea8Torne (Richard Coles) try { 893822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()"); 903822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) loadNativeLibrary(); 913822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 923822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) 933822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Class<WebViewFactoryProvider> providerClass; 943822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getFactoryClass()"); 953822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) try { 963822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) providerClass = getFactoryClass(); 973822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } catch (ClassNotFoundException e) { 983822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Log.e(LOGTAG, "error loading provider", e); 993822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) throw new AndroidRuntimeException(e); 1003822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } finally { 1013822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 1023822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } 1033822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) 1043822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 1053822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()"); 1063822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) try { 1073822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) sProviderInstance = providerClass.newInstance(); 1083822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance); 1093822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) return sProviderInstance; 1103822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } catch (Exception e) { 1113822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Log.e(LOGTAG, "error instantiating provider", e); 1123822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) throw new AndroidRuntimeException(e); 1133822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } finally { 1143822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 1153822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) StrictMode.setThreadPolicy(oldPolicy); 1163822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } 11703ce9b3e69f1eec85e7e7cbfd65bb9093e74cea8Torne (Richard Coles) } finally { 1183822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 119e09e976dad1d974ca28381451b0bbbeafbb872d5Ben Murdoch } 120d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon } 121d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon } 122d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 12303ce9b3e69f1eec85e7e7cbfd65bb9093e74cea8Torne (Richard Coles) private static Class<WebViewFactoryProvider> getFactoryClass() throws ClassNotFoundException { 12463d3d8a458cfc124ebd183994d3d152d3b06c1d8Marcin Kosiba Application initialApplication = AppGlobals.getInitialApplication(); 1250e04bcfbdc1845c931b45b3498aef438b944e961Ben Murdoch try { 1260606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) // First fetch the package info so we can log the webview package version. 1270606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) String packageName = getWebViewPackageName(); 1280606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) PackageInfo pi = initialApplication.getPackageManager().getPackageInfo(packageName, 0); 1290606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) Log.i(LOGTAG, "Loading " + packageName + " version " + pi.versionName + 1300606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) " (code " + pi.versionCode + ")"); 1310606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) 1320606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) // Construct a package context to load the Java code into the current app. 1330606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) Context webViewContext = initialApplication.createPackageContext(packageName, 1346c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles) Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); 13563d3d8a458cfc124ebd183994d3d152d3b06c1d8Marcin Kosiba initialApplication.getAssets().addAssetPath( 13663d3d8a458cfc124ebd183994d3d152d3b06c1d8Marcin Kosiba webViewContext.getApplicationInfo().sourceDir); 1376c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles) ClassLoader clazzLoader = webViewContext.getClassLoader(); 1383822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()"); 1393822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) try { 1403822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY, true, 1413822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) clazzLoader); 1423822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } finally { 1433822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 1443822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } 1456c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles) } catch (PackageManager.NameNotFoundException e) { 1465f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // If the package doesn't exist, then try loading the null WebView instead. 1475f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // If that succeeds, then this is a device without WebView support; if it fails then 1485f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // swallow the failure, complain that the real WebView is missing and rethrow the 1495f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // original exception. 1505f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) try { 1515f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) return (Class<WebViewFactoryProvider>) Class.forName(NULL_WEBVIEW_FACTORY); 1525f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) } catch (ClassNotFoundException e2) { 1535f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // Ignore. 1545f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) } 1555f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) Log.e(LOGTAG, "Chromium WebView package does not exist", e); 1565f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) throw new AndroidRuntimeException(e); 1570e04bcfbdc1845c931b45b3498aef438b944e961Ben Murdoch } 158d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon } 15908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 16008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) /** 16108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * Perform any WebView loading preparations that must happen in the zygote. 16208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * Currently, this means allocating address space to load the real JNI library later. 16308cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) */ 16408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) public static void prepareWebViewInZygote() { 16508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) try { 16608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) System.loadLibrary("webviewchromium_loader"); 1675ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch long addressSpaceToReserve = 1685ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch SystemProperties.getLong(CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY, 1695ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES); 1705ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch sAddressSpaceReserved = nativeReserveAddressSpace(addressSpaceToReserve); 1715ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 17208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) if (sAddressSpaceReserved) { 1735ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (DEBUG) { 1745ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch Log.v(LOGTAG, "address space reserved: " + addressSpaceToReserve + " bytes"); 1755ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 17608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } else { 1775ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch Log.e(LOGTAG, "reserving " + addressSpaceToReserve + 1785ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch " bytes of address space failed"); 17908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 180810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } catch (Throwable t) { 18108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) // Log and discard errors at this stage as we must not crash the zygote. 182810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Log.e(LOGTAG, "error preparing native loader", t); 18308cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 18408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 18508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 18608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) /** 18708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * Perform any WebView loading preparations that must happen at boot from the system server, 1885ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch * after the package manager has started or after an update to the webview is installed. 18908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * This must be called in the system server. 19008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * Currently, this means spawning the child processes which will create the relro files. 19108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) */ 19208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) public static void prepareWebViewInSystemServer() { 1935ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch String[] nativePaths = null; 1945ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch try { 1955ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch nativePaths = getWebViewNativeLibraryPaths(); 19627cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) } catch (Throwable t) { 19727cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // Log and discard errors at this stage as we must not crash the system server. 19827cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Log.e(LOGTAG, "error preparing webview native library", t); 1995ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2005ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch prepareWebViewInSystemServer(nativePaths); 2015ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2025ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 2035ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch private static void prepareWebViewInSystemServer(String[] nativeLibraryPaths) { 20408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) if (DEBUG) Log.v(LOGTAG, "creating relro files"); 2055ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 2065ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch // We must always trigger createRelRo regardless of the value of nativeLibraryPaths. Any 2075ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch // unexpected values will be handled there to ensure that we trigger notifying any process 2085ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch // waiting on relreo creation. 2095ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 2105ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro"); 2115ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch createRelroFile(false /* is64Bit */, nativeLibraryPaths); 2125ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2135ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 2145ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 2155ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro"); 2165ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch createRelroFile(true /* is64Bit */, nativeLibraryPaths); 2175ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2185ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2195ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 2205ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch public static void onWebViewUpdateInstalled() { 2215ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch String[] nativeLibs = null; 2225ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch try { 2235ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch nativeLibs = WebViewFactory.getWebViewNativeLibraryPaths(); 22427cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (nativeLibs != null) { 22527cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) long newVmSize = 0L; 22627cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) 22727cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) for (String path : nativeLibs) { 22827cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (DEBUG) Log.d(LOGTAG, "Checking file size of " + path); 22927cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (path == null) continue; 23027cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) File f = new File(path); 23127cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (f.exists()) { 23227cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) long length = f.length(); 23327cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (length > newVmSize) { 23427cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) newVmSize = length; 23527cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) } 2365ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2375ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2385ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 23927cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (DEBUG) { 24027cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Log.v(LOGTAG, "Based on library size, need " + newVmSize + 24127cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) " bytes of address space."); 24227cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) } 24327cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // The required memory can be larger than the file on disk (due to .bss), and an 24427cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // upgraded version of the library will likely be larger, so always attempt to 24527cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // reserve twice as much as we think to allow for the library to grow during this 24627cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // boot cycle. 24727cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) newVmSize = Math.max(2 * newVmSize, CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES); 24827cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Log.d(LOGTAG, "Setting new address space to " + newVmSize); 24927cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) SystemProperties.set(CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY, 25027cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Long.toString(newVmSize)); 2515ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 25227cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) } catch (Throwable t) { 25327cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // Log and discard errors at this stage as we must not crash the system server. 25427cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Log.e(LOGTAG, "error preparing webview native library", t); 25508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 2565ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch prepareWebViewInSystemServer(nativeLibs); 25708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 25808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 2591b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci private static String[] getWebViewNativeLibraryPaths() 2601b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci throws PackageManager.NameNotFoundException { 2611b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci final String NATIVE_LIB_FILE_NAME = "libwebviewchromium.so"; 2621b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci 2631b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); 2641b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci ApplicationInfo ai = pm.getApplicationInfo(getWebViewPackageName(), 0); 2651b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci 2661b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci String path32; 2671b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci String path64; 2681b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci boolean primaryArchIs64bit = VMRuntime.is64BitAbi(ai.primaryCpuAbi); 2691b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!TextUtils.isEmpty(ai.secondaryCpuAbi)) { 2701b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Multi-arch case. 2711b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (primaryArchIs64bit) { 2721b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Primary arch: 64-bit, secondary: 32-bit. 2731b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path64 = ai.nativeLibraryDir; 2741b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path32 = ai.secondaryNativeLibraryDir; 2751b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } else { 2761b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Primary arch: 32-bit, secondary: 64-bit. 2771b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path64 = ai.secondaryNativeLibraryDir; 2781b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path32 = ai.nativeLibraryDir; 2791b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 2801b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } else if (primaryArchIs64bit) { 2811b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Single-arch 64-bit. 2821b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path64 = ai.nativeLibraryDir; 2831b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path32 = ""; 2841b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } else { 2851b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Single-arch 32-bit. 2861b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path32 = ai.nativeLibraryDir; 2871b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path64 = ""; 2881b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 2891b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!TextUtils.isEmpty(path32)) path32 += "/" + NATIVE_LIB_FILE_NAME; 2901b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!TextUtils.isEmpty(path64)) path64 += "/" + NATIVE_LIB_FILE_NAME; 2911b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci return new String[] { path32, path64 }; 2921b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 2931b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci 2945ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch private static void createRelroFile(final boolean is64Bit, String[] nativeLibraryPaths) { 2951b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci final String abi = 2961b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci is64Bit ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 297810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci 298810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci // crashHandler is invoked by the ActivityManagerService when the isolated process crashes. 299810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Runnable crashHandler = new Runnable() { 300810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci @Override 301810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci public void run() { 302810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci try { 3031b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "relro file creator for " + abi + " crashed. Proceeding without"); 304810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci getUpdateService().notifyRelroCreationCompleted(is64Bit, false); 305810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } catch (RemoteException e) { 306810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Log.e(LOGTAG, "Cannot reach WebViewUpdateService. " + e.getMessage()); 307810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } 308810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } 309810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci }; 310810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci 31108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) try { 3125ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (nativeLibraryPaths == null 3135ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch || nativeLibraryPaths[0] == null || nativeLibraryPaths[1] == null) { 3145ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch throw new IllegalArgumentException( 3155ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch "Native library paths to the WebView RelRo process must not be null!"); 3165ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 317161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci int pid = LocalServices.getService(ActivityManagerInternal.class).startIsolatedProcess( 3185ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch RelroFileCreator.class.getName(), nativeLibraryPaths, "WebViewLoader-" + abi, abi, 319810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Process.SHARED_RELRO_UID, crashHandler); 320e76e81a227a29db5223d231ec88ecb02fa4d6835Primiano Tucci if (pid <= 0) throw new Exception("Failed to start the relro file creator process"); 321810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } catch (Throwable t) { 32208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) // Log and discard errors as we must not crash the system server. 323810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Log.e(LOGTAG, "error starting relro file creator for abi " + abi, t); 324810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci crashHandler.run(); 32508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 32608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 32708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 32808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static class RelroFileCreator { 32908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) // Called in an unprivileged child process to create the relro file. 33008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) public static void main(String[] args) { 331161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci boolean result = false; 332161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci boolean is64Bit = VMRuntime.getRuntime().is64Bit(); 3331b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci try{ 3341b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (args.length != 2 || args[0] == null || args[1] == null) { 3351b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "Invalid RelroFileCreator args: " + Arrays.toString(args)); 3361b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci return; 3371b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 3381b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.v(LOGTAG, "RelroFileCreator (64bit = " + is64Bit + "), " + 3391b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci " 32-bit lib: " + args[0] + ", 64-bit lib: " + args[1]); 3401b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!sAddressSpaceReserved) { 3411b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "can't create relro file; address space not reserved"); 3421b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci return; 3431b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 344161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci result = nativeCreateRelroFile(args[0] /* path32 */, 345161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci args[1] /* path64 */, 346161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci CHROMIUM_WEBVIEW_NATIVE_RELRO_32, 347161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci CHROMIUM_WEBVIEW_NATIVE_RELRO_64); 348e76e81a227a29db5223d231ec88ecb02fa4d6835Primiano Tucci if (result && DEBUG) Log.v(LOGTAG, "created relro file"); 349161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci } finally { 350161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci // We must do our best to always notify the update service, even if something fails. 3511b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci try { 3521b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci getUpdateService().notifyRelroCreationCompleted(is64Bit, result); 3531b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } catch (RemoteException e) { 3541b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "error notifying update service", e); 3551b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 356161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci 357161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci if (!result) Log.e(LOGTAG, "failed to create relro file"); 358161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci 3591b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Must explicitly exit or else this process will just sit around after we return. 3601b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci System.exit(0); 3611b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 36208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 36308cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 36408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 36508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static void loadNativeLibrary() { 36608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) if (!sAddressSpaceReserved) { 36708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) Log.e(LOGTAG, "can't load with relro file; address space not reserved"); 36808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) return; 36908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 37008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 37108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) try { 37208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) getUpdateService().waitForRelroCreationCompleted(VMRuntime.getRuntime().is64Bit()); 37308cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } catch (RemoteException e) { 37408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) Log.e(LOGTAG, "error waiting for relro creation, proceeding without", e); 37508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) return; 37608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 37708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 3781b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci try { 3791b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci String[] args = getWebViewNativeLibraryPaths(); 3801b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci boolean result = nativeLoadWithRelroFile(args[0] /* path32 */, 3811b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci args[1] /* path64 */, 3821b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci CHROMIUM_WEBVIEW_NATIVE_RELRO_32, 3831b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci CHROMIUM_WEBVIEW_NATIVE_RELRO_64); 3841b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!result) { 3851b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.w(LOGTAG, "failed to load with relro file, proceeding without"); 3861b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } else if (DEBUG) { 3871b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.v(LOGTAG, "loaded with relro file"); 3881b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 3891b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } catch (PackageManager.NameNotFoundException e) { 3901b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "Failed to list WebView package libraries for loadNativeLibrary", e); 39108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 39208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 39308cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 39408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static IWebViewUpdateService getUpdateService() { 39508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) return IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate")); 39608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 39708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 3985ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch private static native boolean nativeReserveAddressSpace(long addressSpaceToReserve); 39908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static native boolean nativeCreateRelroFile(String lib32, String lib64, 40008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) String relro32, String relro64); 40108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static native boolean nativeLoadWithRelroFile(String lib32, String lib64, 40208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) String relro32, String relro64); 403d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon} 404