blob: 1afdc0012f1ab2cdb2e144d2937ca69fade396eb [file] [log] [blame]
[email protected]60b122d2012-01-09 23:00:071// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]b48c9182011-10-26 18:03:302// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_
6#define CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_
[email protected]b48c9182011-10-26 18:03:307
dcheng59716272016-04-09 05:19:088#include <memory>
9
[email protected]cec95632014-07-02 18:01:5010#include "base/files/file_path.h"
Francois Doray6d3c649692017-06-16 19:20:2511#include "base/gtest_prod_util.h"
avib7348942015-12-25 20:57:1012#include "base/macros.h"
[email protected]57624ab2013-08-01 16:01:5113#include "base/memory/ref_counted.h"
[email protected]cec95632014-07-02 18:01:5014#include "base/timer/timer.h"
avib7348942015-12-25 20:57:1015#include "build/build_config.h"
[email protected]2e5b60a22011-11-28 15:56:4116#include "content/browser/browser_process_sub_thread.h"
[email protected]57624ab2013-08-01 16:01:5117#include "content/public/browser/browser_main_runner.h"
[email protected]b48c9182011-10-26 18:03:3018
sadrul578205fa2016-04-11 22:43:5619#if defined(USE_AURA)
20namespace aura {
21class Env;
22}
23#endif
24
[email protected]b48c9182011-10-26 18:03:3025namespace base {
[email protected]2f3b1cc2014-03-17 23:07:1526class CommandLine;
[email protected]1eb14612013-11-21 01:04:5827class FilePath;
[email protected]89bf27e2013-06-27 18:04:5628class HighResolutionTimerManager;
gab3ee0e442016-12-16 17:43:1129class MemoryPressureMonitor;
[email protected]5e9e96a2013-03-31 02:29:2030class MessageLoop;
[email protected]ed3bf8a62014-04-05 18:55:5731class PowerMonitor;
kylecharee7cefd2017-07-13 16:05:0332class SingleThreadTaskRunner;
[email protected]b48c9182011-10-26 18:03:3033class SystemMonitor;
primiano15960432015-02-05 14:20:2634namespace trace_event {
[email protected]e5a631a2013-09-18 07:33:2735class TraceEventSystemStatsMonitor;
primiano15960432015-02-05 14:20:2636} // namespace trace_event
[email protected]111494e2013-07-24 18:38:2937} // namespace base
[email protected]b48c9182011-10-26 18:03:3038
penghuangcf823972016-12-21 16:01:1339namespace discardable_memory {
40class DiscardableSharedMemoryManager;
41}
42
sadrul059bc532017-07-05 21:22:1643namespace gpu {
44class GpuChannelEstablishFactory;
45}
46
[email protected]67dfea902012-04-03 01:49:0947namespace media {
alokp2cbd4fc2017-05-13 04:13:2448class AudioManager;
olkaef762c92017-02-06 16:45:1649class AudioSystem;
mcasas96388e92016-03-02 02:18:0750#if defined(OS_WIN)
51class SystemMessageWindowWin;
52#elif defined(OS_LINUX) && defined(USE_UDEV)
mcasas9d2063682016-02-11 22:12:3953class DeviceMonitorLinux;
54#endif
[email protected]61f697f2013-08-15 22:02:4055class UserInputMonitor;
mcasas9d03ac2e2016-02-24 17:10:0256#if defined(OS_MACOSX)
57class DeviceMonitorMac;
58#endif
toyoshim59e319712016-10-13 06:43:2959} // namespace media
60
primianoaca468f82017-05-22 13:30:3261namespace memory_instrumentation {
62class CoordinatorImpl;
63} // memory_instrumentation
64
toyoshim78b9d632015-05-08 04:58:3165namespace midi {
toyoshim967340a2016-12-15 06:18:2966class MidiService;
toyoshim78b9d632015-05-08 04:58:3167} // namespace midi
[email protected]67dfea902012-04-03 01:49:0968
amistrycafcdff2016-06-17 03:33:4869namespace mojo {
70namespace edk {
71class ScopedIPCSupport;
72} // namespace edk
73} // namespace mojo
74
[email protected]b48c9182011-10-26 18:03:3075namespace net {
76class NetworkChangeNotifier;
[email protected]111494e2013-07-24 18:38:2977} // namespace net
[email protected]b48c9182011-10-26 18:03:3078
dongseong.hwang16f5a8a42015-08-06 11:00:3079#if defined(USE_OZONE)
julien.isorcef09c3132017-03-24 21:06:1480namespace gfx {
dongseong.hwang16f5a8a42015-08-06 11:00:3081class ClientNativePixmapFactory;
julien.isorcef09c3132017-03-24 21:06:1482} // namespace gfx
dongseong.hwang16f5a8a42015-08-06 11:00:3083#endif
84
fsamuelea6969822017-06-12 21:14:3285namespace viz {
danakj4def4a242017-06-24 01:18:3786class FrameSinkManagerImpl;
Fady Samueldea5e8f2017-07-19 21:41:3387class HostFrameSinkManager;
fsamuelea6969822017-06-12 21:14:3288}
89
[email protected]b48c9182011-10-26 18:03:3090namespace content {
[email protected]b48c9182011-10-26 18:03:3091class BrowserMainParts;
[email protected]2208a74d2012-10-29 17:09:4492class BrowserOnlineStateObserver;
[email protected]c38831a12011-10-28 12:44:4993class BrowserThreadImpl;
scottmg5cbd1cf2016-06-29 02:34:5294class LoaderDelegateImpl;
[email protected]1d232b92012-10-29 17:39:0795class MediaStreamManager;
[email protected]ea114722012-03-12 01:11:2596class ResourceDispatcherHostImpl;
ananta73296c572016-08-15 21:58:2597class SaveFileManager;
benff461632016-10-06 14:27:3398class ServiceManagerContext;
[email protected]fcb8e0212012-10-29 11:57:1899class SpeechRecognitionManagerImpl;
[email protected]232e09d2013-08-27 15:29:56100class StartupTaskRunner;
Scott Haseley7a02fce2017-08-01 21:55:01101class SwapMetricsDriver;
[email protected]97646c92012-07-31 20:30:08102struct MainFunctionParams;
103
jonross36980292014-10-08 15:55:10104#if defined(OS_ANDROID)
105class ScreenOrientationDelegate;
[email protected]97646c92012-07-31 20:30:08106#endif
[email protected]b48c9182011-10-26 18:03:30107
thomasanderson62ba78ff2016-10-01 02:03:42108#if defined(USE_X11) && !defined(OS_CHROMEOS)
109namespace internal {
110class GpuDataManagerVisualProxy;
111}
112#endif
113
[email protected]53ab4802012-04-12 22:14:35114// Implements the main browser loop stages called from BrowserMainRunner.
[email protected]b48c9182011-10-26 18:03:30115// See comments in browser_main_parts.h for additional info.
[email protected]89acda82013-06-25 20:52:50116class CONTENT_EXPORT BrowserMainLoop {
[email protected]b48c9182011-10-26 18:03:30117 public:
[email protected]aa445462013-06-21 17:12:36118 // Returns the current instance. This is used to get access to the getters
119 // that return objects which are owned by this class.
120 static BrowserMainLoop* GetInstance();
121
[email protected]46488322012-10-30 03:22:20122 explicit BrowserMainLoop(const MainFunctionParams& parameters);
[email protected]b48c9182011-10-26 18:03:30123 virtual ~BrowserMainLoop();
124
125 void Init();
126
127 void EarlyInitialization();
thestig7e202d1a2015-05-27 21:54:55128
[email protected]d957b102014-04-25 20:17:19129 // Initializes the toolkit. Returns whether the toolkit initialization was
130 // successful or not.
131 bool InitializeToolkit();
thestig7e202d1a2015-05-27 21:54:55132
133 void PreMainMessageLoopStart();
[email protected]b48c9182011-10-26 18:03:30134 void MainMessageLoopStart();
thestig7e202d1a2015-05-27 21:54:55135 void PostMainMessageLoopStart();
bcwhiteda097d32017-01-12 23:55:03136 void PreShutdown();
[email protected]f573ed6b2012-02-10 15:58:52137
[email protected]232e09d2013-08-27 15:29:56138 // Create and start running the tasks we need to complete startup. Note that
139 // this can be called more than once (currently only on Android) if we get a
140 // request for synchronous startup while the tasks created by asynchronous
141 // startup are still running.
[email protected]57624ab2013-08-01 16:01:51142 void CreateStartupTasks();
[email protected]f573ed6b2012-02-10 15:58:52143
144 // Perform the default message loop run logic.
145 void RunMainMessageLoopParts();
146
147 // Performs the shutdown sequence, starting with PostMainMessageLoopRun
148 // through stopping threads to PostDestroyThreads.
149 void ShutdownThreadsAndCleanUp();
[email protected]b48c9182011-10-26 18:03:30150
151 int GetResultCode() const { return result_code_; }
152
[email protected]aa445462013-06-21 17:12:36153 media::AudioManager* audio_manager() const { return audio_manager_.get(); }
olkaef762c92017-02-06 16:45:16154 media::AudioSystem* audio_system() const { return audio_system_.get(); }
[email protected]aa445462013-06-21 17:12:36155 MediaStreamManager* media_stream_manager() const {
156 return media_stream_manager_.get();
157 }
[email protected]61f697f2013-08-15 22:02:40158 media::UserInputMonitor* user_input_monitor() const {
159 return user_input_monitor_.get();
160 }
penghuangcf823972016-12-21 16:01:13161 discardable_memory::DiscardableSharedMemoryManager*
162 discardable_shared_memory_manager() const {
163 return discardable_shared_memory_manager_.get();
164 }
toyoshim967340a2016-12-15 06:18:29165 midi::MidiService* midi_service() const { return midi_service_.get(); }
[email protected]52e456b92012-02-23 17:13:18166
zhenwc074d282015-08-31 17:28:17167 bool is_tracing_startup_for_duration() const {
168 return is_tracing_startup_for_duration_;
169 }
[email protected]1eb14612013-11-21 01:04:58170
[email protected]cec95632014-07-02 18:01:50171 const base::FilePath& startup_trace_file() const {
172 return startup_trace_file_;
173 }
174
kylecharee7cefd2017-07-13 16:05:03175 // Returns the task runner for tasks that that are critical to producing a new
176 // CompositorFrame on resize. On Mac this will be the task runner provided by
177 // WindowResizeHelperMac, on other platforms it will just be the thread task
178 // runner.
179 scoped_refptr<base::SingleThreadTaskRunner> GetResizeTaskRunner();
180
sadrul059bc532017-07-05 21:22:16181 gpu::GpuChannelEstablishFactory* gpu_channel_establish_factory() const;
182
Bo Liu79c92c3b2017-06-28 18:52:25183#if defined(OS_ANDROID)
184 void SynchronouslyFlushStartupTasks();
185#endif // OS_ANDROID
186
fsamuelea6969822017-06-12 21:14:32187#if !defined(OS_ANDROID)
danakj4def4a242017-06-24 01:18:37188 // TODO(fsamuel): We should find an object to own HostFrameSinkManager on all
fsamuelea6969822017-06-12 21:14:32189 // platforms including Android. See http://crbug.com/732507.
danakj4def4a242017-06-24 01:18:37190 viz::HostFrameSinkManager* host_frame_sink_manager() const {
191 return host_frame_sink_manager_.get();
fsamuelea6969822017-06-12 21:14:32192 }
danakjaee67172017-06-13 16:37:02193
194 // TODO(crbug.com/657959): This will be removed once there are no users, as
195 // SurfaceManager is being moved out of process.
Fady Samueldea5e8f2017-07-19 21:41:33196 viz::FrameSinkManagerImpl* GetFrameSinkManager() const;
fsamuelea6969822017-06-12 21:14:32197#endif
198
[email protected]cec95632014-07-02 18:01:50199 void StopStartupTracingTimer();
200
[email protected]08f2c54c2014-03-12 09:27:25201#if defined(OS_MACOSX) && !defined(OS_IOS)
mcasas9d03ac2e2016-02-24 17:10:02202 media::DeviceMonitorMac* device_monitor_mac() const {
[email protected]08f2c54c2014-03-12 09:27:25203 return device_monitor_mac_.get();
204 }
205#endif
206
[email protected]b48c9182011-10-26 18:03:30207 private:
Francois Doray6d3c649692017-06-16 19:20:25208 FRIEND_TEST_ALL_PREFIXES(BrowserMainLoopTest, CreateThreadsInSingleProcess);
209
[email protected]b48c9182011-10-26 18:03:30210 void InitializeMainThread();
211
[email protected]57624ab2013-08-01 16:01:51212 // Called just before creating the threads
213 int PreCreateThreads();
214
215 // Create all secondary threads.
216 int CreateThreads();
217
[email protected]99907362012-01-11 05:41:40218 // Called right after the browser threads have been started.
[email protected]57624ab2013-08-01 16:01:51219 int BrowserThreadsStarted();
220
221 int PreMainMessageLoopRun();
[email protected]99907362012-01-11 05:41:40222
[email protected]f573ed6b2012-02-10 15:58:52223 void MainMessageLoopRun();
224
sadrula15cfccb2016-08-08 18:04:07225 void InitializeMojo();
[email protected]cec95632014-07-02 18:01:50226 base::FilePath GetStartupTraceFileName(
227 const base::CommandLine& command_line) const;
zhenwc074d282015-08-31 17:28:17228 void InitStartupTracingForDuration(const base::CommandLine& command_line);
[email protected]cec95632014-07-02 18:01:50229 void EndStartupTracing();
[email protected]1eb14612013-11-21 01:04:58230
alokp1f499672016-04-19 15:26:28231 void CreateAudioManager();
alokp2cbd4fc2017-05-13 04:13:24232
boliu7439d042015-01-27 22:51:11233 bool UsingInProcessGpu() const;
thestig7e202d1a2015-05-27 21:54:55234
bashi58dd2fa2016-10-17 00:01:07235 void InitializeMemoryManagementComponent();
236
thestig7e202d1a2015-05-27 21:54:55237 // Quick reference for initialization order:
238 // Constructor
239 // Init()
240 // EarlyInitialization()
241 // InitializeToolkit()
242 // PreMainMessageLoopStart()
243 // MainMessageLoopStart()
244 // InitializeMainThread()
245 // PostMainMessageLoopStart()
zhenwc074d282015-08-31 17:28:17246 // InitStartupTracingForDuration()
thestig7e202d1a2015-05-27 21:54:55247 // CreateStartupTasks()
248 // PreCreateThreads()
249 // CreateThreads()
250 // BrowserThreadsStarted()
mfomitchev202f333b2016-05-26 01:15:45251 // PreMainMessageLoopRun()
boliu7439d042015-01-27 22:51:11252
[email protected]b48c9182011-10-26 18:03:30253 // Members initialized on construction ---------------------------------------
[email protected]46488322012-10-30 03:22:20254 const MainFunctionParams& parameters_;
[email protected]2f3b1cc2014-03-17 23:07:15255 const base::CommandLine& parsed_command_line_;
[email protected]b48c9182011-10-26 18:03:30256 int result_code_;
thestig7e202d1a2015-05-27 21:54:55257 bool created_threads_; // True if the non-UI threads were created.
zhenwc074d282015-08-31 17:28:17258 bool is_tracing_startup_for_duration_;
[email protected]b48c9182011-10-26 18:03:30259
[email protected]b48c9182011-10-26 18:03:30260 // Members initialized in |MainMessageLoopStart()| ---------------------------
dcheng59716272016-04-09 05:19:08261 std::unique_ptr<base::MessageLoop> main_message_loop_;
thestig7e202d1a2015-05-27 21:54:55262
263 // Members initialized in |PostMainMessageLoopStart()| -----------------------
dcheng59716272016-04-09 05:19:08264 std::unique_ptr<base::SystemMonitor> system_monitor_;
265 std::unique_ptr<base::PowerMonitor> power_monitor_;
266 std::unique_ptr<base::HighResolutionTimerManager> hi_res_timer_manager_;
267 std::unique_ptr<net::NetworkChangeNotifier> network_change_notifier_;
thestig7e202d1a2015-05-27 21:54:55268
[email protected]bff327f2012-03-11 22:17:19269 // Per-process listener for online state changes.
dcheng59716272016-04-09 05:19:08270 std::unique_ptr<BrowserOnlineStateObserver> online_state_observer_;
thestig7e202d1a2015-05-27 21:54:55271
dcheng59716272016-04-09 05:19:08272 std::unique_ptr<base::trace_event::TraceEventSystemStatsMonitor>
thestig7e202d1a2015-05-27 21:54:55273 system_stats_monitor_;
274
sadrul578205fa2016-04-11 22:43:56275#if defined(USE_AURA)
276 std::unique_ptr<aura::Env> env_;
277#endif
278
jonross36980292014-10-08 15:55:10279#if defined(OS_ANDROID)
280 // Android implementation of ScreenOrientationDelegate
dcheng59716272016-04-09 05:19:08281 std::unique_ptr<ScreenOrientationDelegate> screen_orientation_delegate_;
jonross36980292014-10-08 15:55:10282#endif
chrishadc837f52015-05-15 03:09:06283
zhenwc074d282015-08-31 17:28:17284 // Members initialized in |InitStartupTracingForDuration()| ------------------
thestig7e202d1a2015-05-27 21:54:55285 base::FilePath startup_trace_file_;
[email protected]50462bf02011-11-21 19:13:31286
thestig7e202d1a2015-05-27 21:54:55287 // This timer initiates trace file saving.
danakj8c3eb802015-09-24 07:53:00288 base::OneShotTimer startup_trace_timer_;
thestig7e202d1a2015-05-27 21:54:55289
290 // Members initialized in |Init()| -------------------------------------------
291 // Destroy |parts_| before |main_message_loop_| (required) and before other
292 // classes constructed in content (but after |main_thread_|).
dcheng59716272016-04-09 05:19:08293 std::unique_ptr<BrowserMainParts> parts_;
[email protected]50462bf02011-11-21 19:13:31294
295 // Members initialized in |InitializeMainThread()| ---------------------------
thestig7e202d1a2015-05-27 21:54:55296 // This must get destroyed before other threads that are created in |parts_|.
dcheng59716272016-04-09 05:19:08297 std::unique_ptr<BrowserThreadImpl> main_thread_;
[email protected]60b122d2012-01-09 23:00:07298
thestig7e202d1a2015-05-27 21:54:55299 // Members initialized in |CreateStartupTasks()| -----------------------------
dcheng59716272016-04-09 05:19:08300 std::unique_ptr<StartupTaskRunner> startup_task_runner_;
[email protected]99907362012-01-11 05:41:40301
thestig7e202d1a2015-05-27 21:54:55302 // Members initialized in |PreCreateThreads()| -------------------------------
303 // Torn down in ShutdownThreadsAndCleanUp.
dcheng59716272016-04-09 05:19:08304 std::unique_ptr<base::MemoryPressureMonitor> memory_pressure_monitor_;
Scott Haseley7a02fce2017-08-01 21:55:01305 std::unique_ptr<SwapMetricsDriver> swap_metrics_driver_;
thomasanderson62ba78ff2016-10-01 02:03:42306#if defined(USE_X11) && !(OS_CHROMEOS)
307 std::unique_ptr<internal::GpuDataManagerVisualProxy>
308 gpu_data_manager_visual_proxy_;
309#endif
thestig7e202d1a2015-05-27 21:54:55310
311 // Members initialized in |CreateThreads()| ----------------------------------
Gabriel Charettec0cdb672017-06-13 17:24:42312 // Only the IO thread is a real thread by default, other BrowserThreads are
313 // redirected to TaskScheduler under the hood.
dcheng59716272016-04-09 05:19:08314 std::unique_ptr<BrowserProcessSubThread> io_thread_;
Gabriel Charettec0cdb672017-06-13 17:24:42315#if defined(OS_ANDROID)
316 // On Android, the PROCESS_LAUNCHER thread is handled by Java,
317 // |process_launcher_thread_| is merely a proxy to the real message loop.
318 std::unique_ptr<BrowserProcessSubThread> process_launcher_thread_;
319#elif defined(OS_WIN)
320 // TaskScheduler doesn't support async I/O on Windows as CACHE thread is
321 // the only user and this use case is going away in
322 // https://codereview.chromium.org/2216583003/.
323 // TODO(gavinp): Remove this (and thus enable redirection of the CACHE thread
324 // on Windows) once that CL lands.
325 std::unique_ptr<BrowserProcessSubThread> cache_thread_;
326#endif
thestig7e202d1a2015-05-27 21:54:55327
328 // Members initialized in |BrowserThreadsStarted()| --------------------------
benff461632016-10-06 14:27:33329 std::unique_ptr<ServiceManagerContext> service_manager_context_;
amistrycafcdff2016-06-17 03:33:48330 std::unique_ptr<mojo::edk::ScopedIPCSupport> mojo_ipc_support_;
[email protected]b48c9182011-10-26 18:03:30331
thestig7e202d1a2015-05-27 21:54:55332 // |user_input_monitor_| has to outlive |audio_manager_|, so declared first.
dcheng59716272016-04-09 05:19:08333 std::unique_ptr<media::UserInputMonitor> user_input_monitor_;
alokp2cbd4fc2017-05-13 04:13:24334 std::unique_ptr<media::AudioManager> audio_manager_;
olkaef762c92017-02-06 16:45:16335 // Calls to |audio_system_| must not be posted to the audio thread if it
olka3dfb4cf2017-04-11 15:43:28336 // differs from the UI one. See http://crbug.com/705455.
olkaef762c92017-02-06 16:45:16337 std::unique_ptr<media::AudioSystem> audio_system_;
[email protected]cec95632014-07-02 18:01:50338
toyoshim967340a2016-12-15 06:18:29339 std::unique_ptr<midi::MidiService> midi_service_;
thestig7e202d1a2015-05-27 21:54:55340
Kevin Marshallf7882372017-06-06 00:14:34341 // Must be deleted on the IO thread.
342 std::unique_ptr<SpeechRecognitionManagerImpl> speech_recognition_manager_;
343
mcasas96388e92016-03-02 02:18:07344#if defined(OS_WIN)
dcheng59716272016-04-09 05:19:08345 std::unique_ptr<media::SystemMessageWindowWin> system_message_window_;
mcasas96388e92016-03-02 02:18:07346#elif defined(OS_LINUX) && defined(USE_UDEV)
dcheng59716272016-04-09 05:19:08347 std::unique_ptr<media::DeviceMonitorLinux> device_monitor_linux_;
thestig7e202d1a2015-05-27 21:54:55348#elif defined(OS_MACOSX) && !defined(OS_IOS)
dcheng59716272016-04-09 05:19:08349 std::unique_ptr<media::DeviceMonitorMac> device_monitor_mac_;
thestig7e202d1a2015-05-27 21:54:55350#endif
dongseong.hwang16f5a8a42015-08-06 11:00:30351#if defined(USE_OZONE)
julien.isorcef09c3132017-03-24 21:06:14352 std::unique_ptr<gfx::ClientNativePixmapFactory> client_native_pixmap_factory_;
dongseong.hwang16f5a8a42015-08-06 11:00:30353#endif
thestig7e202d1a2015-05-27 21:54:55354
scottmg5cbd1cf2016-06-29 02:34:52355 std::unique_ptr<LoaderDelegateImpl> loader_delegate_;
dcheng59716272016-04-09 05:19:08356 std::unique_ptr<ResourceDispatcherHostImpl> resource_dispatcher_host_;
357 std::unique_ptr<MediaStreamManager> media_stream_manager_;
penghuangcf823972016-12-21 16:01:13358 std::unique_ptr<discardable_memory::DiscardableSharedMemoryManager>
359 discardable_shared_memory_manager_;
ananta73296c572016-08-15 21:58:25360 scoped_refptr<SaveFileManager> save_file_manager_;
chiniforooshan6e4c5072017-03-17 07:56:56361 std::unique_ptr<memory_instrumentation::CoordinatorImpl>
362 memory_instrumentation_coordinator_;
fsamuelea6969822017-06-12 21:14:32363#if !defined(OS_ANDROID)
danakj4def4a242017-06-24 01:18:37364 std::unique_ptr<viz::HostFrameSinkManager> host_frame_sink_manager_;
danakjaee67172017-06-13 16:37:02365 // This is owned here so that SurfaceManager will be accessible in process
366 // when display is in the same process. Other than using SurfaceManager,
367 // access to |in_process_frame_sink_manager_| should happen via
danakj4def4a242017-06-24 01:18:37368 // |host_frame_sink_manager_| instead which uses Mojo. See
danakjaee67172017-06-13 16:37:02369 // http://crbug.com/657959.
Alex Zhang96cb9e712017-07-07 21:03:47370 std::unique_ptr<viz::FrameSinkManagerImpl> frame_sink_manager_impl_;
fsamuelea6969822017-06-12 21:14:32371#endif
thestig7e202d1a2015-05-27 21:54:55372
373 // DO NOT add members here. Add them to the right categories above.
[email protected]1eb14612013-11-21 01:04:58374
[email protected]b48c9182011-10-26 18:03:30375 DISALLOW_COPY_AND_ASSIGN(BrowserMainLoop);
376};
377
378} // namespace content
379
380#endif // CONTENT_BROWSER_BROWSER_MAIN_LOOP_H_