diff options
author | mnaganov <mnaganov@chromium.org> | 2015-09-02 10:52:57 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-09-02 17:54:22 +0000 |
commit | 5698e42ca565654da35056bcf03ee42bbf87fd11 (patch) | |
tree | 9cee2f95f57737765ece0e6328df8e6a6470ed2a | |
parent | 1d1a7f7e335710a7a38a2e16631491d63bdddd21 (diff) | |
download | chromium_src-5698e42ca565654da35056bcf03ee42bbf87fd11.zip chromium_src-5698e42ca565654da35056bcf03ee42bbf87fd11.tar.gz chromium_src-5698e42ca565654da35056bcf03ee42bbf87fd11.tar.bz2 |
[Android WebView] Add switch for enabling experimental renderer sandboxing
To run AwShell in this mode (no graphical output):
build/android/adb_android_webview_command_line --webview-sandboxed-renderer
Added a simple test for this mode. The next step will be to run all AW
instrumentation tests like this in addition to normal mode.
BUG=156062,525697
Review URL: https://codereview.chromium.org/1315633003
Cr-Commit-Position: refs/heads/master@{#346963}
16 files changed, 145 insertions, 18 deletions
diff --git a/android_webview/browser/aw_browser_main_parts.cc b/android_webview/browser/aw_browser_main_parts.cc index 1b7f08f..e2bf9a2 100644 --- a/android_webview/browser/aw_browser_main_parts.cc +++ b/android_webview/browser/aw_browser_main_parts.cc @@ -98,8 +98,12 @@ void AwBrowserMainParts::PreMainMessageLoopRun() { content::RenderFrameHost::AllowInjectingJavaScriptForAndroidWebView(); // This is needed for WebView Classic backwards compatibility - // See crbug.com/298495 - content::SetMaxURLChars(20 * 1024 * 1024); + // See crbug.com/298495. Also see crbug.com/525697 on why it is currently + // for single process mode only. + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSingleProcess)) { + content::SetMaxURLChars(20 * 1024 * 1024); + } } bool AwBrowserMainParts::MainMessageLoopRun(int* result_code) { diff --git a/android_webview/browser/aw_content_browser_client.cc b/android_webview/browser/aw_content_browser_client.cc index 6176b93..759c844 100644 --- a/android_webview/browser/aw_content_browser_client.cc +++ b/android_webview/browser/aw_content_browser_client.cc @@ -22,6 +22,7 @@ #include "android_webview/common/url_constants.h" #include "base/android/locale_utils.h" #include "base/base_paths_android.h" +#include "base/command_line.h" #include "base/path_service.h" #include "components/cdm/browser/cdm_message_filter_android.h" #include "content/public/browser/access_token_store.h" @@ -32,6 +33,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" #include "content/public/common/url_constants.h" #include "content/public/common/web_preferences.h" #include "net/android/network_library.h" @@ -244,7 +246,13 @@ std::string AwContentBrowserClient::GetCanonicalEncodingNameByAliasName( void AwContentBrowserClient::AppendExtraCommandLineSwitches( base::CommandLine* command_line, int child_process_id) { - NOTREACHED() << "Android WebView does not support multi-process yet"; + if (command_line->HasSwitch(switches::kSingleProcess)) { + NOTREACHED() << "Android WebView does not support multi-process yet"; + } else { + // The only kind of a child process WebView can have is renderer. + DCHECK_EQ(switches::kRendererProcess, + command_line->GetSwitchValueASCII(switches::kProcessType)); + } } std::string AwContentBrowserClient::GetApplicationLocale() { diff --git a/android_webview/common/aw_switches.cc b/android_webview/common/aw_switches.cc index f9bc2fe..23ed453 100644 --- a/android_webview/common/aw_switches.cc +++ b/android_webview/common/aw_switches.cc @@ -8,5 +8,6 @@ namespace switches { const char kEnablePageVisibility[] = "enable-page-visibility"; const char kUseInProcCommandBuffer[] = "use-in-proc-command-buffer"; +const char kWebViewSanboxedRenderer[] = "webview-sandboxed-renderer"; } // namespace switches diff --git a/android_webview/common/aw_switches.h b/android_webview/common/aw_switches.h index 4dd4a6d..5b3569b 100644 --- a/android_webview/common/aw_switches.h +++ b/android_webview/common/aw_switches.h @@ -9,6 +9,7 @@ namespace switches { extern const char kEnablePageVisibility[]; extern const char kUseInProcCommandBuffer[]; +extern const char kWebViewSanboxedRenderer[]; } // namespace switches diff --git a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java index 7a4b709..0989339 100644 --- a/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java +++ b/android_webview/java/src/org/chromium/android_webview/AwBrowserProcess.java @@ -6,6 +6,7 @@ package org.chromium.android_webview; import android.content.Context; +import org.chromium.base.CommandLine; import org.chromium.base.PathUtils; import org.chromium.base.ThreadUtils; import org.chromium.base.library_loader.LibraryLoader; @@ -55,7 +56,8 @@ public abstract class AwBrowserProcess { public void run() { try { BrowserStartupController.get(context, LibraryProcessType.PROCESS_WEBVIEW) - .startBrowserProcessesSync(true); + .startBrowserProcessesSync(!CommandLine.getInstance().hasSwitch( + AwSwitches.WEBVIEW_SANDBOXED_RENDERER)); } catch (ProcessInitException e) { throw new RuntimeException("Cannot initialize WebView", e); } diff --git a/android_webview/java/src/org/chromium/android_webview/AwSwitches.java b/android_webview/java/src/org/chromium/android_webview/AwSwitches.java new file mode 100644 index 0000000..22a7fda --- /dev/null +++ b/android_webview/java/src/org/chromium/android_webview/AwSwitches.java @@ -0,0 +1,17 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.android_webview; + +/** + * Contains command line switches that are specific to Android WebView. + */ +public abstract class AwSwitches { + // Experimental mode to run renderers in a sandbox, disables kSingleProcess, + // enables kInProcessGPU ans sets kRendererProcessLimit to 1. + // Native switch kWebViewSanboxedRenderer. + public static final String WEBVIEW_SANDBOXED_RENDERER = "webview-sandboxed-renderer"; + + private AwSwitches() {} +} diff --git a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java index 1562b52..3ca6e91 100644 --- a/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java +++ b/android_webview/javatests/src/org/chromium/android_webview/test/AwContentsTest.java @@ -4,6 +4,7 @@ package org.chromium.android_webview.test; +import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; @@ -23,12 +24,18 @@ import org.apache.http.Header; import org.apache.http.HttpRequest; import org.chromium.android_webview.AwContents; import org.chromium.android_webview.AwSettings; +import org.chromium.android_webview.AwSwitches; import org.chromium.android_webview.AwWebViewLifecycleObserver; import org.chromium.android_webview.test.TestAwContentsClient.OnDownloadStartHelper; import org.chromium.android_webview.test.util.CommonResources; +import org.chromium.android_webview.test.util.JSUtils; import org.chromium.base.annotations.SuppressFBWarnings; +import org.chromium.base.test.util.CommandLineFlags; import org.chromium.base.test.util.Feature; import org.chromium.base.test.util.MinAndroidSdkLevel; +import org.chromium.content.browser.BindingManager; +import org.chromium.content.browser.ChildProcessConnection; +import org.chromium.content.browser.ChildProcessLauncher; import org.chromium.content.browser.test.util.CallbackHelper; import org.chromium.content_public.browser.AccessibilitySnapshotCallback; import org.chromium.content_public.browser.AccessibilitySnapshotNode; @@ -547,6 +554,70 @@ public class AwContentsTest extends AwTestBase { script)); } + private static class MockBindingManager implements BindingManager { + private boolean mIsChildProcessCreated; + + boolean isChildProcessCreated() { + return mIsChildProcessCreated; + } + + @Override + public void addNewConnection(int pid, ChildProcessConnection connection) { + mIsChildProcessCreated = true; + } + + @Override + public void setInForeground(int pid, boolean inForeground) {} + + @Override + public void determinedVisibility(int pid) {} + + @Override + public void onSentToBackground() {} + + @Override + public void onBroughtToForeground() {} + + @Override + public boolean isOomProtected(int pid) { + return false; + } + + @Override + public void clearConnection(int pid) {} + + @Override + public void startModerateBindingManagement( + Context context, int maxSize, float lowReduceRatio, float highReduceRatio) {} + + @Override + public void releaseAllModerateBindings() {} + } + + @Feature({"AndroidWebView"}) + @SmallTest + @CommandLineFlags.Add(AwSwitches.WEBVIEW_SANDBOXED_RENDERER) + public void testSandboxedRendererWorks() throws Throwable { + MockBindingManager bindingManager = new MockBindingManager(); + ChildProcessLauncher.setBindingManagerForTesting(bindingManager); + assertFalse(bindingManager.isChildProcessCreated()); + + AwTestContainerView testView = createAwTestContainerViewOnMainSync(mContentsClient); + AwContents awContents = testView.getAwContents(); + final String pageTitle = "I am sandboxed"; + loadDataSync(awContents, mContentsClient.getOnPageFinishedHelper(), + "<html><head><title>" + pageTitle + "</title></head></html>", "text/html", false); + assertEquals(pageTitle, getTitleOnUiThread(awContents)); + + assertTrue(bindingManager.isChildProcessCreated()); + + // Test end-to-end interaction with the renderer. + AwSettings awSettings = getAwSettingsOnUiThread(awContents); + awSettings.setJavaScriptEnabled(true); + assertEquals("42", JSUtils.executeJavaScriptAndWaitForResult(this, awContents, + mContentsClient.getOnEvaluateJavaScriptResultHelper(), "21 + 21")); + } + private static class AccessibilityCallbackHelper extends CallbackHelper { private AccessibilitySnapshotNode mRoot; diff --git a/android_webview/lib/main/aw_main_delegate.cc b/android_webview/lib/main/aw_main_delegate.cc index ee52b20..37f044b 100644 --- a/android_webview/lib/main/aw_main_delegate.cc +++ b/android_webview/lib/main/aw_main_delegate.cc @@ -136,6 +136,11 @@ bool AwMainDelegate::BasicStartupComplete(int* exit_code) { kV8SnapshotDataDescriptor, kSnapshotFileName)); } + if (cl->HasSwitch(switches::kWebViewSanboxedRenderer)) { + cl->AppendSwitch(switches::kInProcessGPU); + cl->AppendSwitchASCII(switches::kRendererProcessLimit, "1"); + } + return false; } diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc index b78ba79..10c21da 100644 --- a/android_webview/native/aw_contents.cc +++ b/android_webview/native/aw_contents.cc @@ -40,6 +40,7 @@ #include "base/atomicops.h" #include "base/bind.h" #include "base/callback.h" +#include "base/command_line.h" #include "base/memory/memory_pressure_listener.h" #include "base/message_loop/message_loop.h" #include "base/pickle.h" @@ -62,6 +63,7 @@ #include "content/public/browser/render_process_host.h" #include "content/public/browser/render_view_host.h" #include "content/public/browser/web_contents.h" +#include "content/public/common/content_switches.h" #include "content/public/common/message_port_types.h" #include "content/public/common/renderer_preferences.h" #include "content/public/common/ssl_status.h" @@ -204,8 +206,12 @@ AwContents::AwContents(scoped_ptr<WebContents> web_contents) InitDataReductionProxyIfNecessary(); if (autofill_manager_delegate) InitAutofillIfNecessary(autofill_manager_delegate->GetSaveFormData()); - content::SynchronousCompositor::SetClientForWebContents( - web_contents_.get(), &browser_view_renderer_); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSingleProcess)) { + // TODO(boliu): Figure out how to deal with this more nicely. + content::SynchronousCompositor::SetClientForWebContents( + web_contents_.get(), &browser_view_renderer_); + } if (current_instance_count == 1) AwWebViewLifecycleObserver::OnFirstWebViewCreated(); } diff --git a/android_webview/test/shell/AndroidManifest.xml b/android_webview/test/shell/AndroidManifest.xml index b34de62..dbfa31a 100644 --- a/android_webview/test/shell/AndroidManifest.xml +++ b/android_webview/test/shell/AndroidManifest.xml @@ -37,5 +37,13 @@ </activity> <provider android:name="org.chromium.android_webview.test.TestContentProvider" android:authorities="org.chromium.android_webview.test.TestContentProvider" /> + <meta-data android:name="org.chromium.content.browser.NUM_SANDBOXED_SERVICES" + android:value="1"/> + <service android:name="org.chromium.content.app.SandboxedProcessService0" + android:process=":sandboxed_process0" + android:isolatedProcess="true" + android:exported="false" /> + <meta-data android:name="org.chromium.content.browser.NUM_PRIVILEGED_SERVICES" + android:value="0"/> </application> </manifest> diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java index e566441..0039ea2 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeSwitches.java @@ -91,12 +91,6 @@ public abstract class ChromeSwitches { /////////////////////////////////////////////////////////////////////////////////////////////// /** - * Sets the max number of render processes to use. - * Native switch - content_switches::kRendererProcessLimit. - */ - public static final String RENDER_PROCESS_LIMIT = "renderer-process-limit"; - - /** * Enable enhanced bookmarks feature. * Native switch - switches::kEnhancedBookmarksExperiment */ diff --git a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java index 97a5a03..2a9818b 100644 --- a/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java +++ b/chrome/android/java/src/org/chromium/chrome/browser/ChromeTabbedActivity.java @@ -746,7 +746,7 @@ public class ChromeTabbedActivity extends ChromeActivity implements OverviewMode ChromeTabbedActivity.INTENT_EXTRA_TEST_RENDER_PROCESS_LIMIT, -1); if (value != -1) { String[] args = new String[1]; - args[0] = "--" + ChromeSwitches.RENDER_PROCESS_LIMIT + args[0] = "--" + ContentSwitches.RENDER_PROCESS_LIMIT + "=" + Integer.toString(value); commandLine.appendSwitchesAndArguments(args); } diff --git a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc index 220c8624..3a8fa4d 100644 --- a/content/browser/android/in_process/synchronous_compositor_factory_impl.cc +++ b/content/browser/android/in_process/synchronous_compositor_factory_impl.cc @@ -19,12 +19,12 @@ #include "content/gpu/in_process_gpu_thread.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/gpu_data_manager.h" +#include "content/public/common/content_switches.h" #include "content/renderer/gpu/frame_swap_message_queue.h" #include "content/renderer/render_thread_impl.h" #include "gpu/blink/webgraphicscontext3d_in_process_command_buffer_impl.h" #include "gpu/command_buffer/client/gl_in_process_context.h" #include "gpu/command_buffer/common/gles2_cmd_utils.h" -#include "gpu/command_buffer/service/gpu_switches.h" #include "ui/gl/android/surface_texture.h" #include "ui/gl/gl_surface.h" #include "ui/gl/gl_surface_stub.h" @@ -149,7 +149,11 @@ SynchronousCompositorFactoryImpl::SynchronousCompositorFactoryImpl() : record_full_layer_(true), use_ipc_command_buffer_(false), num_hardware_compositors_(0) { - SynchronousCompositorFactory::SetInstance(this); + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kSingleProcess)) { + // TODO(boliu): Figure out how to deal with this more nicely. + SynchronousCompositorFactory::SetInstance(this); + } } SynchronousCompositorFactoryImpl::~SynchronousCompositorFactoryImpl() {} diff --git a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java index ab4c60d..ee4d63a 100644 --- a/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java +++ b/content/public/android/java/src/org/chromium/content/browser/ChildProcessLauncher.java @@ -232,7 +232,7 @@ public class ChildProcessLauncher { ApplicationInfo appInfo = packageManager.getApplicationInfo(context.getPackageName(), PackageManager.GET_META_DATA); int numServices = appInfo.metaData.getInt(inSandbox ? NUM_SANDBOXED_SERVICES_KEY - : NUM_PRIVILEGED_SERVICES_KEY); + : NUM_PRIVILEGED_SERVICES_KEY, -1); if (inSandbox && CommandLine.getInstance().hasSwitch( SWITCH_NUM_SANDBOXED_SERVICES_FOR_TESTING)) { @@ -247,7 +247,7 @@ public class ChildProcessLauncher { } } } - if (numServices <= 0) { + if (numServices < 0) { throw new RuntimeException("Illegal meta data value for number of child services"); } return numServices; diff --git a/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java b/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java index 0c29fc7..79e2999 100644 --- a/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java +++ b/content/public/android/java/src/org/chromium/content/common/ContentSwitches.java @@ -73,6 +73,12 @@ public abstract class ContentSwitches { public static final String DISABLE_GESTURE_REQUIREMENT_FOR_MEDIA_PLAYBACK = "disable-gesture-requirement-for-media-playback"; + // Native switch kRendererProcessLimit + public static final String RENDER_PROCESS_LIMIT = "renderer-process-limit"; + + // Native switch kInProcessGPU + public static final String IN_PROCESS_GPU = "in-process-gpu"; + // Prevent instantiation. private ContentSwitches() {} } diff --git a/content/public/common/content_switches.h b/content/public/common/content_switches.h index c64b9c4..8c6e983 100644 --- a/content/public/common/content_switches.h +++ b/content/public/common/content_switches.h @@ -166,7 +166,7 @@ extern const char kGpuVendorID[]; CONTENT_EXPORT extern const char kHostResolverRules[]; CONTENT_EXPORT extern const char kIgnoreCertificateErrors[]; CONTENT_EXPORT extern const char kIgnoreGpuBlacklist[]; -extern const char kInProcessGPU[]; +CONTENT_EXPORT extern const char kInProcessGPU[]; CONTENT_EXPORT extern const char kIPCConnectionTimeout[]; CONTENT_EXPORT extern const char kJavaScriptFlags[]; extern const char kLoadPlugin[]; |