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; 7584392d74fef177a87bc96a255761daf39569e726Torne (Richard Coles) private static PackageInfo sPackageInfo; 76d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 77dc00a84af15ff3594a6dfa512be21095bf9fee82Ben Murdoch public static String getWebViewPackageName() { 785651fc2feeed3af1bd0991e32788a8936d698811Torne (Richard Coles) return AppGlobals.getInitialApplication().getString( 795651fc2feeed3af1bd0991e32788a8936d698811Torne (Richard Coles) com.android.internal.R.string.config_webViewPackageName); 80dc00a84af15ff3594a6dfa512be21095bf9fee82Ben Murdoch } 81dc00a84af15ff3594a6dfa512be21095bf9fee82Ben Murdoch 8284392d74fef177a87bc96a255761daf39569e726Torne (Richard Coles) public static PackageInfo getLoadedPackageInfo() { 8384392d74fef177a87bc96a255761daf39569e726Torne (Richard Coles) return sPackageInfo; 8484392d74fef177a87bc96a255761daf39569e726Torne (Richard Coles) } 8584392d74fef177a87bc96a255761daf39569e726Torne (Richard Coles) 869f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck static WebViewFactoryProvider getProvider() { 879f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck synchronized (sProviderLock) { 889f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck // For now the main purpose of this function (and the factory abstraction) is to keep 89d892afc88d3c67a7fe1c9550bfa7a452051d031dTorne (Richard Coles) // us honest and minimize usage of WebView internals when binding the proxy. 909f9d34552f53c534141584a5ad4a8a49ad7939dcJohn Reck if (sProviderInstance != null) return sProviderInstance; 91d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 923822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getProvider()"); 9303ce9b3e69f1eec85e7e7cbfd65bb9093e74cea8Torne (Richard Coles) try { 943822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.loadNativeLibrary()"); 953822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) loadNativeLibrary(); 963822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 973822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) 983822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Class<WebViewFactoryProvider> providerClass; 993822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "WebViewFactory.getFactoryClass()"); 1003822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) try { 1013822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) providerClass = getFactoryClass(); 1023822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } catch (ClassNotFoundException e) { 1033822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Log.e(LOGTAG, "error loading provider", e); 1043822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) throw new AndroidRuntimeException(e); 1053822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } finally { 1063822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 1073822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } 1083822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) 1093822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads(); 1103822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "providerClass.newInstance()"); 1113822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) try { 1123822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) sProviderInstance = providerClass.newInstance(); 1133822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) if (DEBUG) Log.v(LOGTAG, "Loaded provider: " + sProviderInstance); 1143822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) return sProviderInstance; 1153822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } catch (Exception e) { 1163822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Log.e(LOGTAG, "error instantiating provider", e); 1173822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) throw new AndroidRuntimeException(e); 1183822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } finally { 1193822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 1203822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) StrictMode.setThreadPolicy(oldPolicy); 1213822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } 12203ce9b3e69f1eec85e7e7cbfd65bb9093e74cea8Torne (Richard Coles) } finally { 1233822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 124e09e976dad1d974ca28381451b0bbbeafbb872d5Ben Murdoch } 125d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon } 126d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon } 127d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon 12803ce9b3e69f1eec85e7e7cbfd65bb9093e74cea8Torne (Richard Coles) private static Class<WebViewFactoryProvider> getFactoryClass() throws ClassNotFoundException { 12963d3d8a458cfc124ebd183994d3d152d3b06c1d8Marcin Kosiba Application initialApplication = AppGlobals.getInitialApplication(); 1300e04bcfbdc1845c931b45b3498aef438b944e961Ben Murdoch try { 1310606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) // First fetch the package info so we can log the webview package version. 1320606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) String packageName = getWebViewPackageName(); 13384392d74fef177a87bc96a255761daf39569e726Torne (Richard Coles) sPackageInfo = initialApplication.getPackageManager().getPackageInfo(packageName, 0); 13484392d74fef177a87bc96a255761daf39569e726Torne (Richard Coles) Log.i(LOGTAG, "Loading " + packageName + " version " + sPackageInfo.versionName + 13584392d74fef177a87bc96a255761daf39569e726Torne (Richard Coles) " (code " + sPackageInfo.versionCode + ")"); 1360606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) 1370606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) // Construct a package context to load the Java code into the current app. 1380606cd572ad345fb2c40456509feac626c68dee3Torne (Richard Coles) Context webViewContext = initialApplication.createPackageContext(packageName, 1396c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles) Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY); 14063d3d8a458cfc124ebd183994d3d152d3b06c1d8Marcin Kosiba initialApplication.getAssets().addAssetPath( 14163d3d8a458cfc124ebd183994d3d152d3b06c1d8Marcin Kosiba webViewContext.getApplicationInfo().sourceDir); 1426c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles) ClassLoader clazzLoader = webViewContext.getClassLoader(); 1433822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceBegin(Trace.TRACE_TAG_WEBVIEW, "Class.forName()"); 1443822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) try { 1453822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) return (Class<WebViewFactoryProvider>) Class.forName(CHROMIUM_WEBVIEW_FACTORY, true, 1463822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) clazzLoader); 1473822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } finally { 1483822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) Trace.traceEnd(Trace.TRACE_TAG_WEBVIEW); 1493822882b32d9b1b803aaff9b657a91d680f1d0f9Torne (Richard Coles) } 1506c778cebc73e7eb76510f6e2183d804b8c07082bTorne (Richard Coles) } catch (PackageManager.NameNotFoundException e) { 1515f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // If the package doesn't exist, then try loading the null WebView instead. 1525f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // If that succeeds, then this is a device without WebView support; if it fails then 1535f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // swallow the failure, complain that the real WebView is missing and rethrow the 1545f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // original exception. 1555f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) try { 1565f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) return (Class<WebViewFactoryProvider>) Class.forName(NULL_WEBVIEW_FACTORY); 1575f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) } catch (ClassNotFoundException e2) { 1585f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) // Ignore. 1595f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) } 1605f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) Log.e(LOGTAG, "Chromium WebView package does not exist", e); 1615f3278ba1e7572d4a5624d18fd08ba9038abc575Torne (Richard Coles) throw new AndroidRuntimeException(e); 1620e04bcfbdc1845c931b45b3498aef438b944e961Ben Murdoch } 163d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon } 16408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 16508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) /** 16608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * Perform any WebView loading preparations that must happen in the zygote. 16708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * Currently, this means allocating address space to load the real JNI library later. 16808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) */ 16908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) public static void prepareWebViewInZygote() { 17008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) try { 17108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) System.loadLibrary("webviewchromium_loader"); 1725ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch long addressSpaceToReserve = 1735ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch SystemProperties.getLong(CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY, 1745ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES); 1755ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch sAddressSpaceReserved = nativeReserveAddressSpace(addressSpaceToReserve); 1765ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 17708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) if (sAddressSpaceReserved) { 1785ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (DEBUG) { 1795ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch Log.v(LOGTAG, "address space reserved: " + addressSpaceToReserve + " bytes"); 1805ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 18108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } else { 1825ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch Log.e(LOGTAG, "reserving " + addressSpaceToReserve + 1835ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch " bytes of address space failed"); 18408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 185810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } catch (Throwable t) { 18608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) // Log and discard errors at this stage as we must not crash the zygote. 187810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Log.e(LOGTAG, "error preparing native loader", t); 18808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 18908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 19008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 19108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) /** 19208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * Perform any WebView loading preparations that must happen at boot from the system server, 1935ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch * after the package manager has started or after an update to the webview is installed. 19408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * This must be called in the system server. 19508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) * Currently, this means spawning the child processes which will create the relro files. 19608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) */ 19708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) public static void prepareWebViewInSystemServer() { 1985ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch String[] nativePaths = null; 1995ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch try { 2005ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch nativePaths = getWebViewNativeLibraryPaths(); 20127cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) } catch (Throwable t) { 20227cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // Log and discard errors at this stage as we must not crash the system server. 20327cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Log.e(LOGTAG, "error preparing webview native library", t); 2045ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2055ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch prepareWebViewInSystemServer(nativePaths); 2065ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2075ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 2085ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch private static void prepareWebViewInSystemServer(String[] nativeLibraryPaths) { 20908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) if (DEBUG) Log.v(LOGTAG, "creating relro files"); 2105ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 2115ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch // We must always trigger createRelRo regardless of the value of nativeLibraryPaths. Any 2125ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch // unexpected values will be handled there to ensure that we trigger notifying any process 2135ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch // waiting on relreo creation. 2145ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { 2155ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (DEBUG) Log.v(LOGTAG, "Create 32 bit relro"); 2165ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch createRelroFile(false /* is64Bit */, nativeLibraryPaths); 2175ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2185ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 2195ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { 2205ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (DEBUG) Log.v(LOGTAG, "Create 64 bit relro"); 2215ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch createRelroFile(true /* is64Bit */, nativeLibraryPaths); 2225ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2235ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2245ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 2255ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch public static void onWebViewUpdateInstalled() { 2265ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch String[] nativeLibs = null; 2275ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch try { 2285ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch nativeLibs = WebViewFactory.getWebViewNativeLibraryPaths(); 22927cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (nativeLibs != null) { 23027cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) long newVmSize = 0L; 23127cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) 23227cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) for (String path : nativeLibs) { 23327cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (DEBUG) Log.d(LOGTAG, "Checking file size of " + path); 23427cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (path == null) continue; 23527cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) File f = new File(path); 23627cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (f.exists()) { 23727cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) long length = f.length(); 23827cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (length > newVmSize) { 23927cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) newVmSize = length; 24027cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) } 2415ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2425ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 2435ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch 24427cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) if (DEBUG) { 24527cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Log.v(LOGTAG, "Based on library size, need " + newVmSize + 24627cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) " bytes of address space."); 24727cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) } 24827cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // The required memory can be larger than the file on disk (due to .bss), and an 24927cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // upgraded version of the library will likely be larger, so always attempt to 25027cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // reserve twice as much as we think to allow for the library to grow during this 25127cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // boot cycle. 25227cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) newVmSize = Math.max(2 * newVmSize, CHROMIUM_WEBVIEW_DEFAULT_VMSIZE_BYTES); 25327cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Log.d(LOGTAG, "Setting new address space to " + newVmSize); 25427cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) SystemProperties.set(CHROMIUM_WEBVIEW_VMSIZE_SIZE_PROPERTY, 25527cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Long.toString(newVmSize)); 2565ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 25727cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) } catch (Throwable t) { 25827cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) // Log and discard errors at this stage as we must not crash the system server. 25927cb0d22a839f9fc132ae6b4e7c059c75a1826e1Torne (Richard Coles) Log.e(LOGTAG, "error preparing webview native library", t); 26008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 2615ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch prepareWebViewInSystemServer(nativeLibs); 26208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 26308cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 2641b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci private static String[] getWebViewNativeLibraryPaths() 2651b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci throws PackageManager.NameNotFoundException { 2661b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci final String NATIVE_LIB_FILE_NAME = "libwebviewchromium.so"; 2671b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci 2681b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci PackageManager pm = AppGlobals.getInitialApplication().getPackageManager(); 2691b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci ApplicationInfo ai = pm.getApplicationInfo(getWebViewPackageName(), 0); 2701b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci 2711b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci String path32; 2721b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci String path64; 2731b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci boolean primaryArchIs64bit = VMRuntime.is64BitAbi(ai.primaryCpuAbi); 2741b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!TextUtils.isEmpty(ai.secondaryCpuAbi)) { 2751b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Multi-arch case. 2761b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (primaryArchIs64bit) { 2771b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Primary arch: 64-bit, secondary: 32-bit. 2781b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path64 = ai.nativeLibraryDir; 2791b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path32 = ai.secondaryNativeLibraryDir; 2801b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } else { 2811b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Primary arch: 32-bit, secondary: 64-bit. 2821b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path64 = ai.secondaryNativeLibraryDir; 2831b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path32 = ai.nativeLibraryDir; 2841b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 2851b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } else if (primaryArchIs64bit) { 2861b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Single-arch 64-bit. 2871b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path64 = ai.nativeLibraryDir; 2881b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path32 = ""; 2891b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } else { 2901b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Single-arch 32-bit. 2911b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path32 = ai.nativeLibraryDir; 2921b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci path64 = ""; 2931b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 2941b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!TextUtils.isEmpty(path32)) path32 += "/" + NATIVE_LIB_FILE_NAME; 2951b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!TextUtils.isEmpty(path64)) path64 += "/" + NATIVE_LIB_FILE_NAME; 2961b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci return new String[] { path32, path64 }; 2971b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 2981b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci 2995ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch private static void createRelroFile(final boolean is64Bit, String[] nativeLibraryPaths) { 3001b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci final String abi = 3011b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci is64Bit ? Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; 302810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci 303810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci // crashHandler is invoked by the ActivityManagerService when the isolated process crashes. 304810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Runnable crashHandler = new Runnable() { 305810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci @Override 306810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci public void run() { 307810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci try { 3081b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "relro file creator for " + abi + " crashed. Proceeding without"); 309810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci getUpdateService().notifyRelroCreationCompleted(is64Bit, false); 310810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } catch (RemoteException e) { 311810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Log.e(LOGTAG, "Cannot reach WebViewUpdateService. " + e.getMessage()); 312810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } 313810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } 314810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci }; 315810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci 31608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) try { 3175ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch if (nativeLibraryPaths == null 3185ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch || nativeLibraryPaths[0] == null || nativeLibraryPaths[1] == null) { 3195ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch throw new IllegalArgumentException( 3205ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch "Native library paths to the WebView RelRo process must not be null!"); 3215ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch } 322161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci int pid = LocalServices.getService(ActivityManagerInternal.class).startIsolatedProcess( 3235ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch RelroFileCreator.class.getName(), nativeLibraryPaths, "WebViewLoader-" + abi, abi, 324810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Process.SHARED_RELRO_UID, crashHandler); 325e76e81a227a29db5223d231ec88ecb02fa4d6835Primiano Tucci if (pid <= 0) throw new Exception("Failed to start the relro file creator process"); 326810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci } catch (Throwable t) { 32708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) // Log and discard errors as we must not crash the system server. 328810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci Log.e(LOGTAG, "error starting relro file creator for abi " + abi, t); 329810c052d9b117217152c2a609ccec056a2a61d1ePrimiano Tucci crashHandler.run(); 33008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 33108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 33208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 33308cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static class RelroFileCreator { 33408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) // Called in an unprivileged child process to create the relro file. 33508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) public static void main(String[] args) { 336161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci boolean result = false; 337161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci boolean is64Bit = VMRuntime.getRuntime().is64Bit(); 3381b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci try{ 3391b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (args.length != 2 || args[0] == null || args[1] == null) { 3401b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "Invalid RelroFileCreator args: " + Arrays.toString(args)); 3411b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci return; 3421b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 3431b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.v(LOGTAG, "RelroFileCreator (64bit = " + is64Bit + "), " + 3441b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci " 32-bit lib: " + args[0] + ", 64-bit lib: " + args[1]); 3451b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!sAddressSpaceReserved) { 3461b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "can't create relro file; address space not reserved"); 3471b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci return; 3481b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 349161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci result = nativeCreateRelroFile(args[0] /* path32 */, 350161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci args[1] /* path64 */, 351161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci CHROMIUM_WEBVIEW_NATIVE_RELRO_32, 352161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci CHROMIUM_WEBVIEW_NATIVE_RELRO_64); 353e76e81a227a29db5223d231ec88ecb02fa4d6835Primiano Tucci if (result && DEBUG) Log.v(LOGTAG, "created relro file"); 354161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci } finally { 355161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci // We must do our best to always notify the update service, even if something fails. 3561b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci try { 3571b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci getUpdateService().notifyRelroCreationCompleted(is64Bit, result); 3581b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } catch (RemoteException e) { 3591b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "error notifying update service", e); 3601b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 361161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci 362161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci if (!result) Log.e(LOGTAG, "failed to create relro file"); 363161536b5970ba5ab43233e7695ef69ba2bb804f4Primiano Tucci 3641b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci // Must explicitly exit or else this process will just sit around after we return. 3651b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci System.exit(0); 3661b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 36708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 36808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 36908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 37008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static void loadNativeLibrary() { 37108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) if (!sAddressSpaceReserved) { 37208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) Log.e(LOGTAG, "can't load with relro file; address space not reserved"); 37308cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) return; 37408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 37508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 37608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) try { 37708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) getUpdateService().waitForRelroCreationCompleted(VMRuntime.getRuntime().is64Bit()); 37808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } catch (RemoteException e) { 37908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) Log.e(LOGTAG, "error waiting for relro creation, proceeding without", e); 38008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) return; 38108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 38208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 3831b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci try { 3841b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci String[] args = getWebViewNativeLibraryPaths(); 3851b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci boolean result = nativeLoadWithRelroFile(args[0] /* path32 */, 3861b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci args[1] /* path64 */, 3871b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci CHROMIUM_WEBVIEW_NATIVE_RELRO_32, 3881b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci CHROMIUM_WEBVIEW_NATIVE_RELRO_64); 3891b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci if (!result) { 3901b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.w(LOGTAG, "failed to load with relro file, proceeding without"); 3911b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } else if (DEBUG) { 3921b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.v(LOGTAG, "loaded with relro file"); 3931b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } 3941b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci } catch (PackageManager.NameNotFoundException e) { 3951b7977b608cd07366a1708aba36d48203f85bbbdPrimiano Tucci Log.e(LOGTAG, "Failed to list WebView package libraries for loadNativeLibrary", e); 39608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 39708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 39808cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 39908cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static IWebViewUpdateService getUpdateService() { 40008cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) return IWebViewUpdateService.Stub.asInterface(ServiceManager.getService("webviewupdate")); 40108cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) } 40208cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) 4035ced502fba5a69dc1d2e55b3d7e5fd429280d6aeBen Murdoch private static native boolean nativeReserveAddressSpace(long addressSpaceToReserve); 40408cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static native boolean nativeCreateRelroFile(String lib32, String lib64, 40508cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) String relro32, String relro64); 40608cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) private static native boolean nativeLoadWithRelroFile(String lib32, String lib64, 40708cfaf672604422dd355d6703aec78f3aa5ee74eTorne (Richard Coles) String relro32, String relro64); 408d3101b1d300f5942fdb7dfa323dc8830c4edc007Jonathan Dixon} 409