// Copyright (c) 2012 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. #ifndef CONTENT_BROWSER_RENDERER_HOST_BROWSER_RENDER_PROCESS_HOST_IMPL_H_ #define CONTENT_BROWSER_RENDERER_HOST_BROWSER_RENDER_PROCESS_HOST_IMPL_H_ #include #include #include #include "base/memory/scoped_ptr.h" #include "base/observer_list.h" #include "base/process/process.h" #include "base/timer/timer.h" #include "content/browser/child_process_launcher.h" #include "content/browser/dom_storage/session_storage_namespace_impl.h" #include "content/browser/power_monitor_message_broadcaster.h" #include "content/common/content_export.h" #include "content/public/browser/gpu_data_manager_observer.h" #include "content/public/browser/render_process_host.h" #include "ipc/ipc_channel_proxy.h" #include "ipc/ipc_platform_file.h" #include "mojo/public/cpp/bindings/interface_ptr.h" #if defined(OS_MACOSX) #include #include "base/mac/scoped_cftyperef.h" #endif struct ViewHostMsg_CompositorSurfaceBuffersSwapped_Params; namespace base { class CommandLine; class MessageLoop; } namespace gfx { class Size; struct GpuMemoryBufferHandle; } namespace content { class AudioRendererHost; class BrowserDemuxerAndroid; class GpuMessageFilter; class MessagePortMessageFilter; class MojoApplicationHost; #if defined(ENABLE_WEBRTC) class P2PSocketDispatcherHost; #endif class PeerConnectionTrackerHost; class RendererMainThread; class RenderProcessHostMojoImpl; class RenderWidgetHelper; class RenderWidgetHost; class RenderWidgetHostImpl; class RenderWidgetHostViewFrameSubscriber; class ScreenOrientationDispatcherHost; class StoragePartition; class StoragePartitionImpl; typedef base::Thread* (*RendererMainThreadFactoryFunction)( const std::string& id); // Implements a concrete RenderProcessHost for the browser process for talking // to actual renderer processes (as opposed to mocks). // // Represents the browser side of the browser <--> renderer communication // channel. There will be one RenderProcessHost per renderer process. // // This object is refcounted so that it can release its resources when all // hosts using it go away. // // This object communicates back and forth with the RenderProcess object // running in the renderer process. Each RenderProcessHost and RenderProcess // keeps a list of RenderView (renderer) and WebContentsImpl (browser) which // are correlated with IDs. This way, the Views and the corresponding ViewHosts // communicate through the two process objects. // // A RenderProcessHost is also associated with one and only one // StoragePartition. This allows us to implement strong storage isolation // because all the IPCs from the RenderViews (renderer) will only ever be able // to access the partition they are assigned to. class CONTENT_EXPORT RenderProcessHostImpl : public RenderProcessHost, public ChildProcessLauncher::Client, public GpuDataManagerObserver { public: RenderProcessHostImpl(BrowserContext* browser_context, StoragePartitionImpl* storage_partition_impl, bool is_isolated_guest); virtual ~RenderProcessHostImpl(); // RenderProcessHost implementation (public portion). virtual void EnableSendQueue() OVERRIDE; virtual bool Init() OVERRIDE; virtual int GetNextRoutingID() OVERRIDE; virtual void AddRoute(int32 routing_id, IPC::Listener* listener) OVERRIDE; virtual void RemoveRoute(int32 routing_id) OVERRIDE; virtual void AddObserver(RenderProcessHostObserver* observer) OVERRIDE; virtual void RemoveObserver(RenderProcessHostObserver* observer) OVERRIDE; virtual bool WaitForBackingStoreMsg(int render_widget_id, const base::TimeDelta& max_delay, IPC::Message* msg) OVERRIDE; virtual void ReceivedBadMessage() OVERRIDE; virtual void WidgetRestored() OVERRIDE; virtual void WidgetHidden() OVERRIDE; virtual int VisibleWidgetCount() const OVERRIDE; virtual bool IsIsolatedGuest() const OVERRIDE; virtual StoragePartition* GetStoragePartition() const OVERRIDE; virtual bool FastShutdownIfPossible() OVERRIDE; virtual void DumpHandles() OVERRIDE; virtual base::ProcessHandle GetHandle() const OVERRIDE; virtual BrowserContext* GetBrowserContext() const OVERRIDE; virtual bool InSameStoragePartition( StoragePartition* partition) const OVERRIDE; virtual int GetID() const OVERRIDE; virtual bool HasConnection() const OVERRIDE; virtual void SetIgnoreInputEvents(bool ignore_input_events) OVERRIDE; virtual bool IgnoreInputEvents() const OVERRIDE; virtual void Cleanup() OVERRIDE; virtual void AddPendingView() OVERRIDE; virtual void RemovePendingView() OVERRIDE; virtual void SetSuddenTerminationAllowed(bool enabled) OVERRIDE; virtual bool SuddenTerminationAllowed() const OVERRIDE; virtual IPC::ChannelProxy* GetChannel() OVERRIDE; virtual void AddFilter(BrowserMessageFilter* filter) OVERRIDE; virtual bool FastShutdownForPageCount(size_t count) OVERRIDE; virtual bool FastShutdownStarted() const OVERRIDE; virtual base::TimeDelta GetChildProcessIdleTime() const OVERRIDE; virtual void ResumeRequestsForView(int route_id) OVERRIDE; virtual void FilterURL(bool empty_allowed, GURL* url) OVERRIDE; #if defined(ENABLE_WEBRTC) virtual void EnableAecDump(const base::FilePath& file) OVERRIDE; virtual void DisableAecDump() OVERRIDE; virtual void SetWebRtcLogMessageCallback( base::Callback callback) OVERRIDE; virtual WebRtcStopRtpDumpCallback StartRtpDump( bool incoming, bool outgoing, const WebRtcRtpPacketCallback& packet_callback) OVERRIDE; #endif virtual void ResumeDeferredNavigation(const GlobalRequestID& request_id) OVERRIDE; virtual void NotifyTimezoneChange() OVERRIDE; // IPC::Sender via RenderProcessHost. virtual bool Send(IPC::Message* msg) OVERRIDE; // IPC::Listener via RenderProcessHost. virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; virtual void OnChannelConnected(int32 peer_pid) OVERRIDE; virtual void OnChannelError() OVERRIDE; virtual void OnBadMessageReceived(const IPC::Message& message) OVERRIDE; // ChildProcessLauncher::Client implementation. virtual void OnProcessLaunched() OVERRIDE; scoped_refptr audio_renderer_host() const; // Call this function when it is evident that the child process is actively // performing some operation, for example if we just received an IPC message. void mark_child_process_activity_time() { child_process_activity_time_ = base::TimeTicks::Now(); } // Returns the current number of active views in this process. Excludes // any RenderViewHosts that are swapped out. int GetActiveViewCount(); // Start and end frame subscription for a specific renderer. // This API only supports subscription to accelerated composited frames. void BeginFrameSubscription( int route_id, scoped_ptr subscriber); void EndFrameSubscription(int route_id); #if defined(ENABLE_WEBRTC) // Fires the webrtc log message callback with |message|, if callback is set. void WebRtcLogMessage(const std::string& message); #endif scoped_refptr screen_orientation_dispatcher_host() const; // Used to extend the lifetime of the sessions until the render view // in the renderer is fully closed. This is static because its also called // with mock hosts as input in test cases. static void ReleaseOnCloseACK( RenderProcessHost* host, const SessionStorageNamespaceMap& sessions, int view_route_id); // Register/unregister the host identified by the host id in the global host // list. static void RegisterHost(int host_id, RenderProcessHost* host); static void UnregisterHost(int host_id); // Implementation of FilterURL below that can be shared with the mock class. static void FilterURL(RenderProcessHost* rph, bool empty_allowed, GURL* url); // Returns true if |host| is suitable for launching a new view with |site_url| // in the given |browser_context|. static bool IsSuitableHost(RenderProcessHost* host, BrowserContext* browser_context, const GURL& site_url); // Returns an existing RenderProcessHost for |url| in |browser_context|, // if one exists. Otherwise a new RenderProcessHost should be created and // registered using RegisterProcessHostForSite(). // This should only be used for process-per-site mode, which can be enabled // globally with a command line flag or per-site, as determined by // SiteInstanceImpl::ShouldUseProcessPerSite. static RenderProcessHost* GetProcessHostForSite( BrowserContext* browser_context, const GURL& url); // Registers the given |process| to be used for any instance of |url| // within |browser_context|. // This should only be used for process-per-site mode, which can be enabled // globally with a command line flag or per-site, as determined by // SiteInstanceImpl::ShouldUseProcessPerSite. static void RegisterProcessHostForSite( BrowserContext* browser_context, RenderProcessHost* process, const GURL& url); static base::MessageLoop* GetInProcessRendererThreadForTesting(); // This forces a renderer that is running "in process" to shut down. static void ShutDownInProcessRenderer(); static void RegisterRendererMainThreadFactory( RendererMainThreadFactoryFunction create); #if defined(OS_ANDROID) const scoped_refptr& browser_demuxer_android() { return browser_demuxer_android_; } #endif MessagePortMessageFilter* message_port_message_filter() const { return message_port_message_filter_; } void set_is_isolated_guest_for_testing(bool is_isolated_guest) { is_isolated_guest_ = is_isolated_guest; } // Called when the existence of the other renderer process which is connected // to the Worker in this renderer process has changed. // It is only called when "enable-embedded-shared-worker" flag is set. void IncrementWorkerRefCount(); void DecrementWorkerRefCount(); // Establish a connection to a renderer-provided service. See // content/common/mojo/mojo_service_names.h for a list of services. void ConnectTo(const base::StringPiece& service_name, mojo::ScopedMessagePipeHandle handle); template void ConnectTo(const base::StringPiece& service_name, mojo::InterfacePtr* ptr) { mojo::MessagePipe pipe; ptr->Bind(pipe.handle0.Pass()); ConnectTo(service_name, pipe.handle1.Pass()); } protected: // A proxy for our IPC::Channel that lives on the IO thread (see // browser_process.h) scoped_ptr channel_; // True if fast shutdown has been performed on this RPH. bool fast_shutdown_started_; // True if we've posted a DeleteTask and will be deleted soon. bool deleting_soon_; #ifndef NDEBUG // True if this object has deleted itself. bool is_self_deleted_; #endif // The count of currently swapped out but pending RenderViews. We have // started to swap these in, so the renderer process should not exit if // this count is non-zero. int32 pending_views_; private: friend class VisitRelayingRenderProcessHost; void MaybeActivateMojo(); // Creates and adds the IO thread message filters. void CreateMessageFilters(); // Control message handlers. void OnShutdownRequest(); void OnDumpHandlesDone(); void SuddenTerminationChanged(bool enabled); void OnUserMetricsRecordAction(const std::string& action); void OnSavedPageAsMHTML(int job_id, int64 mhtml_file_size); void OnCloseACK(int old_route_id); // CompositorSurfaceBuffersSwapped handler when there's no RWH. void OnCompositorSurfaceBuffersSwappedNoHost( const ViewHostMsg_CompositorSurfaceBuffersSwapped_Params& params); // Generates a command line to be used to spawn a renderer and appends the // results to |*command_line|. void AppendRendererCommandLine(base::CommandLine* command_line) const; // Copies applicable command line switches from the given |browser_cmd| line // flags to the output |renderer_cmd| line flags. Not all switches will be // copied over. void PropagateBrowserCommandLineToRenderer( const base::CommandLine& browser_cmd, base::CommandLine* renderer_cmd) const; // Callers can reduce the RenderProcess' priority. void SetBackgrounded(bool backgrounded); // Handle termination of our process. void ProcessDied(bool already_dead); virtual void OnGpuSwitching() OVERRIDE; #if defined(ENABLE_WEBRTC) // Sends |file_for_transit| to the render process. void SendAecDumpFileToRenderer(IPC::PlatformFileForTransit file_for_transit); void SendDisableAecDumpToRenderer(); #endif // GpuMemoryBuffer allocation handler. void OnAllocateGpuMemoryBuffer(uint32 width, uint32 height, uint32 internalformat, uint32 usage, IPC::Message* reply); void GpuMemoryBufferAllocated(IPC::Message* reply, const gfx::GpuMemoryBufferHandle& handle); scoped_ptr mojo_application_host_; bool mojo_activation_required_; // The registered IPC listener objects. When this list is empty, we should // delete ourselves. IDMap listeners_; // The count of currently visible widgets. Since the host can be a container // for multiple widgets, it uses this count to determine when it should be // backgrounded. int32 visible_widgets_; // Does this process have backgrounded priority. bool backgrounded_; // Used to allow a RenderWidgetHost to intercept various messages on the // IO thread. scoped_refptr widget_helper_; // The filter for GPU-related messages coming from the renderer. // Thread safety note: this field is to be accessed from the UI thread. // We don't keep a reference to it, to avoid it being destroyed on the UI // thread, but we clear this field when we clear channel_. When channel_ goes // away, it posts a task to the IO thread to destroy it there, so we know that // it's valid if non-NULL. GpuMessageFilter* gpu_message_filter_; // The filter for MessagePort messages coming from the renderer. scoped_refptr message_port_message_filter_; // Used in single-process mode. scoped_ptr in_process_renderer_; // True after Init() has been called. We can't just check channel_ because we // also reset that in the case of process termination. bool is_initialized_; // Used to launch and terminate the process without blocking the UI thread. scoped_ptr child_process_launcher_; // Messages we queue while waiting for the process handle. We queue them here // instead of in the channel so that we ensure they're sent after init related // messages that are sent once the process handle is available. This is // because the queued messages may have dependencies on the init messages. std::queue queued_messages_; // The globally-unique identifier for this RPH. int id_; BrowserContext* browser_context_; // Owned by |browser_context_|. StoragePartitionImpl* storage_partition_impl_; // The observers watching our lifetime. ObserverList observers_; // True if the process can be shut down suddenly. If this is true, then we're // sure that all the RenderViews in the process can be shutdown suddenly. If // it's false, then specific RenderViews might still be allowed to be shutdown // suddenly by checking their SuddenTerminationAllowed() flag. This can occur // if one WebContents has an unload event listener but another WebContents in // the same process doesn't. bool sudden_termination_allowed_; // Set to true if we shouldn't send input events. We actually do the // filtering for this at the render widget level. bool ignore_input_events_; // Records the last time we regarded the child process active. base::TimeTicks child_process_activity_time_; // Indicates whether this is a RenderProcessHost of a Browser Plugin guest // renderer. bool is_isolated_guest_; // Forwards messages between WebRTCInternals in the browser process // and PeerConnectionTracker in the renderer process. scoped_refptr peer_connection_tracker_host_; // Prevents the class from being added as a GpuDataManagerImpl observer more // than once. bool gpu_observer_registered_; // Set if a call to Cleanup is required once the RenderProcessHostImpl is no // longer within the RenderProcessHostObserver::RenderProcessExited callbacks. bool delayed_cleanup_needed_; // Indicates whether RenderProcessHostImpl is currently iterating and calling // through RenderProcessHostObserver::RenderProcessExited. bool within_process_died_observer_; // Forwards power state messages to the renderer process. PowerMonitorMessageBroadcaster power_monitor_broadcaster_; scoped_refptr audio_renderer_host_; #if defined(OS_ANDROID) scoped_refptr browser_demuxer_android_; #endif #if defined(ENABLE_WEBRTC) base::Callback webrtc_log_message_callback_; scoped_refptr p2p_socket_dispatcher_host_; WebRtcStopRtpDumpCallback stop_rtp_dump_callback_; #endif // Message filter and dispatcher for screen orientation. ScreenOrientationDispatcherHost* screen_orientation_dispatcher_host_; int worker_ref_count_; // Records the time when the process starts surviving for workers for UMA. base::TimeTicks survive_for_worker_start_time_; base::WeakPtrFactory weak_factory_; #if defined(OS_MACOSX) base::ScopedCFTypeRef last_io_surface_; #endif DISALLOW_COPY_AND_ASSIGN(RenderProcessHostImpl); }; } // namespace content #endif // CONTENT_BROWSER_RENDERER_HOST_BROWSER_RENDER_PROCESS_HOST_IMPL_H_