Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1431)

Unified Diff: content/browser/renderer_host/browser_render_process_host.cc

Issue 8515027: Define the public version of the browser side RenderProcessHost interface. This interface is not ... (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/browser_render_process_host.cc
===================================================================
--- content/browser/renderer_host/browser_render_process_host.cc (revision 110571)
+++ content/browser/renderer_host/browser_render_process_host.cc (working copy)
@@ -1,1012 +0,0 @@
-// Copyright (c) 2011 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.
-
-// Represents the browser side of the browser <--> renderer communication
-// channel. There will be one RenderProcessHost per renderer process.
-
-#include "content/browser/renderer_host/browser_render_process_host.h"
-
-#include <algorithm>
-#include <limits>
-#include <vector>
-
-#if defined(OS_POSIX)
-#include <utility> // for pair<>
-#endif
-
-#include "base/base_switches.h"
-#include "base/bind.h"
-#include "base/bind_helpers.h"
-#include "base/callback.h"
-#include "base/command_line.h"
-#include "base/logging.h"
-#include "base/metrics/field_trial.h"
-#include "base/metrics/histogram.h"
-#include "base/path_service.h"
-#include "base/platform_file.h"
-#include "base/stl_util.h"
-#include "base/string_util.h"
-#include "base/threading/thread.h"
-#include "base/threading/thread_restrictions.h"
-#include "content/browser/appcache/appcache_dispatcher_host.h"
-#include "content/browser/browser_child_process_host.h"
-#include "content/browser/browser_context.h"
-#include "content/browser/child_process_security_policy.h"
-#include "content/browser/device_orientation/message_filter.h"
-#include "content/browser/download/mhtml_generation_manager.h"
-#include "content/browser/file_system/file_system_dispatcher_host.h"
-#include "content/browser/geolocation/geolocation_dispatcher_host.h"
-#include "content/browser/gpu/gpu_data_manager.h"
-#include "content/browser/gpu/gpu_process_host.h"
-#include "content/browser/in_process_webkit/dom_storage_message_filter.h"
-#include "content/browser/in_process_webkit/indexed_db_dispatcher_host.h"
-#include "content/browser/mime_registry_message_filter.h"
-#include "content/browser/plugin_service.h"
-#include "content/browser/renderer_host/blob_message_filter.h"
-#include "content/browser/renderer_host/clipboard_message_filter.h"
-#include "content/browser/renderer_host/database_message_filter.h"
-#include "content/browser/renderer_host/file_utilities_message_filter.h"
-#include "content/browser/renderer_host/gpu_message_filter.h"
-#include "content/browser/renderer_host/media/audio_input_renderer_host.h"
-#include "content/browser/renderer_host/media/audio_renderer_host.h"
-#include "content/browser/renderer_host/media/media_stream_dispatcher_host.h"
-#include "content/browser/renderer_host/media/video_capture_host.h"
-#include "content/browser/renderer_host/p2p/socket_dispatcher_host.h"
-#include "content/browser/renderer_host/pepper_file_message_filter.h"
-#include "content/browser/renderer_host/pepper_message_filter.h"
-#include "content/browser/renderer_host/quota_dispatcher_host.h"
-#include "content/browser/renderer_host/render_message_filter.h"
-#include "content/browser/renderer_host/render_view_host.h"
-#include "content/browser/renderer_host/render_view_host_delegate.h"
-#include "content/browser/renderer_host/render_widget_helper.h"
-#include "content/browser/renderer_host/render_widget_host.h"
-#include "content/browser/renderer_host/resource_message_filter.h"
-#include "content/browser/renderer_host/socket_stream_dispatcher_host.h"
-#include "content/browser/renderer_host/text_input_client_message_filter.h"
-#include "content/browser/resolve_proxy_msg_helper.h"
-#include "content/browser/speech/speech_input_dispatcher_host.h"
-#include "content/browser/trace_message_filter.h"
-#include "content/browser/user_metrics.h"
-#include "content/browser/worker_host/worker_message_filter.h"
-#include "content/common/child_process_info.h"
-#include "content/common/child_process_messages.h"
-#include "content/common/gpu/gpu_messages.h"
-#include "content/public/browser/notification_service.h"
-#include "content/common/process_watcher.h"
-#include "content/common/resource_messages.h"
-#include "content/common/view_messages.h"
-#include "content/public/browser/content_browser_client.h"
-#include "content/public/common/content_switches.h"
-#include "content/public/common/result_codes.h"
-#include "content/renderer/render_process_impl.h"
-#include "content/renderer/render_thread_impl.h"
-#include "ipc/ipc_logging.h"
-#include "ipc/ipc_platform_file.h"
-#include "ipc/ipc_switches.h"
-#include "media/base/media_switches.h"
-#include "net/url_request/url_request_context_getter.h"
-#include "ui/base/ui_base_switches.h"
-#include "ui/gfx/gl/gl_switches.h"
-#include "webkit/fileapi/file_system_path_manager.h"
-#include "webkit/fileapi/sandbox_mount_point_provider.h"
-#include "webkit/glue/resource_type.h"
-#include "webkit/plugins/plugin_switches.h"
-
-#if defined(OS_WIN)
-#include <objbase.h>
-#include "base/synchronization/waitable_event.h"
-#include "content/common/section_util_win.h"
-#endif
-
-#include "third_party/skia/include/core/SkBitmap.h"
-
-using content::BrowserThread;
-
-// This class creates the IO thread for the renderer when running in
-// single-process mode. It's not used in multi-process mode.
-class RendererMainThread : public base::Thread {
- public:
- explicit RendererMainThread(const std::string& channel_id)
- : base::Thread("Chrome_InProcRendererThread"),
- channel_id_(channel_id),
- render_process_(NULL) {
- }
-
- ~RendererMainThread() {
- Stop();
- }
-
- protected:
- virtual void Init() {
-#if defined(OS_WIN)
- CoInitialize(NULL);
-#endif
-
- render_process_ = new RenderProcessImpl();
- render_process_->set_main_thread(new RenderThreadImpl(channel_id_));
- }
-
- virtual void CleanUp() {
- delete render_process_;
-
-#if defined(OS_WIN)
- CoUninitialize();
-#endif
- // It's a little lame to manually set this flag. But the single process
- // RendererThread will receive the WM_QUIT. We don't need to assert on
- // this thread, so just force the flag manually.
- // If we want to avoid this, we could create the InProcRendererThread
- // directly with _beginthreadex() rather than using the Thread class.
- // We used to set this flag in the Init function above. However there
- // other threads like WebThread which are created by this thread
- // which resets this flag. Please see Thread::StartWithOptions. Setting
- // this flag to true in Cleanup works around these problems.
- base::Thread::SetThreadWasQuitProperly(true);
- }
-
- private:
- std::string channel_id_;
- // Deleted in CleanUp() on the renderer thread, so don't use a smart pointer.
- RenderProcess* render_process_;
-};
-
-namespace {
-
-// Helper class that we pass to ResourceMessageFilter so that it can find the
-// right net::URLRequestContext for a request.
-class RendererURLRequestContextSelector
- : public ResourceMessageFilter::URLRequestContextSelector {
- public:
- RendererURLRequestContextSelector(content::BrowserContext* browser_context,
- int render_child_id)
- : request_context_(browser_context->GetRequestContextForRenderProcess(
- render_child_id)),
- media_request_context_(browser_context->GetRequestContextForMedia()) {
- }
-
- virtual net::URLRequestContext* GetRequestContext(
- ResourceType::Type resource_type) {
- net::URLRequestContextGetter* request_context = request_context_;
- // If the request has resource type of ResourceType::MEDIA, we use a request
- // context specific to media for handling it because these resources have
- // specific needs for caching.
- if (resource_type == ResourceType::MEDIA)
- request_context = media_request_context_;
- return request_context->GetURLRequestContext();
- }
-
- private:
- virtual ~RendererURLRequestContextSelector() {}
-
- scoped_refptr<net::URLRequestContextGetter> request_context_;
- scoped_refptr<net::URLRequestContextGetter> media_request_context_;
-};
-
-} // namespace
-
-BrowserRenderProcessHost::BrowserRenderProcessHost(
- content::BrowserContext* browser_context)
- : RenderProcessHost(browser_context),
- visible_widgets_(0),
- backgrounded_(true),
- ALLOW_THIS_IN_INITIALIZER_LIST(cached_dibs_cleaner_(
- FROM_HERE, base::TimeDelta::FromSeconds(5),
- this, &BrowserRenderProcessHost::ClearTransportDIBCache)),
- accessibility_enabled_(false),
- is_initialized_(false) {
- widget_helper_ = new RenderWidgetHelper();
-
- ChildProcessSecurityPolicy::GetInstance()->Add(id());
-
- // Grant most file permissions to this renderer.
- // PLATFORM_FILE_TEMPORARY, PLATFORM_FILE_HIDDEN and
- // PLATFORM_FILE_DELETE_ON_CLOSE are not granted, because no existing API
- // requests them.
- // This is for the filesystem sandbox.
- ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile(
- id(), browser_context->GetPath().Append(
- fileapi::SandboxMountPointProvider::kNewFileSystemDirectory),
- base::PLATFORM_FILE_OPEN |
- base::PLATFORM_FILE_CREATE |
- base::PLATFORM_FILE_OPEN_ALWAYS |
- base::PLATFORM_FILE_CREATE_ALWAYS |
- base::PLATFORM_FILE_OPEN_TRUNCATED |
- base::PLATFORM_FILE_READ |
- base::PLATFORM_FILE_WRITE |
- base::PLATFORM_FILE_EXCLUSIVE_READ |
- base::PLATFORM_FILE_EXCLUSIVE_WRITE |
- base::PLATFORM_FILE_ASYNC |
- base::PLATFORM_FILE_WRITE_ATTRIBUTES |
- base::PLATFORM_FILE_ENUMERATE);
- // This is so that we can read and move stuff out of the old filesystem
- // sandbox.
- ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile(
- id(), browser_context->GetPath().Append(
- fileapi::SandboxMountPointProvider::kOldFileSystemDirectory),
- base::PLATFORM_FILE_READ | base::PLATFORM_FILE_WRITE |
- base::PLATFORM_FILE_WRITE_ATTRIBUTES | base::PLATFORM_FILE_ENUMERATE);
- // This is so that we can rename the old sandbox out of the way so that we
- // know we've taken care of it.
- ChildProcessSecurityPolicy::GetInstance()->GrantPermissionsForFile(
- id(), browser_context->GetPath().Append(
- fileapi::SandboxMountPointProvider::kRenamedOldFileSystemDirectory),
- base::PLATFORM_FILE_CREATE | base::PLATFORM_FILE_CREATE_ALWAYS |
- base::PLATFORM_FILE_WRITE);
-
- // Note: When we create the BrowserRenderProcessHost, it's technically
- // backgrounded, because it has no visible listeners. But the process
- // doesn't actually exist yet, so we'll Background it later, after
- // creation.
-}
-
-BrowserRenderProcessHost::~BrowserRenderProcessHost() {
- ChildProcessSecurityPolicy::GetInstance()->Remove(id());
-
- // We may have some unsent messages at this point, but that's OK.
- channel_.reset();
- while (!queued_messages_.empty()) {
- delete queued_messages_.front();
- queued_messages_.pop();
- }
-
- ClearTransportDIBCache();
-}
-
-void BrowserRenderProcessHost::EnableSendQueue() {
- is_initialized_ = false;
-}
-
-bool BrowserRenderProcessHost::Init(bool is_accessibility_enabled) {
- // calling Init() more than once does nothing, this makes it more convenient
- // for the view host which may not be sure in some cases
- if (channel_.get())
- return true;
-
- accessibility_enabled_ = is_accessibility_enabled;
-
- CommandLine::StringType renderer_prefix;
-#if defined(OS_POSIX)
- // A command prefix is something prepended to the command line of the spawned
- // process. It is supported only on POSIX systems.
- const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
- renderer_prefix =
- browser_command_line.GetSwitchValueNative(switches::kRendererCmdPrefix);
-#endif // defined(OS_POSIX)
-
-#if defined(OS_LINUX)
- int flags = renderer_prefix.empty() ? ChildProcessHost::CHILD_ALLOW_SELF :
- ChildProcessHost::CHILD_NORMAL;
-#else
- int flags = ChildProcessHost::CHILD_NORMAL;
-#endif
-
- // Find the renderer before creating the channel so if this fails early we
- // return without creating the channel.
- FilePath renderer_path = ChildProcessHost::GetChildPath(flags);
- if (renderer_path.empty())
- return false;
-
- // Setup the IPC channel.
- const std::string channel_id =
- ChildProcessInfo::GenerateRandomChannelID(this);
- channel_.reset(new IPC::ChannelProxy(
- channel_id, IPC::Channel::MODE_SERVER, this,
- BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO)));
-
- // Call the embedder first so that their IPC filters have priority.
- content::GetContentClient()->browser()->BrowserRenderProcessHostCreated(this);
-
- CreateMessageFilters();
-
- if (run_renderer_in_process()) {
- // Crank up a thread and run the initialization there. With the way that
- // messages flow between the browser and renderer, this thread is required
- // to prevent a deadlock in single-process mode. Since the primordial
- // thread in the renderer process runs the WebKit code and can sometimes
- // make blocking calls to the UI thread (i.e. this thread), they need to run
- // on separate threads.
- in_process_renderer_.reset(new RendererMainThread(channel_id));
-
- base::Thread::Options options;
-#if !defined(TOOLKIT_USES_GTK)
- // In-process plugins require this to be a UI message loop.
- options.message_loop_type = MessageLoop::TYPE_UI;
-#else
- // We can't have multiple UI loops on GTK, so we don't support
- // in-process plugins.
- options.message_loop_type = MessageLoop::TYPE_DEFAULT;
-#endif
- in_process_renderer_->StartWithOptions(options);
-
- OnProcessLaunched(); // Fake a callback that the process is ready.
- } else {
- // Build command line for renderer. We call AppendRendererCommandLine()
- // first so the process type argument will appear first.
- CommandLine* cmd_line = new CommandLine(renderer_path);
- if (!renderer_prefix.empty())
- cmd_line->PrependWrapper(renderer_prefix);
- AppendRendererCommandLine(cmd_line);
- cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
-
- // Spawn the child process asynchronously to avoid blocking the UI thread.
- // As long as there's no renderer prefix, we can use the zygote process
- // at this stage.
- child_process_launcher_.reset(new ChildProcessLauncher(
-#if defined(OS_WIN)
- FilePath(),
-#elif defined(OS_POSIX)
- renderer_prefix.empty(),
- base::environment_vector(),
- channel_->TakeClientFileDescriptor(),
-#endif
- cmd_line,
- this));
-
- fast_shutdown_started_ = false;
- }
-
- is_initialized_ = true;
- return true;
-}
-
-void BrowserRenderProcessHost::CreateMessageFilters() {
- scoped_refptr<RenderMessageFilter> render_message_filter(
- new RenderMessageFilter(
- id(),
- PluginService::GetInstance(),
- browser_context(),
- browser_context()->GetRequestContextForRenderProcess(id()),
- widget_helper_));
- channel_->AddFilter(render_message_filter);
-
- ResourceMessageFilter* resource_message_filter = new ResourceMessageFilter(
- id(), ChildProcessInfo::RENDER_PROCESS,
- &browser_context()->GetResourceContext(),
- new RendererURLRequestContextSelector(browser_context(), id()),
- content::GetContentClient()->browser()->GetResourceDispatcherHost());
-
- channel_->AddFilter(resource_message_filter);
- channel_->AddFilter(new AudioInputRendererHost(
- &browser_context()->GetResourceContext()));
- channel_->AddFilter(
- new AudioRendererHost(&browser_context()->GetResourceContext()));
- channel_->AddFilter(
- new VideoCaptureHost(&browser_context()->GetResourceContext()));
- channel_->AddFilter(
- new AppCacheDispatcherHost(browser_context()->GetAppCacheService(),
- id()));
- channel_->AddFilter(new ClipboardMessageFilter());
- channel_->AddFilter(
- new DOMStorageMessageFilter(id(), browser_context()->GetWebKitContext()));
- channel_->AddFilter(
- new IndexedDBDispatcherHost(id(), browser_context()->GetWebKitContext()));
- channel_->AddFilter(
- GeolocationDispatcherHost::New(
- id(), browser_context()->GetGeolocationPermissionContext()));
- channel_->AddFilter(new GpuMessageFilter(id(), widget_helper_.get()));
- channel_->AddFilter(new media_stream::MediaStreamDispatcherHost(
- &browser_context()->GetResourceContext(), id()));
- channel_->AddFilter(new PepperFileMessageFilter(id(), browser_context()));
- channel_->AddFilter(
- new PepperMessageFilter(&browser_context()->GetResourceContext()));
- channel_->AddFilter(new speech_input::SpeechInputDispatcherHost(
- id(), browser_context()->GetRequestContext(),
- browser_context()->GetSpeechInputPreferences()));
- channel_->AddFilter(
- new FileSystemDispatcherHost(browser_context()->GetRequestContext(),
- browser_context()->GetFileSystemContext()));
- channel_->AddFilter(new device_orientation::MessageFilter());
- channel_->AddFilter(
- new BlobMessageFilter(id(), browser_context()->GetBlobStorageContext()));
- channel_->AddFilter(new FileUtilitiesMessageFilter(id()));
- channel_->AddFilter(new MimeRegistryMessageFilter());
- channel_->AddFilter(new DatabaseMessageFilter(
- browser_context()->GetDatabaseTracker()));
-#if defined(OS_MACOSX)
- channel_->AddFilter(new TextInputClientMessageFilter(id()));
-#endif
-
- SocketStreamDispatcherHost* socket_stream_dispatcher_host =
- new SocketStreamDispatcherHost(
- new RendererURLRequestContextSelector(browser_context(), id()),
- &browser_context()->GetResourceContext());
- channel_->AddFilter(socket_stream_dispatcher_host);
-
- channel_->AddFilter(
- new WorkerMessageFilter(
- id(),
- &browser_context()->GetResourceContext(),
- content::GetContentClient()->browser()->GetResourceDispatcherHost(),
- base::Bind(&RenderWidgetHelper::GetNextRoutingID,
- base::Unretained(widget_helper_.get()))));
-
-#if defined(ENABLE_P2P_APIS)
- channel_->AddFilter(new content::P2PSocketDispatcherHost(
- &browser_context()->GetResourceContext()));
-#endif
-
- channel_->AddFilter(new TraceMessageFilter());
- channel_->AddFilter(new ResolveProxyMsgHelper(
- browser_context()->GetRequestContextForRenderProcess(id())));
- channel_->AddFilter(new QuotaDispatcherHost(
- id(), browser_context()->GetQuotaManager(),
- content::GetContentClient()->browser()->CreateQuotaPermissionContext()));
-}
-
-int BrowserRenderProcessHost::GetNextRoutingID() {
- return widget_helper_->GetNextRoutingID();
-}
-
-void BrowserRenderProcessHost::UpdateAndSendMaxPageID(int32 page_id) {
- if (page_id > max_page_id_)
- Send(new ViewMsg_SetNextPageID(page_id + 1));
- UpdateMaxPageID(page_id);
-}
-
-void BrowserRenderProcessHost::CancelResourceRequests(int render_widget_id) {
- widget_helper_->CancelResourceRequests(render_widget_id);
-}
-
-void BrowserRenderProcessHost::CrossSiteSwapOutACK(
- const ViewMsg_SwapOut_Params& params) {
- widget_helper_->CrossSiteSwapOutACK(params);
-}
-
-bool BrowserRenderProcessHost::WaitForUpdateMsg(
- int render_widget_id,
- const base::TimeDelta& max_delay,
- IPC::Message* msg) {
- // The post task to this thread with the process id could be in queue, and we
- // don't want to dispatch a message before then since it will need the handle.
- if (child_process_launcher_.get() && child_process_launcher_->IsStarting())
- return false;
-
- return widget_helper_->WaitForUpdateMsg(render_widget_id, max_delay, msg);
-}
-
-void BrowserRenderProcessHost::ReceivedBadMessage() {
- if (run_renderer_in_process()) {
- // In single process mode it is better if we don't suicide but just
- // crash.
- CHECK(false);
- }
- NOTREACHED();
- base::KillProcess(GetHandle(), content::RESULT_CODE_KILLED_BAD_MESSAGE,
- false);
-}
-
-void BrowserRenderProcessHost::WidgetRestored() {
- // Verify we were properly backgrounded.
- DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
- visible_widgets_++;
- SetBackgrounded(false);
-}
-
-void BrowserRenderProcessHost::WidgetHidden() {
- // On startup, the browser will call Hide
- if (backgrounded_)
- return;
-
- DCHECK_EQ(backgrounded_, (visible_widgets_ == 0));
- visible_widgets_--;
- DCHECK_GE(visible_widgets_, 0);
- if (visible_widgets_ == 0) {
- DCHECK(!backgrounded_);
- SetBackgrounded(true);
- }
-}
-
-int BrowserRenderProcessHost::VisibleWidgetCount() const {
- return visible_widgets_;
-}
-
-void BrowserRenderProcessHost::AppendRendererCommandLine(
- CommandLine* command_line) const {
- // Pass the process type first, so it shows first in process listings.
- command_line->AppendSwitchASCII(switches::kProcessType,
- switches::kRendererProcess);
-
- if (accessibility_enabled_)
- command_line->AppendSwitch(switches::kEnableAccessibility);
-
- // Now send any options from our own command line we want to propagate.
- const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
- PropagateBrowserCommandLineToRenderer(browser_command_line, command_line);
-
- // Pass on the browser locale.
- const std::string locale =
- content::GetContentClient()->browser()->GetApplicationLocale();
- command_line->AppendSwitchASCII(switches::kLang, locale);
-
- // If we run base::FieldTrials, we want to pass to their state to the
- // renderer so that it can act in accordance with each state, or record
- // histograms relating to the base::FieldTrial states.
- std::string field_trial_states;
- base::FieldTrialList::StatesToString(&field_trial_states);
- if (!field_trial_states.empty()) {
- command_line->AppendSwitchASCII(switches::kForceFieldTestNameAndValue,
- field_trial_states);
- }
-
- content::GetContentClient()->browser()->AppendExtraCommandLineSwitches(
- command_line, id());
-
- // Appending disable-gpu-feature switches due to software rendering list.
- GpuDataManager* gpu_data_manager = GpuDataManager::GetInstance();
- DCHECK(gpu_data_manager);
- gpu_data_manager->AppendRendererCommandLine(command_line);
-}
-
-void BrowserRenderProcessHost::PropagateBrowserCommandLineToRenderer(
- const CommandLine& browser_cmd,
- CommandLine* renderer_cmd) const {
- // Propagate the following switches to the renderer command line (along
- // with any associated values) if present in the browser command line.
- static const char* const kSwitchNames[] = {
- // We propagate the Chrome Frame command line here as well in case the
- // renderer is not run in the sandbox.
- switches::kAuditAllHandles,
- switches::kAuditHandles,
- switches::kChromeFrame,
- switches::kDisable3DAPIs,
- switches::kDisableAcceleratedCompositing,
- switches::kDisableApplicationCache,
- switches::kDisableAudio,
- switches::kDisableBreakpad,
- switches::kDisableDataTransferItems,
- switches::kDisableDatabases,
- switches::kDisableDesktopNotifications,
- switches::kDisableDeviceOrientation,
- switches::kDisableFileSystem,
- switches::kDisableGeolocation,
- switches::kDisableGLMultisampling,
- switches::kDisableGLSLTranslator,
- switches::kDisableGpuDriverBugWorkarounds,
- switches::kDisableGpuVsync,
- switches::kDisableIndexedDatabase,
- switches::kDisableJavaScriptI18NAPI,
- switches::kDisableLocalStorage,
- switches::kDisableLogging,
- switches::kDisableSeccompSandbox,
- switches::kDisableSessionStorage,
- switches::kDisableSharedWorkers,
- switches::kDisableSpeechInput,
- switches::kDisableWebAudio,
- switches::kDisableWebSockets,
- switches::kEnableAccessibilityLogging,
- switches::kEnableDCHECK,
- switches::kEnableGamepad,
- switches::kEnableGPUServiceLogging,
- switches::kEnableGPUClientLogging,
- switches::kEnableLogging,
- switches::kEnableMediaSource,
- switches::kEnableMediaStream,
- switches::kEnableStrictSiteIsolation,
- switches::kDisableFullScreen,
- switches::kEnablePepperTesting,
-#if defined(OS_MACOSX)
- // Allow this to be set when invoking the browser and relayed along.
- switches::kEnableSandboxLogging,
-#endif
- switches::kEnableSeccompSandbox,
- switches::kEnableStatsTable,
- switches::kEnableThreadedCompositing,
- switches::kEnableVideoFullscreen,
- switches::kEnableVideoLogging,
- switches::kEnableVideoTrack,
- switches::kFullMemoryCrashReport,
-#if !defined (GOOGLE_CHROME_BUILD)
- // These are unsupported and not fully tested modes, so don't enable them
- // for official Google Chrome builds.
- switches::kInProcessPlugins,
-#endif // GOOGLE_CHROME_BUILD
- switches::kInProcessWebGL,
- switches::kJavaScriptFlags,
- switches::kLoggingLevel,
- switches::kHighLatencyAudio,
- switches::kNoJsRandomness,
- switches::kNoReferrers,
- switches::kNoSandbox,
- switches::kPlaybackMode,
- switches::kPpapiOutOfProcess,
- switches::kRecordMode,
- switches::kRegisterPepperPlugins,
- switches::kRemoteShellPort,
- switches::kRendererAssertTest,
-#if !defined(OFFICIAL_BUILD)
- switches::kRendererCheckFalseTest,
-#endif // !defined(OFFICIAL_BUILD)
- switches::kRendererCrashTest,
- switches::kRendererStartupDialog,
- switches::kShowPaintRects,
- switches::kSimpleDataSource,
- switches::kTestSandbox,
- switches::kTraceStartup,
- // This flag needs to be propagated to the renderer process for
- // --in-process-webgl.
- switches::kUseGL,
- switches::kUserAgent,
- switches::kV,
- switches::kVideoThreads,
- switches::kVModule,
- switches::kWebCoreLogChannels,
- };
- renderer_cmd->CopySwitchesFrom(browser_cmd, kSwitchNames,
- arraysize(kSwitchNames));
-
- // Disable databases in incognito mode.
- if (browser_context()->IsOffTheRecord() &&
- !browser_cmd.HasSwitch(switches::kDisableDatabases)) {
- renderer_cmd->AppendSwitch(switches::kDisableDatabases);
- }
-}
-
-base::ProcessHandle BrowserRenderProcessHost::GetHandle() {
- // child_process_launcher_ is null either because we're in single process
- // mode, we have done fast termination, or the process has crashed.
- if (run_renderer_in_process() || !child_process_launcher_.get())
- return base::Process::Current().handle();
-
- if (child_process_launcher_->IsStarting())
- return base::kNullProcessHandle;
-
- return child_process_launcher_->GetHandle();
-}
-
-bool BrowserRenderProcessHost::FastShutdownIfPossible() {
- if (run_renderer_in_process())
- return false; // Single process mode can't do fast shutdown.
-
- if (!content::GetContentClient()->browser()->IsFastShutdownPossible())
- return false;
-
- if (!child_process_launcher_.get() ||
- child_process_launcher_->IsStarting() ||
- !GetHandle())
- return false; // Render process hasn't started or is probably crashed.
-
- // Test if there's an unload listener.
- // NOTE: It's possible that an onunload listener may be installed
- // while we're shutting down, so there's a small race here. Given that
- // the window is small, it's unlikely that the web page has much
- // state that will be lost by not calling its unload handlers properly.
- if (!sudden_termination_allowed())
- return false;
-
- // Store the handle before it gets changed.
- base::ProcessHandle handle = GetHandle();
- ProcessDied(handle, base::TERMINATION_STATUS_NORMAL_TERMINATION, 0, false);
- fast_shutdown_started_ = true;
- return true;
-}
-
-void BrowserRenderProcessHost::DumpHandles() {
-#if defined(OS_WIN)
- Send(new ChildProcessMsg_DumpHandles());
- return;
-#endif
-
- NOTIMPLEMENTED();
-}
-
-// This is a platform specific function for mapping a transport DIB given its id
-TransportDIB* BrowserRenderProcessHost::MapTransportDIB(
- TransportDIB::Id dib_id) {
-#if defined(OS_WIN)
- // On Windows we need to duplicate the handle from the remote process
- HANDLE section = chrome::GetSectionFromProcess(
- dib_id.handle, GetHandle(), false /* read write */);
- return TransportDIB::Map(section);
-#elif defined(OS_MACOSX)
- // On OSX, the browser allocates all DIBs and keeps a file descriptor around
- // for each.
- return widget_helper_->MapTransportDIB(dib_id);
-#elif defined(OS_POSIX)
- return TransportDIB::Map(dib_id.shmkey);
-#endif // defined(OS_POSIX)
-}
-
-TransportDIB* BrowserRenderProcessHost::GetTransportDIB(
- TransportDIB::Id dib_id) {
- if (!TransportDIB::is_valid_id(dib_id))
- return NULL;
-
- const std::map<TransportDIB::Id, TransportDIB*>::iterator
- i = cached_dibs_.find(dib_id);
- if (i != cached_dibs_.end()) {
- cached_dibs_cleaner_.Reset();
- return i->second;
- }
-
- TransportDIB* dib = MapTransportDIB(dib_id);
- if (!dib)
- return NULL;
-
- if (cached_dibs_.size() >= MAX_MAPPED_TRANSPORT_DIBS) {
- // Clean a single entry from the cache
- std::map<TransportDIB::Id, TransportDIB*>::iterator smallest_iterator;
- size_t smallest_size = std::numeric_limits<size_t>::max();
-
- for (std::map<TransportDIB::Id, TransportDIB*>::iterator
- i = cached_dibs_.begin(); i != cached_dibs_.end(); ++i) {
- if (i->second->size() <= smallest_size) {
- smallest_iterator = i;
- smallest_size = i->second->size();
- }
- }
-
- delete smallest_iterator->second;
- cached_dibs_.erase(smallest_iterator);
- }
-
- cached_dibs_[dib_id] = dib;
- cached_dibs_cleaner_.Reset();
- return dib;
-}
-
-void BrowserRenderProcessHost::ClearTransportDIBCache() {
- STLDeleteContainerPairSecondPointers(
- cached_dibs_.begin(), cached_dibs_.end());
- cached_dibs_.clear();
-}
-
-void BrowserRenderProcessHost::SetCompositingSurface(
- int render_widget_id,
- gfx::PluginWindowHandle compositing_surface) {
- widget_helper_->SetCompositingSurface(render_widget_id, compositing_surface);
-}
-
-bool BrowserRenderProcessHost::Send(IPC::Message* msg) {
- if (!channel_.get()) {
- if (!is_initialized_) {
- queued_messages_.push(msg);
- return true;
- } else {
- delete msg;
- return false;
- }
- }
-
- if (child_process_launcher_.get() && child_process_launcher_->IsStarting()) {
- queued_messages_.push(msg);
- return true;
- }
-
- return channel_->Send(msg);
-}
-
-bool BrowserRenderProcessHost::OnMessageReceived(const IPC::Message& msg) {
- // If we're about to be deleted, or have initiated the fast shutdown sequence,
- // we ignore incoming messages.
-
- if (deleting_soon_ || fast_shutdown_started_)
- return false;
-
- mark_child_process_activity_time();
- if (msg.routing_id() == MSG_ROUTING_CONTROL) {
- // Dispatch control messages.
- bool msg_is_ok = true;
- IPC_BEGIN_MESSAGE_MAP_EX(BrowserRenderProcessHost, msg, msg_is_ok)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_ShutdownRequest,
- OnShutdownRequest)
- IPC_MESSAGE_HANDLER(ChildProcessHostMsg_DumpHandlesDone,
- OnDumpHandlesDone)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SuddenTerminationChanged,
- SuddenTerminationChanged)
- IPC_MESSAGE_HANDLER(ViewHostMsg_UserMetricsRecordAction,
- OnUserMetricsRecordAction)
- IPC_MESSAGE_HANDLER(ViewHostMsg_RevealFolderInOS, OnRevealFolderInOS)
- IPC_MESSAGE_HANDLER(ViewHostMsg_SavedPageAsMHTML, OnSavedPageAsMHTML)
- IPC_MESSAGE_UNHANDLED_ERROR()
- IPC_END_MESSAGE_MAP_EX()
-
- if (!msg_is_ok) {
- // The message had a handler, but its de-serialization failed.
- // We consider this a capital crime. Kill the renderer if we have one.
- LOG(ERROR) << "bad message " << msg.type() << " terminating renderer.";
- UserMetrics::RecordAction(UserMetricsAction("BadMessageTerminate_BRPH"));
- ReceivedBadMessage();
- }
- return true;
- }
-
- // Dispatch incoming messages to the appropriate RenderView/WidgetHost.
- IPC::Channel::Listener* listener = GetListenerByID(msg.routing_id());
- if (!listener) {
- if (msg.is_sync()) {
- // The listener has gone away, so we must respond or else the caller will
- // hang waiting for a reply.
- IPC::Message* reply = IPC::SyncMessage::GenerateReply(&msg);
- reply->set_reply_error();
- Send(reply);
- }
- return true;
- }
- return listener->OnMessageReceived(msg);
-}
-
-void BrowserRenderProcessHost::OnChannelConnected(int32 peer_pid) {
-#if defined(IPC_MESSAGE_LOG_ENABLED)
- Send(new ChildProcessMsg_SetIPCLoggingEnabled(
- IPC::Logging::GetInstance()->Enabled()));
-#endif
-
- // Make sure the child checks with us before exiting, so that we do not try
- // to schedule a new navigation in a swapped out and exiting renderer.
- Send(new ChildProcessMsg_AskBeforeShutdown());
-}
-
-void BrowserRenderProcessHost::OnChannelError() {
- if (!channel_.get())
- return;
-
- // Store the handle before it gets changed.
- base::ProcessHandle handle = GetHandle();
-
- // child_process_launcher_ can be NULL in single process mode or if fast
- // termination happened.
- int exit_code = 0;
- base::TerminationStatus status =
- child_process_launcher_.get() ?
- child_process_launcher_->GetChildTerminationStatus(&exit_code) :
- base::TERMINATION_STATUS_NORMAL_TERMINATION;
-
-#if defined(OS_WIN)
- if (!run_renderer_in_process()) {
- if (status == base::TERMINATION_STATUS_STILL_RUNNING) {
- HANDLE process = child_process_launcher_->GetHandle();
- child_process_watcher_.StartWatching(
- new base::WaitableEvent(process), this);
- return;
- }
- }
-#endif
- ProcessDied(handle, status, exit_code, false);
-}
-
-// Called when the renderer process handle has been signaled.
-void BrowserRenderProcessHost::OnWaitableEventSignaled(
- base::WaitableEvent* waitable_event) {
-#if defined (OS_WIN)
- base::ProcessHandle handle = GetHandle();
- int exit_code = 0;
- base::TerminationStatus status =
- base::GetTerminationStatus(waitable_event->Release(), &exit_code);
- delete waitable_event;
- ProcessDied(handle, status, exit_code, true);
-#endif
-}
-
-void BrowserRenderProcessHost::ProcessDied(base::ProcessHandle handle,
- base::TerminationStatus status,
- int exit_code,
- bool was_alive) {
- // Our child process has died. If we didn't expect it, it's a crash.
- // In any case, we need to let everyone know it's gone.
- // The OnChannelError notification can fire multiple times due to nested sync
- // calls to a renderer. If we don't have a valid channel here it means we
- // already handled the error.
-
- RendererClosedDetails details(handle, status, exit_code, was_alive);
- content::NotificationService::current()->Notify(
- content::NOTIFICATION_RENDERER_PROCESS_CLOSED,
- content::Source<RenderProcessHost>(this),
- content::Details<RendererClosedDetails>(&details));
-
- child_process_launcher_.reset();
- channel_.reset();
-
- IDMap<IPC::Channel::Listener>::iterator iter(&listeners_);
- while (!iter.IsAtEnd()) {
- iter.GetCurrentValue()->OnMessageReceived(
- ViewHostMsg_RenderViewGone(iter.GetCurrentKey(),
- static_cast<int>(status),
- exit_code));
- iter.Advance();
- }
-
- ClearTransportDIBCache();
-
- // this object is not deleted at this point and may be reused later.
- // TODO(darin): clean this up
-}
-
-void BrowserRenderProcessHost::OnShutdownRequest() {
- // Don't shutdown if there are pending RenderViews being swapped back in.
- if (pending_views_)
- return;
-
- // Notify any tabs that might have swapped out renderers from this process.
- // They should not attempt to swap them back in.
- content::NotificationService::current()->Notify(
- content::NOTIFICATION_RENDERER_PROCESS_CLOSING,
- content::Source<RenderProcessHost>(this),
- content::NotificationService::NoDetails());
-
- Send(new ChildProcessMsg_Shutdown());
-}
-
-void BrowserRenderProcessHost::OnDumpHandlesDone() {
- Cleanup();
-}
-
-void BrowserRenderProcessHost::SuddenTerminationChanged(bool enabled) {
- set_sudden_termination_allowed(enabled);
-}
-
-void BrowserRenderProcessHost::SetBackgrounded(bool backgrounded) {
- // Note: we always set the backgrounded_ value. If the process is NULL
- // (and hence hasn't been created yet), we will set the process priority
- // later when we create the process.
- backgrounded_ = backgrounded;
- if (!child_process_launcher_.get() || child_process_launcher_->IsStarting())
- return;
-
-#if defined(OS_WIN)
- // The cbstext.dll loads as a global GetMessage hook in the browser process
- // and intercepts/unintercepts the kernel32 API SetPriorityClass in a
- // background thread. If the UI thread invokes this API just when it is
- // intercepted the stack is messed up on return from the interceptor
- // which causes random crashes in the browser process. Our hack for now
- // is to not invoke the SetPriorityClass API if the dll is loaded.
- if (GetModuleHandle(L"cbstext.dll"))
- return;
-#endif // OS_WIN
-
- child_process_launcher_->SetProcessBackgrounded(backgrounded);
-}
-
-void BrowserRenderProcessHost::OnProcessLaunched() {
- // No point doing anything, since this object will be destructed soon. We
- // especially don't want to send the RENDERER_PROCESS_CREATED notification,
- // since some clients might expect a RENDERER_PROCESS_TERMINATED afterwards to
- // properly cleanup.
- if (deleting_soon_)
- return;
-
- if (child_process_launcher_.get()) {
- if (!child_process_launcher_->GetHandle()) {
- OnChannelError();
- return;
- }
-
- child_process_launcher_->SetProcessBackgrounded(backgrounded_);
- }
-
- if (max_page_id_ != -1)
- Send(new ViewMsg_SetNextPageID(max_page_id_ + 1));
-
- // NOTE: This needs to be before sending queued messages because
- // ExtensionService uses this notification to initialize the renderer process
- // with state that must be there before any JavaScript executes.
- //
- // The queued messages contain such things as "navigate". If this notification
- // was after, we can end up executing JavaScript before the initialization
- // happens.
- content::NotificationService::current()->Notify(
- content::NOTIFICATION_RENDERER_PROCESS_CREATED,
- content::Source<RenderProcessHost>(this),
- content::NotificationService::NoDetails());
-
- while (!queued_messages_.empty()) {
- Send(queued_messages_.front());
- queued_messages_.pop();
- }
-}
-
-void BrowserRenderProcessHost::OnUserMetricsRecordAction(
- const std::string& action) {
- UserMetrics::RecordComputedAction(action);
-}
-
-void BrowserRenderProcessHost::OnRevealFolderInOS(const FilePath& path) {
- // Only honor the request if appropriate persmissions are granted.
- if (ChildProcessSecurityPolicy::GetInstance()->CanReadFile(id(), path))
- content::GetContentClient()->browser()->OpenItem(path);
-}
-
-void BrowserRenderProcessHost::OnSavedPageAsMHTML(int job_id, int64 data_size) {
- content::GetContentClient()->browser()->GetMHTMLGenerationManager()->
- MHTMLGenerated(job_id, data_size);
-}
« no previous file with comments | « content/browser/renderer_host/browser_render_process_host.h ('k') | content/browser/renderer_host/mock_render_process_host.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698