shell_browser_main_parts.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "extensions/shell/browser/shell_browser_main_parts.h"
  5. #include <memory>
  6. #include <string>
  7. #include "apps/browser_context_keyed_service_factories.h"
  8. #include "base/bind.h"
  9. #include "base/command_line.h"
  10. #include "base/memory/ref_counted.h"
  11. #include "build/build_config.h"
  12. #include "build/chromeos_buildflags.h"
  13. #include "components/keyed_service/content/browser_context_dependency_manager.h"
  14. #include "components/nacl/common/buildflags.h"
  15. #include "components/prefs/pref_service.h"
  16. #include "components/sessions/core/session_id_generator.h"
  17. #include "components/storage_monitor/storage_monitor.h"
  18. #include "components/update_client/update_query_params.h"
  19. #include "content/public/browser/browser_task_traits.h"
  20. #include "content/public/browser/child_process_security_policy.h"
  21. #include "content/public/browser/context_factory.h"
  22. #include "content/public/browser/devtools_agent_host.h"
  23. #include "content/public/browser/media_session_service.h"
  24. #include "content/public/common/content_switches.h"
  25. #include "content/public/common/result_codes.h"
  26. #include "content/shell/browser/shell_devtools_manager_delegate.h"
  27. #include "extensions/browser/browser_context_keyed_service_factories.h"
  28. #include "extensions/browser/extension_system.h"
  29. #include "extensions/browser/updater/update_service.h"
  30. #include "extensions/common/constants.h"
  31. #include "extensions/shell/browser/desktop_controller.h"
  32. #include "extensions/shell/browser/shell_browser_context.h"
  33. #include "extensions/shell/browser/shell_browser_context_keyed_service_factories.h"
  34. #include "extensions/shell/browser/shell_browser_main_delegate.h"
  35. #include "extensions/shell/browser/shell_extension_system.h"
  36. #include "extensions/shell/browser/shell_extension_system_factory.h"
  37. #include "extensions/shell/browser/shell_extensions_browser_client.h"
  38. #include "extensions/shell/browser/shell_prefs.h"
  39. #include "extensions/shell/browser/shell_update_query_params_delegate.h"
  40. #include "extensions/shell/common/shell_extensions_client.h"
  41. #include "extensions/shell/common/switches.h"
  42. #include "ui/base/ime/init/input_method_initializer.h"
  43. #include "ui/base/resource/resource_bundle.h"
  44. #if defined(USE_AURA)
  45. #include "ui/aura/env.h"
  46. #endif
  47. #if BUILDFLAG(IS_LINUX)
  48. #include "device/bluetooth/bluetooth_adapter_factory.h"
  49. #include "device/bluetooth/dbus/dbus_bluez_manager_wrapper_linux.h"
  50. #endif
  51. #if BUILDFLAG(IS_CHROMEOS)
  52. #include "device/bluetooth/bluetooth_adapter_factory.h"
  53. #include "device/bluetooth/dbus/bluez_dbus_manager.h"
  54. #endif
  55. #if BUILDFLAG(IS_CHROMEOS_ASH)
  56. #include "ash/components/disks/disk_mount_manager.h"
  57. #include "chromeos/ash/components/audio/audio_devices_pref_handler_impl.h"
  58. #include "chromeos/ash/components/audio/cras_audio_handler.h"
  59. #include "chromeos/ash/components/dbus/audio/cras_audio_client.h"
  60. #include "chromeos/ash/components/dbus/cros_disks/cros_disks_client.h"
  61. #include "chromeos/ash/components/dbus/dbus_thread_manager.h"
  62. #include "chromeos/ash/components/dbus/hermes/hermes_clients.h"
  63. #include "chromeos/ash/components/dbus/shill/shill_clients.h"
  64. #include "chromeos/ash/components/network/network_handler.h"
  65. #include "chromeos/dbus/power/power_manager_client.h"
  66. #include "extensions/shell/browser/shell_audio_controller_chromeos.h"
  67. #include "extensions/shell/browser/shell_network_controller_chromeos.h"
  68. #endif
  69. #if BUILDFLAG(IS_CHROMEOS_LACROS)
  70. #include "chromeos/lacros/dbus/lacros_dbus_thread_manager.h"
  71. #include "device/bluetooth/dbus/bluez_dbus_thread_manager.h"
  72. #endif
  73. #if BUILDFLAG(ENABLE_NACL)
  74. #include "components/nacl/browser/nacl_browser.h"
  75. #include "components/nacl/browser/nacl_process_host.h"
  76. #include "content/public/browser/browser_thread.h"
  77. #include "extensions/shell/browser/shell_nacl_browser_delegate.h"
  78. #endif
  79. using base::CommandLine;
  80. using content::BrowserContext;
  81. #if BUILDFLAG(ENABLE_NACL)
  82. #endif
  83. namespace extensions {
  84. ShellBrowserMainParts::ShellBrowserMainParts(
  85. ShellBrowserMainDelegate* browser_main_delegate,
  86. bool is_integration_test)
  87. : extension_system_(nullptr),
  88. browser_main_delegate_(browser_main_delegate),
  89. is_integration_test_(is_integration_test) {}
  90. ShellBrowserMainParts::~ShellBrowserMainParts() = default;
  91. void ShellBrowserMainParts::PostCreateMainMessageLoop() {
  92. #if BUILDFLAG(IS_CHROMEOS_ASH)
  93. // Perform initialization of D-Bus objects here rather than in the below
  94. // helper classes so those classes' tests can initialize stub versions of the
  95. // D-Bus objects.
  96. chromeos::DBusThreadManager::Initialize();
  97. dbus::Bus* bus = chromeos::DBusThreadManager::Get()->GetSystemBus();
  98. #elif BUILDFLAG(IS_CHROMEOS_LACROS)
  99. chromeos::LacrosDBusThreadManager::Initialize();
  100. dbus::Bus* bus = chromeos::LacrosDBusThreadManager::Get()->GetSystemBus();
  101. #endif
  102. #if BUILDFLAG(IS_CHROMEOS)
  103. if (bus) {
  104. bluez::BluezDBusManager::Initialize(bus);
  105. } else {
  106. bluez::BluezDBusManager::InitializeFake();
  107. }
  108. #endif // BUILDFLAG(IS_CHROMEOS)
  109. #if BUILDFLAG(IS_CHROMEOS_ASH)
  110. if (bus) {
  111. ash::shill_clients::Initialize(bus);
  112. ash::hermes_clients::Initialize(bus);
  113. ash::CrasAudioClient::Initialize(bus);
  114. ash::CrosDisksClient::Initialize(bus);
  115. chromeos::PowerManagerClient::Initialize(bus);
  116. } else {
  117. ash::shill_clients::InitializeFakes();
  118. ash::hermes_clients::InitializeFakes();
  119. ash::CrasAudioClient::InitializeFake();
  120. ash::CrosDisksClient::InitializeFake();
  121. chromeos::PowerManagerClient::InitializeFake();
  122. }
  123. // Depends on CrosDisksClient.
  124. ash::disks::DiskMountManager::Initialize();
  125. ash::NetworkHandler::Initialize();
  126. network_controller_ = std::make_unique<ShellNetworkController>(
  127. base::CommandLine::ForCurrentProcess()->GetSwitchValueNative(
  128. switches::kAppShellPreferredNetwork));
  129. if (base::CommandLine::ForCurrentProcess()->HasSwitch(
  130. switches::kAppShellAllowRoaming)) {
  131. network_controller_->SetCellularAllowRoaming(true);
  132. }
  133. #elif BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS_LACROS)
  134. // app_shell doesn't need GTK, so the fake input method context can work.
  135. // See crbug.com/381852 and revision fb69f142.
  136. // TODO(michaelpg): Verify this works for target environments.
  137. ui::InitializeInputMethodForTesting();
  138. #else
  139. ui::InitializeInputMethodForTesting();
  140. #endif
  141. #if BUILDFLAG(IS_LINUX)
  142. bluez::DBusBluezManagerWrapperLinux::Initialize();
  143. #endif
  144. }
  145. int ShellBrowserMainParts::PreEarlyInitialization() {
  146. return content::RESULT_CODE_NORMAL_EXIT;
  147. }
  148. int ShellBrowserMainParts::PreCreateThreads() {
  149. // TODO(jamescook): Initialize ash::CrosSettings here?
  150. content::ChildProcessSecurityPolicy::GetInstance()->RegisterWebSafeScheme(
  151. kExtensionScheme);
  152. // Return no error.
  153. return 0;
  154. }
  155. int ShellBrowserMainParts::PreMainMessageLoopRun() {
  156. extensions_client_ = std::make_unique<ShellExtensionsClient>();
  157. ExtensionsClient::Set(extensions_client_.get());
  158. // BrowserContextKeyedAPIServiceFactories require an ExtensionsBrowserClient.
  159. extensions_browser_client_ = std::make_unique<ShellExtensionsBrowserClient>();
  160. ExtensionsBrowserClient::Set(extensions_browser_client_.get());
  161. apps::EnsureBrowserContextKeyedServiceFactoriesBuilt();
  162. EnsureBrowserContextKeyedServiceFactoriesBuilt();
  163. shell::EnsureBrowserContextKeyedServiceFactoriesBuilt();
  164. // Initialize our "profile" equivalent.
  165. browser_context_ = std::make_unique<ShellBrowserContext>();
  166. // app_shell only supports a single user, so all preferences live in the user
  167. // data directory, including the device-wide local state.
  168. local_state_ = shell_prefs::CreateLocalState(browser_context_->GetPath());
  169. sessions::SessionIdGenerator::GetInstance()->Init(local_state_.get());
  170. user_pref_service_ =
  171. shell_prefs::CreateUserPrefService(browser_context_.get());
  172. extensions_browser_client_->InitWithBrowserContext(browser_context_.get(),
  173. user_pref_service_.get());
  174. #if BUILDFLAG(IS_CHROMEOS_ASH)
  175. mojo::PendingRemote<media_session::mojom::MediaControllerManager>
  176. media_controller_manager;
  177. content::GetMediaSessionService().BindMediaControllerManager(
  178. media_controller_manager.InitWithNewPipeAndPassReceiver());
  179. ash::CrasAudioHandler::Initialize(
  180. std::move(media_controller_manager),
  181. base::MakeRefCounted<ash::AudioDevicesPrefHandlerImpl>(
  182. local_state_.get()));
  183. audio_controller_ = std::make_unique<ShellAudioController>();
  184. #endif
  185. // Create BrowserContextKeyedServices now that we have an
  186. // ExtensionsBrowserClient that BrowserContextKeyedAPIServices can query.
  187. BrowserContextDependencyManager::GetInstance()->CreateBrowserContextServices(
  188. browser_context_.get());
  189. #if defined(USE_AURA)
  190. aura::Env::GetInstance()->set_context_factory(content::GetContextFactory());
  191. #endif
  192. storage_monitor::StorageMonitor::Create();
  193. desktop_controller_.reset(
  194. browser_main_delegate_->CreateDesktopController(browser_context_.get()));
  195. // TODO(jamescook): Initialize user_manager::UserManager.
  196. update_query_params_delegate_ =
  197. std::make_unique<ShellUpdateQueryParamsDelegate>();
  198. update_client::UpdateQueryParams::SetDelegate(
  199. update_query_params_delegate_.get());
  200. InitExtensionSystem();
  201. #if BUILDFLAG(ENABLE_NACL)
  202. nacl::NaClBrowser::SetDelegate(
  203. std::make_unique<ShellNaClBrowserDelegate>(browser_context_.get()));
  204. nacl::NaClProcessHost::EarlyStartup();
  205. #endif
  206. content::ShellDevToolsManagerDelegate::StartHttpHandler(
  207. browser_context_.get());
  208. // Skip these steps in integration tests.
  209. if (!is_integration_test_) {
  210. browser_main_delegate_->Start(browser_context_.get());
  211. desktop_controller_->PreMainMessageLoopRun();
  212. }
  213. return content::RESULT_CODE_NORMAL_EXIT;
  214. }
  215. void ShellBrowserMainParts::WillRunMainMessageLoop(
  216. std::unique_ptr<base::RunLoop>& run_loop) {
  217. desktop_controller_->WillRunMainMessageLoop(run_loop);
  218. }
  219. void ShellBrowserMainParts::PostMainMessageLoopRun() {
  220. desktop_controller_->PostMainMessageLoopRun();
  221. // Close apps before shutting down browser context and extensions system.
  222. desktop_controller_->CloseAppWindows();
  223. // NOTE: Please destroy objects in the reverse order of their creation.
  224. browser_main_delegate_->Shutdown();
  225. content::ShellDevToolsManagerDelegate::StopHttpHandler();
  226. BrowserContextDependencyManager::GetInstance()->DestroyBrowserContextServices(
  227. browser_context_.get());
  228. extension_system_ = nullptr;
  229. desktop_controller_.reset();
  230. storage_monitor::StorageMonitor::Destroy();
  231. #if BUILDFLAG(IS_CHROMEOS_ASH)
  232. audio_controller_.reset();
  233. ash::CrasAudioHandler::Shutdown();
  234. #endif
  235. sessions::SessionIdGenerator::GetInstance()->Shutdown();
  236. user_pref_service_->CommitPendingWrite();
  237. user_pref_service_.reset();
  238. local_state_->CommitPendingWrite();
  239. local_state_.reset();
  240. browser_context_.reset();
  241. }
  242. void ShellBrowserMainParts::PostDestroyThreads() {
  243. extensions_browser_client_.reset();
  244. ExtensionsBrowserClient::Set(nullptr);
  245. #if BUILDFLAG(IS_CHROMEOS)
  246. device::BluetoothAdapterFactory::Shutdown();
  247. bluez::BluezDBusManager::Shutdown();
  248. #elif BUILDFLAG(IS_LINUX)
  249. device::BluetoothAdapterFactory::Shutdown();
  250. bluez::DBusBluezManagerWrapperLinux::Shutdown();
  251. #endif
  252. #if BUILDFLAG(IS_CHROMEOS_ASH)
  253. network_controller_.reset();
  254. ash::NetworkHandler::Shutdown();
  255. ash::disks::DiskMountManager::Shutdown();
  256. chromeos::PowerManagerClient::Shutdown();
  257. ash::CrosDisksClient::Shutdown();
  258. ash::CrasAudioClient::Shutdown();
  259. ash::shill_clients::Shutdown();
  260. #endif
  261. #if BUILDFLAG(IS_CHROMEOS_ASH)
  262. chromeos::DBusThreadManager::Shutdown();
  263. #elif BUILDFLAG(IS_CHROMEOS_LACROS)
  264. chromeos::LacrosDBusThreadManager::Shutdown();
  265. #endif
  266. }
  267. void ShellBrowserMainParts::InitExtensionSystem() {
  268. DCHECK(browser_context_);
  269. extension_system_ = static_cast<ShellExtensionSystem*>(
  270. ExtensionSystem::Get(browser_context_.get()));
  271. extension_system_->InitForRegularProfile(true /* extensions_enabled */);
  272. }
  273. } // namespace extensions