diff options
| author | Robert Sesek <rsesek@google.com> | 2016-08-15 13:59:13 -0400 |
|---|---|---|
| committer | Robert Sesek <rsesek@google.com> | 2016-10-07 12:38:04 -0400 |
| commit | ded209843616a98e6f97db0d1784f6d630cbd5e9 (patch) | |
| tree | d69dea3c34d621bdb0ed34120a44bf7614301169 /core/java/android/webkit/WebViewZygote.java | |
| parent | 07bc1ee77d6dc84e0d5ba59b29a2acf4b53c2368 (diff) | |
Create the WebViewZygote and implement WebViewZygoteInit.
This adds a new init-spawned daemon, webview_zygote, that starts a JVM and
acts as a zygote process for WebView isolated_app services.
Test: m
Test: angler boots
Test: Turn on Settings>Developer>Multiprocess Webview. webview_zygote32 or
webview_zygote64 start (requires dependent CLs).
Bug: 21643067
Change-Id: Ida98bd04b4d77736b672b03af651c4eb97ce88c1
Diffstat (limited to 'core/java/android/webkit/WebViewZygote.java')
| -rw-r--r-- | core/java/android/webkit/WebViewZygote.java | 135 |
1 files changed, 135 insertions, 0 deletions
diff --git a/core/java/android/webkit/WebViewZygote.java b/core/java/android/webkit/WebViewZygote.java new file mode 100644 index 000000000000..bc6e7b4a9dd3 --- /dev/null +++ b/core/java/android/webkit/WebViewZygote.java @@ -0,0 +1,135 @@ +/* + * Copyright (C) 2016 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package android.webkit; + +import android.content.pm.PackageInfo; +import android.os.Build; +import android.os.SystemService; +import android.os.ZygoteProcess; +import android.util.Log; + +import java.io.IOException; +import java.util.Arrays; +import java.util.concurrent.TimeoutException; + +/** @hide */ +public class WebViewZygote { + private static final String LOGTAG = "WebViewZygote"; + + private static final String WEBVIEW_ZYGOTE_SERVICE_32 = "webview_zygote32"; + private static final String WEBVIEW_ZYGOTE_SERVICE_64 = "webview_zygote64"; + + private static ZygoteProcess sZygote; + + private static PackageInfo sPackage; + + private static boolean sMultiprocessEnabled = false; + + public static ZygoteProcess getProcess() { + connectToZygoteIfNeeded(); + return sZygote; + } + + public static String getPackageName() { + return sPackage.packageName; + } + + public static void setMultiprocessEnabled(boolean enabled) { + sMultiprocessEnabled = enabled; + + // When toggling between multi-process being on/off, start or stop the + // service. If it is enabled and the zygote is not yet started, bring up the service. + // Otherwise, bring down the service. The name may be null if the package + // information has not yet been resolved. + final String serviceName = getServiceName(); + if (serviceName == null) return; + + if (enabled && sZygote == null) { + SystemService.start(serviceName); + } else { + SystemService.stop(serviceName); + sZygote = null; + } + } + + public static void onWebViewProviderChanged(PackageInfo packageInfo) { + sPackage = packageInfo; + + // If multi-process is not enabled, then do not start the zygote service. + if (!sMultiprocessEnabled) { + return; + } + + final String serviceName = getServiceName(); + + if (SystemService.isStopped(serviceName)) { + SystemService.start(serviceName); + } else if (sZygote != null) { + SystemService.restart(serviceName); + } + + try { + SystemService.waitForState(serviceName, SystemService.State.RUNNING, 5000); + } catch (TimeoutException e) { + Log.e(LOGTAG, "Timed out waiting for " + serviceName); + return; + } + + connectToZygoteIfNeeded(); + } + + private static String getServiceName() { + if (sPackage == null) + return null; + + if (Arrays.asList(Build.SUPPORTED_64_BIT_ABIS).contains( + sPackage.applicationInfo.primaryCpuAbi)) { + return WEBVIEW_ZYGOTE_SERVICE_64; + } + + return WEBVIEW_ZYGOTE_SERVICE_32; + } + + private static void connectToZygoteIfNeeded() { + if (sZygote != null) + return; + + if (sPackage == null) { + Log.e(LOGTAG, "Cannot connect to zygote, no package specified"); + return; + } + + final String serviceName = getServiceName(); + if (!SystemService.isRunning(serviceName)) { + Log.e(LOGTAG, serviceName + " is not running"); + return; + } + + try { + sZygote = new ZygoteProcess("webview_zygote", null); + + String packagePath = sPackage.applicationInfo.sourceDir; + String libsPath = sPackage.applicationInfo.nativeLibraryDir; + + Log.d(LOGTAG, "Preloading package " + packagePath + " " + libsPath); + sZygote.preloadPackageForAbi(packagePath, libsPath, Build.SUPPORTED_ABIS[0]); + } catch (Exception e) { + Log.e(LOGTAG, "Error connecting to " + serviceName, e); + sZygote = null; + } + } +} |
