Commit 3d7205ae authored by ppi@chromium.org's avatar ppi@chromium.org

Drop memory class-based renderer limit on Android.

This patch removes the automatic renderer-process limit on Android, moving the
consumers to MAX_RENDERERS_LIMIT instead.

This does not affect the number of renderers being spawned yet, but will allow
the consumers to use all available renderers once MAX_RENDERERS_LIMIT is
lifted.

BUG=241787

Review URL: https://chromiumcodereview.appspot.com/17450020

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@208095 0039d316-1c4b-4281-b951-d872f2087c98
parent b838eeae
...@@ -59,7 +59,7 @@ public class ChromiumTestShellActivity extends ChromiumActivity { ...@@ -59,7 +59,7 @@ public class ChromiumTestShellActivity extends ChromiumActivity {
DeviceUtils.addDeviceSpecificUserAgentSwitch(this); DeviceUtils.addDeviceSpecificUserAgentSwitch(this);
try { try {
AndroidBrowserProcess.init(this, AndroidBrowserProcess.MAX_RENDERERS_AUTOMATIC); AndroidBrowserProcess.init(this, AndroidBrowserProcess.MAX_RENDERERS_LIMIT);
} catch (ProcessInitException e) { } catch (ProcessInitException e) {
Log.e(TAG, "Chromium browser process initialization failed", e); Log.e(TAG, "Chromium browser process initialization failed", e);
finish(); finish();
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -13,35 +13,13 @@ import org.chromium.content.app.ContentMain; ...@@ -13,35 +13,13 @@ import org.chromium.content.app.ContentMain;
import org.chromium.content.app.LibraryLoader; import org.chromium.content.app.LibraryLoader;
import org.chromium.content.common.ProcessInitException; import org.chromium.content.common.ProcessInitException;
// NOTE: This file hasn't been fully upstreamed, please don't merge to downstream.
@JNINamespace("content") @JNINamespace("content")
public class AndroidBrowserProcess { public class AndroidBrowserProcess {
private static final String TAG = "BrowserProcessMain"; private static final String TAG = "BrowserProcessMain";
// Prevents initializing the process more than once. // Prevents initializing the process more than once.
private static boolean sInitialized = false; private static boolean sInitialized = false;
// Computes the actual max renderer processes used.
private static int normalizeMaxRendererProcesses(Context context, int maxRendererProcesses) {
if (maxRendererProcesses == MAX_RENDERERS_AUTOMATIC) {
// We use the device's memory class to decide the maximum renderer
// processes. For the baseline devices the memory class is 16 and we will
// limit it to one render process. For the devices with memory class 24,
// we allow two render processes.
ActivityManager am = (ActivityManager)context.getSystemService(
Context.ACTIVITY_SERVICE);
maxRendererProcesses = Math.max(((am.getMemoryClass() - 8) / 8), 1);
}
if (maxRendererProcesses > MAX_RENDERERS_LIMIT) {
Log.w(TAG, "Excessive maxRendererProcesses value: " + maxRendererProcesses);
return MAX_RENDERERS_LIMIT;
}
return Math.max(0, maxRendererProcesses);
}
// Automatically decide the number of renderer processes to use based on device memory class.
public static final int MAX_RENDERERS_AUTOMATIC = -1;
// Use single-process mode that runs the renderer on a separate thread in the main application. // Use single-process mode that runs the renderer on a separate thread in the main application.
public static final int MAX_RENDERERS_SINGLE_PROCESS = 0; public static final int MAX_RENDERERS_SINGLE_PROCESS = 0;
...@@ -64,39 +42,36 @@ public class AndroidBrowserProcess { ...@@ -64,39 +42,36 @@ public class AndroidBrowserProcess {
* @param maxRendererProcesses Limit on the number of renderers to use. Each tab runs in its own * @param maxRendererProcesses Limit on the number of renderers to use. Each tab runs in its own
* process until the maximum number of processes is reached. The special value of * process until the maximum number of processes is reached. The special value of
* MAX_RENDERERS_SINGLE_PROCESS requests single-process mode where the renderer will run in the * MAX_RENDERERS_SINGLE_PROCESS requests single-process mode where the renderer will run in the
* application process in a separate thread. If the special value MAX_RENDERERS_AUTOMATIC is * application process in a separate thread. The maximum number of allowed renderers is capped
* used then the number of renderers will be determined based on the device memory class. The * by MAX_RENDERERS_LIMIT.
* maximum number of allowed renderers is capped by MAX_RENDERERS_LIMIT. *
* @return Whether the process actually needed to be initialized (false if already running). * @return Whether the process actually needed to be initialized (false if already running).
*/ */
public static boolean init(Context context, int maxRendererProcesses) public static boolean init(Context context, int maxRendererProcesses)
throws ProcessInitException { throws ProcessInitException {
assert maxRendererProcesses >= 0;
assert maxRendererProcesses <= MAX_RENDERERS_LIMIT;
if (sInitialized) return false; if (sInitialized) return false;
sInitialized = true; sInitialized = true;
Log.i(TAG, "Initializing chromium process, renderers=" + maxRendererProcesses);
// Normally Main.java will have kicked this off asynchronously for Chrome. But // Normally Main.java will have kicked this off asynchronously for Chrome. But other
// other ContentView apps like tests also need them so we make sure we've // ContentView apps like tests also need them so we make sure we've extracted resources
// extracted resources here. We can still make it a little async (wait until // here. We can still make it a little async (wait until the library is loaded).
// the library is loaded).
ResourceExtractor resourceExtractor = ResourceExtractor.get(context); ResourceExtractor resourceExtractor = ResourceExtractor.get(context);
resourceExtractor.startExtractingResources(); resourceExtractor.startExtractingResources();
// Normally Main.java will have already loaded the library asynchronously, we only // Normally Main.java will have already loaded the library asynchronously, we only need to
// need to load it here if we arrived via another flow, e.g. bookmark access & sync setup. // load it here if we arrived via another flow, e.g. bookmark access & sync setup.
LibraryLoader.ensureInitialized(); LibraryLoader.ensureInitialized();
// TODO(yfriedman): Remove dependency on a command line flag for this. // TODO(yfriedman): Remove dependency on a command line flag for this.
DeviceUtils.addDeviceSpecificUserAgentSwitch(context); DeviceUtils.addDeviceSpecificUserAgentSwitch(context);
Context appContext = context.getApplicationContext(); Context appContext = context.getApplicationContext();
int maxRenderers = normalizeMaxRendererProcesses(appContext, maxRendererProcesses);
Log.i(TAG, "Initializing chromium process, renderers=" + maxRenderers);
// Now we really need to have the resources ready. // Now we really need to have the resources ready.
resourceExtractor.waitForCompletion(); resourceExtractor.waitForCompletion();
nativeSetCommandLineFlags(maxRenderers, nativeSetCommandLineFlags(maxRendererProcesses,
nativeIsPluginEnabled() ? getPlugins(context) : null); nativeIsPluginEnabled() ? getPlugins(context) : null);
ContentMain.initApplicationContext(appContext); ContentMain.initApplicationContext(appContext);
int result = ContentMain.start(); int result = ContentMain.start();
...@@ -112,8 +87,8 @@ public class AndroidBrowserProcess { ...@@ -112,8 +87,8 @@ public class AndroidBrowserProcess {
resourceExtractor.startExtractingResources(); resourceExtractor.startExtractingResources();
resourceExtractor.waitForCompletion(); resourceExtractor.waitForCompletion();
// Having a single renderer should be sufficient for tests. // Having a single renderer should be sufficient for tests. We can't have more than
// We can't have more than MAX_RENDERERS_LIMIT. // MAX_RENDERERS_LIMIT.
nativeSetCommandLineFlags(1 /* maxRenderers */, null); nativeSetCommandLineFlags(1 /* maxRenderers */, null);
} }
...@@ -124,9 +99,8 @@ public class AndroidBrowserProcess { ...@@ -124,9 +99,8 @@ public class AndroidBrowserProcess {
private static native void nativeSetCommandLineFlags(int maxRenderProcesses, private static native void nativeSetCommandLineFlags(int maxRenderProcesses,
String pluginDescriptor); String pluginDescriptor);
// Is this an official build of Chrome? Only native code knows // Is this an official build of Chrome? Only native code knows for sure. Official build
// for sure. Official build knowledge is needed very early in // knowledge is needed very early in process startup.
// process startup.
private static native boolean nativeIsOfficialBuild(); private static native boolean nativeIsOfficialBuild();
private static native boolean nativeIsPluginEnabled(); private static native boolean nativeIsPluginEnabled();
......
// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be // Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. // found in the LICENSE file.
...@@ -22,8 +22,7 @@ import org.chromium.content.common.IChildProcessCallback; ...@@ -22,8 +22,7 @@ import org.chromium.content.common.IChildProcessCallback;
import org.chromium.content.common.IChildProcessService; import org.chromium.content.common.IChildProcessService;
/** /**
* This class provides the method to start/stop ChildProcess called by * This class provides the method to start/stop ChildProcess called by native.
* native.
*/ */
@JNINamespace("content") @JNINamespace("content")
public class ChildProcessLauncher { public class ChildProcessLauncher {
...@@ -113,8 +112,8 @@ public class ChildProcessLauncher { ...@@ -113,8 +112,8 @@ public class ChildProcessLauncher {
} }
} }
// Service class for child process. As the default value it uses // Service class for child process. As the default value it uses SandboxedProcessService0 and
// SandboxedProcessService0 and PrivilegedProcessService0 // PrivilegedProcessService0
private static final ChildConnectionAllocator mSandboxedChildConnectionAllocator = private static final ChildConnectionAllocator mSandboxedChildConnectionAllocator =
new ChildConnectionAllocator(true); new ChildConnectionAllocator(true);
private static final ChildConnectionAllocator mPrivilegedChildConnectionAllocator = private static final ChildConnectionAllocator mPrivilegedChildConnectionAllocator =
...@@ -320,9 +319,9 @@ public class ChildProcessLauncher { ...@@ -320,9 +319,9 @@ public class ChildProcessLauncher {
} }
/** /**
* Bind a child process as a high priority process so that it has the same * Bind a child process as a high priority process so that it has the same priority as the main
* priority as the main process. This can be used for the foreground renderer * process. This can be used for the foreground renderer process to distinguish it from the the
* process to distinguish it from the the background renderer process. * background renderer process.
* *
* @param pid The process handle of the service connection obtained from {@link #start}. * @param pid The process handle of the service connection obtained from {@link #start}.
*/ */
...@@ -355,17 +354,16 @@ public class ChildProcessLauncher { ...@@ -355,17 +354,16 @@ public class ChildProcessLauncher {
private static IChildProcessCallback createCallback(final int callbackType) { private static IChildProcessCallback createCallback(final int callbackType) {
return new IChildProcessCallback.Stub() { return new IChildProcessCallback.Stub() {
/** /**
* This is called by the remote service regularly to tell us about * This is called by the remote service regularly to tell us about new values. Note that
* new values. Note that IPC calls are dispatched through a thread * IPC calls are dispatched through a thread pool running in each process, so the code
* pool running in each process, so the code executing here will * executing here will NOT be running in our main thread -- so, to update the UI, we
* NOT be running in our main thread -- so, to update the UI, we need * need to use a Handler.
* to use a Handler.
*/ */
@Override @Override
public void establishSurfacePeer( public void establishSurfacePeer(
int pid, Surface surface, int primaryID, int secondaryID) { int pid, Surface surface, int primaryID, int secondaryID) {
// Do not allow a malicious renderer to connect to a producer. This is only // Do not allow a malicious renderer to connect to a producer. This is only used
// used from stream textures managed by the GPU process. // from stream textures managed by the GPU process.
if (callbackType != CALLBACK_FOR_GPU_PROCESS) { if (callbackType != CALLBACK_FOR_GPU_PROCESS) {
Log.e(TAG, "Illegal callback for non-GPU process."); Log.e(TAG, "Illegal callback for non-GPU process.");
return; return;
......
...@@ -92,7 +92,7 @@ public class ContentShellActivity extends ChromiumActivity { ...@@ -92,7 +92,7 @@ public class ContentShellActivity extends ChromiumActivity {
if (!TextUtils.isEmpty(startupUrl)) { if (!TextUtils.isEmpty(startupUrl)) {
mShellManager.setStartupUrl(Shell.sanitizeUrl(startupUrl)); mShellManager.setStartupUrl(Shell.sanitizeUrl(startupUrl));
} }
if (!AndroidBrowserProcess.init(this, AndroidBrowserProcess.MAX_RENDERERS_AUTOMATIC)) { if (!AndroidBrowserProcess.init(this, AndroidBrowserProcess.MAX_RENDERERS_LIMIT)) {
String shellUrl = ShellManager.DEFAULT_SHELL_URL; String shellUrl = ShellManager.DEFAULT_SHELL_URL;
if (savedInstanceState != null if (savedInstanceState != null
&& savedInstanceState.containsKey(ACTIVE_SHELL_URL_KEY)) { && savedInstanceState.containsKey(ACTIVE_SHELL_URL_KEY)) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment