cast_content_browser_client.cc 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942
  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 "chromecast/browser/cast_content_browser_client.h"
  5. #include <stddef.h>
  6. #include <utility>
  7. #include "base/base_switches.h"
  8. #include "base/bind.h"
  9. #include "base/callback.h"
  10. #include "base/command_line.h"
  11. #include "base/feature_list.h"
  12. #include "base/files/scoped_file.h"
  13. #include "base/i18n/rtl.h"
  14. #include "base/logging.h"
  15. #include "base/message_loop/message_pump_type.h"
  16. #include "base/path_service.h"
  17. #include "base/strings/string_number_conversions.h"
  18. #include "base/strings/utf_string_conversions.h"
  19. #include "base/threading/thread_task_runner_handle.h"
  20. #include "base/unguessable_token.h"
  21. #include "build/build_config.h"
  22. #include "chromecast/base/cast_constants.h"
  23. #include "chromecast/base/cast_features.h"
  24. #include "chromecast/base/cast_paths.h"
  25. #include "chromecast/base/chromecast_switches.h"
  26. #include "chromecast/base/pref_names.h"
  27. #include "chromecast/browser/application_media_info_manager.h"
  28. #include "chromecast/browser/browser_buildflags.h"
  29. #include "chromecast/browser/cast_browser_context.h"
  30. #include "chromecast/browser/cast_browser_main_parts.h"
  31. #include "chromecast/browser/cast_browser_process.h"
  32. #include "chromecast/browser/cast_feature_list_creator.h"
  33. #include "chromecast/browser/cast_http_user_agent_settings.h"
  34. #include "chromecast/browser/cast_navigation_ui_data.h"
  35. #include "chromecast/browser/cast_network_contexts.h"
  36. #include "chromecast/browser/cast_overlay_manifests.h"
  37. #include "chromecast/browser/cast_quota_permission_context.h"
  38. #include "chromecast/browser/cast_session_id_map.h"
  39. #include "chromecast/browser/cast_web_contents.h"
  40. #include "chromecast/browser/cast_web_preferences.h"
  41. #include "chromecast/browser/cast_web_service.h"
  42. #include "chromecast/browser/default_navigation_throttle.h"
  43. #include "chromecast/browser/devtools/cast_devtools_manager_delegate.h"
  44. #include "chromecast/browser/general_audience_browsing_navigation_throttle.h"
  45. #include "chromecast/browser/general_audience_browsing_service.h"
  46. #include "chromecast/browser/media/media_caps_impl.h"
  47. #include "chromecast/browser/service/cast_service_simple.h"
  48. #include "chromecast/browser/service_connector.h"
  49. #include "chromecast/browser/service_manager_connection.h"
  50. #include "chromecast/browser/service_manager_context.h"
  51. #include "chromecast/common/cors_exempt_headers.h"
  52. #include "chromecast/common/global_descriptors.h"
  53. #include "chromecast/common/user_agent.h"
  54. #include "chromecast/external_mojo/broker_service/broker_service.h"
  55. #include "chromecast/media/audio/cast_audio_manager.h"
  56. #include "chromecast/media/cdm/cast_cdm_factory.h"
  57. #include "chromecast/media/cdm/cast_cdm_origin_provider.h"
  58. #include "chromecast/media/cma/backend/cma_backend_factory_impl.h"
  59. #include "chromecast/media/common/media_pipeline_backend_manager.h"
  60. #include "chromecast/media/common/media_resource_tracker.h"
  61. #include "chromecast/media/service/cast_renderer.h"
  62. #include "chromecast/media/service/mojom/video_geometry_setter.mojom.h"
  63. #include "chromecast/public/media/media_pipeline_backend.h"
  64. #include "components/prefs/pref_service.h"
  65. #include "components/url_rewrite/browser/url_request_rewrite_rules_manager.h"
  66. #include "components/url_rewrite/common/url_loader_throttle.h"
  67. #include "content/public/browser/browser_task_traits.h"
  68. #include "content/public/browser/browser_thread.h"
  69. #include "content/public/browser/certificate_request_result_type.h"
  70. #include "content/public/browser/client_certificate_delegate.h"
  71. #include "content/public/browser/navigation_handle.h"
  72. #include "content/public/browser/navigation_ui_data.h"
  73. #include "content/public/browser/render_frame_host.h"
  74. #include "content/public/browser/render_process_host.h"
  75. #include "content/public/browser/site_instance.h"
  76. #include "content/public/browser/storage_partition.h"
  77. #include "content/public/browser/web_contents.h"
  78. #include "content/public/browser/web_ui_url_loader_factory.h"
  79. #include "content/public/common/content_descriptors.h"
  80. #include "content/public/common/content_features.h"
  81. #include "content/public/common/content_switches.h"
  82. #include "content/public/common/url_constants.h"
  83. #include "media/audio/audio_thread_impl.h"
  84. #include "media/base/media_switches.h"
  85. #include "media/gpu/buildflags.h"
  86. #include "media/mojo/services/mojo_renderer_service.h"
  87. #include "mojo/public/cpp/bindings/pending_receiver.h"
  88. #include "net/cert/x509_certificate.h"
  89. #include "net/ssl/ssl_cert_request_info.h"
  90. #include "net/ssl/ssl_private_key.h"
  91. #include "net/url_request/url_request_context_getter.h"
  92. #include "services/metrics/public/cpp/ukm_source_id.h"
  93. #include "services/network/public/cpp/network_switches.h"
  94. #include "third_party/blink/public/common/features.h"
  95. #include "third_party/blink/public/common/web_preferences/web_preferences.h"
  96. #include "ui/display/display.h"
  97. #include "ui/display/screen.h"
  98. #include "ui/gl/gl_switches.h"
  99. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_ANDROID)
  100. #include "components/crash/content/browser/crash_handler_host_linux.h"
  101. #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS) ||
  102. // BUILDFLAG(IS_ANDROID)
  103. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  104. #include "components/crash/core/app/breakpad_linux.h"
  105. #endif // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  106. #if BUILDFLAG(IS_ANDROID)
  107. #include "chromecast/media/audio/cast_audio_manager_android.h" // nogncheck
  108. #include "components/cdm/browser/cdm_message_filter_android.h"
  109. #include "components/crash/core/app/crashpad.h"
  110. #include "media/audio/android/audio_manager_android.h"
  111. #include "media/audio/audio_features.h"
  112. #else
  113. #include "chromecast/browser/memory_pressure_controller_impl.h"
  114. #endif // BUILDFLAG(IS_ANDROID)
  115. #if defined(USE_ALSA)
  116. #include "chromecast/media/audio/cast_audio_manager_alsa.h" // nogncheck
  117. #endif // defined(USE_ALSA)
  118. #if BUILDFLAG(ENABLE_CAST_RENDERER)
  119. #include "base/task/sequenced_task_runner.h"
  120. #include "chromecast/media/service/video_geometry_setter_service.h"
  121. #endif // BUILDFLAG(ENABLE_CAST_RENDERER)
  122. #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
  123. #include "device/bluetooth/cast/bluetooth_adapter_cast.h"
  124. #endif
  125. namespace chromecast {
  126. namespace shell {
  127. CastContentBrowserClient::CastContentBrowserClient(
  128. CastFeatureListCreator* cast_feature_list_creator)
  129. :
  130. #if BUILDFLAG(ENABLE_CAST_RENDERER)
  131. video_geometry_setter_service_(
  132. std::unique_ptr<media::VideoGeometrySetterService,
  133. base::OnTaskRunnerDeleter>(
  134. nullptr,
  135. base::OnTaskRunnerDeleter(nullptr))),
  136. #endif // BUILDFLAG(ENABLE_CAST_RENDERER)
  137. cast_browser_main_parts_(nullptr),
  138. cast_network_contexts_(
  139. std::make_unique<CastNetworkContexts>(GetCorsExemptHeadersList())),
  140. cast_feature_list_creator_(cast_feature_list_creator) {
  141. cast_feature_list_creator_->SetExtraEnableFeatures({
  142. ::media::kInternalMediaSession, features::kNetworkServiceInProcess,
  143. #if BUILDFLAG(IS_ANDROID) && BUILDFLAG(ENABLE_VIDEO_CAPTURE_SERVICE)
  144. features::kMojoVideoCapture,
  145. #endif
  146. #if BUILDFLAG(USE_V4L2_CODEC)
  147. // Enable accelerated video decode if v4l2 codec is supported.
  148. ::media::kVaapiVideoDecodeLinux,
  149. #endif // BUILDFLAG(USE_V4L2_CODEC)
  150. });
  151. #if BUILDFLAG(IS_ANDROID)
  152. cast_feature_list_creator_->SetExtraDisableFeatures({
  153. // Disable AAudio improve AV sync performance.
  154. ::features::kUseAAudioDriver,
  155. });
  156. #endif
  157. }
  158. CastContentBrowserClient::~CastContentBrowserClient() {
  159. DCHECK(!media_resource_tracker_)
  160. << "ResetMediaResourceTracker was not called";
  161. cast_network_contexts_.reset();
  162. }
  163. std::unique_ptr<ServiceConnector>
  164. CastContentBrowserClient::CreateServiceConnector() {
  165. return std::make_unique<ServiceConnector>();
  166. }
  167. std::unique_ptr<CastService> CastContentBrowserClient::CreateCastService(
  168. content::BrowserContext* browser_context,
  169. CastSystemMemoryPressureEvaluatorAdjuster*
  170. cast_system_memory_pressure_evaluator_adjuster,
  171. PrefService* pref_service,
  172. media::VideoPlaneController* video_plane_controller,
  173. CastWindowManager* window_manager,
  174. CastWebService* web_service,
  175. DisplaySettingsManager* display_settings_manager) {
  176. return std::make_unique<CastServiceSimple>(web_service);
  177. }
  178. media::VideoModeSwitcher* CastContentBrowserClient::GetVideoModeSwitcher() {
  179. return nullptr;
  180. }
  181. void CastContentBrowserClient::InitializeURLLoaderThrottleDelegate() {}
  182. void CastContentBrowserClient::SetPersistentCookieAccessSettings(
  183. PrefService* pref_service) {}
  184. scoped_refptr<base::SingleThreadTaskRunner>
  185. CastContentBrowserClient::GetMediaTaskRunner() {
  186. if (!media_thread_) {
  187. media_thread_.reset(new base::Thread("CastMediaThread"));
  188. base::Thread::Options options;
  189. // We need the media thread to be IO-capable to use the mixer service.
  190. options.message_pump_type = base::MessagePumpType::IO;
  191. options.thread_type = base::ThreadType::kRealtimeAudio;
  192. CHECK(media_thread_->StartWithOptions(std::move(options)));
  193. // Start the media_resource_tracker as soon as the media thread is created.
  194. // There are services that run on the media thread that depend on it,
  195. // and we want to initialize it with the correct task runner before any
  196. // tasks that might use it are posted to the media thread.
  197. media_resource_tracker_ = new media::MediaResourceTracker(
  198. base::ThreadTaskRunnerHandle::Get(), media_thread_->task_runner());
  199. }
  200. return media_thread_->task_runner();
  201. }
  202. media::VideoResolutionPolicy*
  203. CastContentBrowserClient::GetVideoResolutionPolicy() {
  204. return nullptr;
  205. }
  206. media::CmaBackendFactory* CastContentBrowserClient::GetCmaBackendFactory() {
  207. DCHECK(GetMediaTaskRunner()->BelongsToCurrentThread());
  208. if (!cma_backend_factory_) {
  209. cma_backend_factory_ = std::make_unique<media::CmaBackendFactoryImpl>(
  210. media_pipeline_backend_manager());
  211. }
  212. return cma_backend_factory_.get();
  213. }
  214. media::MediaResourceTracker*
  215. CastContentBrowserClient::media_resource_tracker() {
  216. DCHECK(media_thread_);
  217. return media_resource_tracker_;
  218. }
  219. void CastContentBrowserClient::ResetMediaResourceTracker() {
  220. media_resource_tracker_->FinalizeAndDestroy();
  221. media_resource_tracker_ = nullptr;
  222. }
  223. media::MediaPipelineBackendManager*
  224. CastContentBrowserClient::media_pipeline_backend_manager() {
  225. DCHECK(cast_browser_main_parts_);
  226. return cast_browser_main_parts_->media_pipeline_backend_manager();
  227. }
  228. std::unique_ptr<::media::AudioManager>
  229. CastContentBrowserClient::CreateAudioManager(
  230. ::media::AudioLogFactory* audio_log_factory) {
  231. // Create the audio thread and initialize the CastSessionIdMap. We need to
  232. // initialize the CastSessionIdMap as soon as possible, so that the task
  233. // runner gets set before any calls to it.
  234. auto audio_thread = std::make_unique<::media::AudioThreadImpl>();
  235. auto* cast_session_id_map =
  236. shell::CastSessionIdMap::GetInstance(audio_thread->GetTaskRunner());
  237. #if defined(USE_ALSA)
  238. return std::make_unique<media::CastAudioManagerAlsa>(
  239. std::move(audio_thread), audio_log_factory, cast_session_id_map,
  240. base::BindRepeating(&CastContentBrowserClient::GetCmaBackendFactory,
  241. base::Unretained(this)),
  242. content::GetUIThreadTaskRunner({}), GetMediaTaskRunner(),
  243. browser_main_parts()->connector(),
  244. BUILDFLAG(ENABLE_CAST_AUDIO_MANAGER_MIXER));
  245. #elif BUILDFLAG(IS_ANDROID)
  246. if (base::FeatureList::IsEnabled(kEnableChromeAudioManagerAndroid)) {
  247. LOG(INFO) << "Use AudioManagerAndroid instead of CastAudioManagerAndroid.";
  248. return std::make_unique<::media::AudioManagerAndroid>(
  249. std::move(audio_thread), audio_log_factory);
  250. }
  251. return std::make_unique<media::CastAudioManagerAndroid>(
  252. std::move(audio_thread), audio_log_factory, cast_session_id_map,
  253. base::BindRepeating(&CastContentBrowserClient::GetCmaBackendFactory,
  254. base::Unretained(this)),
  255. GetMediaTaskRunner(), browser_main_parts()->connector());
  256. #else
  257. return std::make_unique<media::CastAudioManager>(
  258. std::move(audio_thread), audio_log_factory, cast_session_id_map,
  259. base::BindRepeating(&CastContentBrowserClient::GetCmaBackendFactory,
  260. base::Unretained(this)),
  261. content::GetUIThreadTaskRunner({}), GetMediaTaskRunner(),
  262. browser_main_parts()->connector(),
  263. BUILDFLAG(ENABLE_CAST_AUDIO_MANAGER_MIXER));
  264. #endif
  265. }
  266. bool CastContentBrowserClient::OverridesAudioManager() {
  267. return true;
  268. }
  269. std::unique_ptr<::media::CdmFactory> CastContentBrowserClient::CreateCdmFactory(
  270. ::media::mojom::FrameInterfaceFactory* frame_interfaces) {
  271. url::Origin cdm_origin;
  272. if (!CastCdmOriginProvider::GetCdmOrigin(frame_interfaces, &cdm_origin))
  273. return nullptr;
  274. return std::make_unique<media::CastCdmFactory>(
  275. GetMediaTaskRunner(), cdm_origin, media_resource_tracker());
  276. }
  277. media::MediaCapsImpl* CastContentBrowserClient::media_caps() {
  278. DCHECK(cast_browser_main_parts_);
  279. return cast_browser_main_parts_->media_caps();
  280. }
  281. #if !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
  282. scoped_refptr<device::BluetoothAdapterCast>
  283. CastContentBrowserClient::CreateBluetoothAdapter() {
  284. NOTREACHED() << "Bluetooth Adapter is not supported!";
  285. return nullptr;
  286. }
  287. #endif // !BUILDFLAG(IS_ANDROID) && !BUILDFLAG(IS_FUCHSIA)
  288. void CastContentBrowserClient::SetMetricsClientId(
  289. const std::string& client_id) {}
  290. void CastContentBrowserClient::RegisterMetricsProviders(
  291. ::metrics::MetricsService* metrics_service) {}
  292. bool CastContentBrowserClient::EnableRemoteDebuggingImmediately() {
  293. return true;
  294. }
  295. std::vector<std::string> CastContentBrowserClient::GetStartupServices() {
  296. return {
  297. #if BUILDFLAG(ENABLE_EXTERNAL_MOJO_SERVICES)
  298. external_mojo::BrokerService::kServiceName
  299. #endif
  300. };
  301. }
  302. std::unique_ptr<content::BrowserMainParts>
  303. CastContentBrowserClient::CreateBrowserMainParts(
  304. bool /* is_integration_test */) {
  305. DCHECK(!cast_browser_main_parts_);
  306. auto main_parts = CastBrowserMainParts::Create(this);
  307. cast_browser_main_parts_ = main_parts.get();
  308. CastBrowserProcess::GetInstance()->SetCastContentBrowserClient(this);
  309. return main_parts;
  310. }
  311. void CastContentBrowserClient::RenderProcessWillLaunch(
  312. content::RenderProcessHost* host) {
  313. #if BUILDFLAG(IS_ANDROID)
  314. // Cast on Android always allows persisting data.
  315. //
  316. // Cast on Android build always uses kForceVideoOverlays command line switch
  317. // such that secure codecs can always be rendered.
  318. //
  319. // TODO(yucliu): On Clank, secure codecs support is tied to AndroidOverlay.
  320. // Remove kForceVideoOverlays and swtich to the Clank model for secure codecs
  321. // support.
  322. host->AddFilter(new cdm::CdmMessageFilterAndroid(true, true));
  323. #endif // BUILDFLAG(IS_ANDROID)
  324. }
  325. bool CastContentBrowserClient::IsHandledURL(const GURL& url) {
  326. if (!url.is_valid())
  327. return false;
  328. static const char* const kProtocolList[] = {
  329. content::kChromeUIScheme, content::kChromeDevToolsScheme,
  330. kChromeResourceScheme, url::kBlobScheme,
  331. url::kDataScheme, url::kFileSystemScheme,
  332. };
  333. const std::string& scheme = url.scheme();
  334. for (size_t i = 0; i < std::size(kProtocolList); ++i) {
  335. if (scheme == kProtocolList[i])
  336. return true;
  337. }
  338. if (scheme == url::kFileScheme) {
  339. return base::CommandLine::ForCurrentProcess()->HasSwitch(
  340. switches::kEnableLocalFileAccesses);
  341. }
  342. return false;
  343. }
  344. void CastContentBrowserClient::SiteInstanceGotProcess(
  345. content::SiteInstance* site_instance) {}
  346. void CastContentBrowserClient::AppendExtraCommandLineSwitches(
  347. base::CommandLine* command_line,
  348. int child_process_id) {
  349. std::string process_type =
  350. command_line->GetSwitchValueNative(switches::kProcessType);
  351. base::CommandLine* browser_command_line =
  352. base::CommandLine::ForCurrentProcess();
  353. #if !BUILDFLAG(IS_FUCHSIA)
  354. #if BUILDFLAG(IS_ANDROID)
  355. if (base::CommandLine::ForCurrentProcess()->HasSwitch(
  356. switches::kEnableCrashReporter)) {
  357. command_line->AppendSwitch(switches::kEnableCrashReporter);
  358. }
  359. #else
  360. // IsCrashReporterEnabled() is set when InitCrashReporter() is called, and
  361. // controlled by GetBreakpadClient()->EnableBreakpadForProcess(), therefore
  362. // it's ok to add switch to every process here.
  363. if (breakpad::IsCrashReporterEnabled()) {
  364. command_line->AppendSwitch(switches::kEnableCrashReporter);
  365. }
  366. #endif // BUILDFLAG(IS_ANDROID)
  367. #endif // !BUILDFLAG(IS_FUCHSIA)
  368. // Command-line for different processes.
  369. if (process_type == switches::kRendererProcess) {
  370. // Any browser command-line switches that should be propagated to
  371. // the renderer go here.
  372. static const char* const kForwardSwitches[] = {
  373. switches::kCastAppBackgroundColor,
  374. switches::kForceMediaResolutionHeight,
  375. switches::kForceMediaResolutionWidth,
  376. network::switches::kUnsafelyTreatInsecureOriginAsSecure};
  377. command_line->CopySwitchesFrom(*browser_command_line, kForwardSwitches,
  378. std::size(kForwardSwitches));
  379. } else if (process_type == switches::kUtilityProcess) {
  380. if (browser_command_line->HasSwitch(switches::kAudioOutputChannels)) {
  381. command_line->AppendSwitchASCII(switches::kAudioOutputChannels,
  382. browser_command_line->GetSwitchValueASCII(
  383. switches::kAudioOutputChannels));
  384. }
  385. } else if (process_type == switches::kGpuProcess) {
  386. #if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  387. // Necessary for accelerated 2d canvas. By default on Linux, Chromium
  388. // assumes GLES2 contexts can be lost to a power-save mode, which breaks GPU
  389. // canvas apps.
  390. command_line->AppendSwitch(switches::kGpuNoContextLost);
  391. #endif
  392. #if defined(USE_AURA)
  393. static const char* const kForwardSwitches[] = {
  394. switches::kCastInitialScreenHeight,
  395. switches::kCastInitialScreenWidth,
  396. switches::kVSyncInterval,
  397. };
  398. command_line->CopySwitchesFrom(*browser_command_line, kForwardSwitches,
  399. std::size(kForwardSwitches));
  400. auto display = display::Screen::GetScreen()->GetPrimaryDisplay();
  401. gfx::Size res = display.GetSizeInPixel();
  402. if (display.rotation() == display::Display::ROTATE_90 ||
  403. display.rotation() == display::Display::ROTATE_270) {
  404. res = gfx::Size(res.height(), res.width());
  405. }
  406. if (!command_line->HasSwitch(switches::kCastInitialScreenWidth)) {
  407. command_line->AppendSwitchASCII(switches::kCastInitialScreenWidth,
  408. base::NumberToString(res.width()));
  409. }
  410. if (!command_line->HasSwitch(switches::kCastInitialScreenHeight)) {
  411. command_line->AppendSwitchASCII(switches::kCastInitialScreenHeight,
  412. base::NumberToString(res.height()));
  413. }
  414. if (chromecast::IsFeatureEnabled(kSingleBuffer)) {
  415. command_line->AppendSwitchASCII(switches::kGraphicsBufferCount, "1");
  416. } else if (chromecast::IsFeatureEnabled(chromecast::kTripleBuffer720)) {
  417. command_line->AppendSwitchASCII(switches::kGraphicsBufferCount, "3");
  418. }
  419. #endif // defined(USE_AURA)
  420. }
  421. }
  422. std::string CastContentBrowserClient::GetAcceptLangs(
  423. content::BrowserContext* context) {
  424. return CastHttpUserAgentSettings::AcceptLanguage();
  425. }
  426. network::mojom::NetworkContext*
  427. CastContentBrowserClient::GetSystemNetworkContext() {
  428. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  429. return cast_network_contexts_->GetSystemContext();
  430. }
  431. void CastContentBrowserClient::OverrideWebkitPrefs(
  432. content::WebContents* web_contents,
  433. blink::web_pref::WebPreferences* prefs) {
  434. prefs->allow_scripts_to_close_windows = true;
  435. // Enable 5% margins for WebVTT cues to keep within title-safe area
  436. prefs->text_track_margin_percentage = 5;
  437. prefs->hide_scrollbars = true;
  438. // Disable images rendering in Cast for Audio configuration
  439. #if BUILDFLAG(IS_CAST_AUDIO_ONLY)
  440. prefs->images_enabled = false;
  441. #endif
  442. #if BUILDFLAG(IS_ANDROID)
  443. // Enable the television style for viewport so that all cast apps have a
  444. // 1280px wide layout viewport by default.
  445. DCHECK(prefs->viewport_enabled);
  446. DCHECK(prefs->viewport_meta_enabled);
  447. prefs->viewport_style = blink::mojom::ViewportStyle::kTelevision;
  448. #endif // BUILDFLAG(IS_ANDROID)
  449. // Disable WebSQL databases by default.
  450. prefs->databases_enabled = false;
  451. if (web_contents) {
  452. chromecast::CastWebContents* cast_web_contents =
  453. chromecast::CastWebContents::FromWebContents(web_contents);
  454. if (cast_web_contents && cast_web_contents->is_websql_enabled()) {
  455. prefs->databases_enabled = true;
  456. }
  457. }
  458. prefs->preferred_color_scheme =
  459. static_cast<blink::mojom::PreferredColorScheme>(
  460. CastBrowserProcess::GetInstance()->pref_service()->GetInteger(
  461. prefs::kWebColorScheme));
  462. // After all other default settings are set, check and see if there are any
  463. // specific overrides for the WebContents.
  464. CastWebPreferences* web_preferences =
  465. static_cast<CastWebPreferences*>(web_contents->GetUserData(
  466. CastWebPreferences::kCastWebPreferencesDataKey));
  467. if (web_preferences)
  468. web_preferences->Update(prefs);
  469. }
  470. std::string CastContentBrowserClient::GetApplicationLocale() {
  471. const std::string locale(base::i18n::GetConfiguredLocale());
  472. return locale.empty() ? "en-US" : locale;
  473. }
  474. scoped_refptr<content::QuotaPermissionContext>
  475. CastContentBrowserClient::CreateQuotaPermissionContext() {
  476. return new CastQuotaPermissionContext();
  477. }
  478. void CastContentBrowserClient::AllowCertificateError(
  479. content::WebContents* web_contents,
  480. int cert_error,
  481. const net::SSLInfo& ssl_info,
  482. const GURL& request_url,
  483. bool is_primary_main_frame_request,
  484. bool strict_enforcement,
  485. base::OnceCallback<void(content::CertificateRequestResultType)> callback) {
  486. // Allow developers to override certificate errors.
  487. // Otherwise, any fatal certificate errors will cause an abort.
  488. if (callback) {
  489. std::move(callback).Run(content::CERTIFICATE_REQUEST_RESULT_TYPE_CANCEL);
  490. }
  491. return;
  492. }
  493. base::OnceClosure CastContentBrowserClient::SelectClientCertificate(
  494. content::WebContents* web_contents,
  495. net::SSLCertRequestInfo* cert_request_info,
  496. net::ClientCertIdentityList client_certs,
  497. std::unique_ptr<content::ClientCertificateDelegate> delegate) {
  498. GURL requesting_url("https://" + cert_request_info->host_and_port.ToString());
  499. if (!requesting_url.is_valid()) {
  500. LOG(ERROR) << "Invalid URL string: "
  501. << requesting_url.possibly_invalid_spec();
  502. delegate->ContinueWithCertificate(nullptr, nullptr);
  503. return base::OnceClosure();
  504. }
  505. // In our case there are no relevant certs in |client_certs|. The cert
  506. // we need to return (if permitted) is the Cast device cert, which we can
  507. // access directly through the ClientAuthSigner instance. However, we need to
  508. // be on the IO thread to determine whether the app is whitelisted to return
  509. // it.
  510. // Subsequently, the callback must then itself be performed back here
  511. // on the UI thread.
  512. //
  513. // TODO(davidben): Stop using child ID to identify an app.
  514. std::string session_id =
  515. CastNavigationUIData::GetSessionIdForWebContents(web_contents);
  516. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  517. content::GetIOThreadTaskRunner({})->PostTask(
  518. FROM_HERE,
  519. base::BindOnce(
  520. &CastContentBrowserClient::SelectClientCertificateOnIOThread,
  521. base::Unretained(this), requesting_url, session_id,
  522. web_contents->GetPrimaryMainFrame()->GetProcess()->GetID(),
  523. web_contents->GetPrimaryMainFrame()->GetRoutingID(),
  524. base::SequencedTaskRunnerHandle::Get(),
  525. base::BindOnce(
  526. &content::ClientCertificateDelegate::ContinueWithCertificate,
  527. base::Owned(delegate.release()))));
  528. return base::OnceClosure();
  529. }
  530. bool CastContentBrowserClient::IsWhitelisted(
  531. const GURL& /* gurl */,
  532. const std::string& /* session_id */,
  533. int /* render_process_id */,
  534. int /* render_frame_id */,
  535. bool /* for_device_auth */) {
  536. return false;
  537. }
  538. void CastContentBrowserClient::SelectClientCertificateOnIOThread(
  539. GURL requesting_url,
  540. const std::string& session_id,
  541. int render_process_id,
  542. int render_frame_id,
  543. scoped_refptr<base::SequencedTaskRunner> original_runner,
  544. base::OnceCallback<void(scoped_refptr<net::X509Certificate>,
  545. scoped_refptr<net::SSLPrivateKey>)>
  546. continue_callback) {
  547. DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
  548. if (IsWhitelisted(requesting_url, session_id, render_process_id,
  549. render_frame_id, false)) {
  550. original_runner->PostTask(
  551. FROM_HERE, base::BindOnce(std::move(continue_callback), DeviceCert(),
  552. DeviceKey()));
  553. return;
  554. } else {
  555. LOG(ERROR) << "Invalid host for client certificate request: "
  556. << requesting_url.host()
  557. << " with render_process_id: " << render_process_id
  558. << " and render_frame_id: " << render_frame_id;
  559. }
  560. original_runner->PostTask(
  561. FROM_HERE,
  562. base::BindOnce(std::move(continue_callback), nullptr, nullptr));
  563. }
  564. bool CastContentBrowserClient::CanCreateWindow(
  565. content::RenderFrameHost* opener,
  566. const GURL& opener_url,
  567. const GURL& opener_top_level_frame_url,
  568. const url::Origin& source_origin,
  569. content::mojom::WindowContainerType container_type,
  570. const GURL& target_url,
  571. const content::Referrer& referrer,
  572. const std::string& frame_name,
  573. WindowOpenDisposition disposition,
  574. const blink::mojom::WindowFeatures& features,
  575. bool user_gesture,
  576. bool opener_suppressed,
  577. bool* no_javascript_access) {
  578. *no_javascript_access = true;
  579. // To show new page in the existing view for WebView new window navigations,
  580. // when supports_multiple_windows is disabled, return true so
  581. // RenderFrameHostImpl::CreateNewWindow returns with kReuse.
  582. // Otherwise, return false.
  583. content::WebContents* web_contents =
  584. content::WebContents::FromRenderFrameHost(opener);
  585. if (web_contents) {
  586. CastWebPreferences* cast_prefs =
  587. static_cast<CastWebPreferences*>(web_contents->GetUserData(
  588. CastWebPreferences::kCastWebPreferencesDataKey));
  589. return (cast_prefs &&
  590. !cast_prefs->preferences()->supports_multiple_windows.value());
  591. }
  592. return false;
  593. }
  594. void CastContentBrowserClient::GetApplicationMediaInfo(
  595. std::string* application_session_id,
  596. bool* mixer_audio_enabled,
  597. content::RenderFrameHost* render_frame_host) {
  598. content::WebContents* web_contents =
  599. content::WebContents::FromRenderFrameHost(render_frame_host);
  600. if (web_contents) {
  601. *application_session_id =
  602. CastNavigationUIData::GetSessionIdForWebContents(web_contents);
  603. chromecast::CastWebContents* cast_web_contents =
  604. chromecast::CastWebContents::FromWebContents(web_contents);
  605. *mixer_audio_enabled =
  606. (cast_web_contents && cast_web_contents->is_mixer_audio_enabled());
  607. }
  608. }
  609. bool CastContentBrowserClient::IsBufferingEnabled() {
  610. return true;
  611. }
  612. absl::optional<service_manager::Manifest>
  613. CastContentBrowserClient::GetServiceManifestOverlay(
  614. base::StringPiece service_name) {
  615. if (service_name == ServiceManagerContext::kBrowserServiceName)
  616. return GetCastContentBrowserOverlayManifest();
  617. return absl::nullopt;
  618. }
  619. std::vector<service_manager::Manifest>
  620. CastContentBrowserClient::GetExtraServiceManifests() {
  621. // NOTE: This could be simplified and the list of manifests could be inlined.
  622. // Not done yet since it would require touching downstream cast code.
  623. return GetCastContentPackagedServicesOverlayManifest().packaged_services;
  624. }
  625. void CastContentBrowserClient::GetAdditionalMappedFilesForChildProcess(
  626. const base::CommandLine& command_line,
  627. int child_process_id,
  628. content::PosixFileDescriptorInfo* mappings) {
  629. #if BUILDFLAG(IS_ANDROID)
  630. mappings->ShareWithRegion(
  631. kAndroidPakDescriptor,
  632. base::GlobalDescriptors::GetInstance()->Get(kAndroidPakDescriptor),
  633. base::GlobalDescriptors::GetInstance()->GetRegion(kAndroidPakDescriptor));
  634. #endif // BUILDFLAG(IS_ANDROID)
  635. #if !BUILDFLAG(IS_FUCHSIA)
  636. // TODO(crbug.com/753619): Complete crash reporting integration on Fuchsia.
  637. int crash_signal_fd = GetCrashSignalFD(command_line);
  638. if (crash_signal_fd >= 0) {
  639. mappings->Share(kCrashDumpSignal, crash_signal_fd);
  640. }
  641. #endif // !BUILDFLAG(IS_FUCHSIA)
  642. }
  643. void CastContentBrowserClient::GetAdditionalWebUISchemes(
  644. std::vector<std::string>* additional_schemes) {
  645. additional_schemes->push_back(kChromeResourceScheme);
  646. }
  647. std::unique_ptr<content::DevToolsManagerDelegate>
  648. CastContentBrowserClient::CreateDevToolsManagerDelegate() {
  649. return std::make_unique<CastDevToolsManagerDelegate>();
  650. }
  651. std::unique_ptr<content::NavigationUIData>
  652. CastContentBrowserClient::GetNavigationUIData(
  653. content::NavigationHandle* navigation_handle) {
  654. DCHECK(navigation_handle);
  655. content::WebContents* web_contents = navigation_handle->GetWebContents();
  656. DCHECK(web_contents);
  657. std::string session_id =
  658. CastNavigationUIData::GetSessionIdForWebContents(web_contents);
  659. return std::make_unique<CastNavigationUIData>(session_id);
  660. }
  661. bool CastContentBrowserClient::ShouldEnableStrictSiteIsolation() {
  662. return false;
  663. }
  664. scoped_refptr<net::X509Certificate> CastContentBrowserClient::DeviceCert() {
  665. return nullptr;
  666. }
  667. scoped_refptr<net::SSLPrivateKey> CastContentBrowserClient::DeviceKey() {
  668. return nullptr;
  669. }
  670. #if BUILDFLAG(IS_ANDROID)
  671. int CastContentBrowserClient::GetCrashSignalFD(
  672. const base::CommandLine& command_line) {
  673. return crashpad::CrashHandlerHost::Get()->GetDeathSignalSocket();
  674. }
  675. #elif !BUILDFLAG(IS_FUCHSIA)
  676. int CastContentBrowserClient::GetCrashSignalFD(
  677. const base::CommandLine& command_line) {
  678. std::string process_type =
  679. command_line.GetSwitchValueASCII(switches::kProcessType);
  680. if (process_type == switches::kRendererProcess ||
  681. process_type == switches::kGpuProcess ||
  682. process_type == switches::kUtilityProcess) {
  683. breakpad::CrashHandlerHostLinux* crash_handler =
  684. crash_handlers_[process_type];
  685. if (!crash_handler) {
  686. crash_handler = CreateCrashHandlerHost(process_type);
  687. crash_handlers_[process_type] = crash_handler;
  688. }
  689. return crash_handler->GetDeathSignalSocket();
  690. }
  691. return -1;
  692. }
  693. breakpad::CrashHandlerHostLinux*
  694. CastContentBrowserClient::CreateCrashHandlerHost(
  695. const std::string& process_type) {
  696. // Let cast shell dump to /tmp. Internal minidump generator code can move it
  697. // to /data/minidumps later, since /data/minidumps is file lock-controlled.
  698. base::FilePath dumps_path;
  699. base::PathService::Get(base::DIR_TEMP, &dumps_path);
  700. // Alway set "upload" to false to use our own uploader.
  701. breakpad::CrashHandlerHostLinux* crash_handler =
  702. new breakpad::CrashHandlerHostLinux(process_type, dumps_path,
  703. false /* upload */);
  704. // StartUploaderThread() even though upload is diferred.
  705. // Breakpad-related memory is freed in the uploader thread.
  706. crash_handler->StartUploaderThread();
  707. return crash_handler;
  708. }
  709. #endif // BUILDFLAG(IS_ANDROID)
  710. std::vector<std::unique_ptr<content::NavigationThrottle>>
  711. CastContentBrowserClient::CreateThrottlesForNavigation(
  712. content::NavigationHandle* handle) {
  713. std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
  714. if (chromecast::IsFeatureEnabled(kEnableGeneralAudienceBrowsing)) {
  715. throttles.push_back(
  716. std::make_unique<GeneralAudienceBrowsingNavigationThrottle>(
  717. handle, general_audience_browsing_service_.get()));
  718. }
  719. return throttles;
  720. }
  721. void CastContentBrowserClient::RegisterNonNetworkNavigationURLLoaderFactories(
  722. int frame_tree_node_id,
  723. ukm::SourceIdObj ukm_source_id,
  724. NonNetworkURLLoaderFactoryMap* factories) {}
  725. void CastContentBrowserClient::RegisterNonNetworkSubresourceURLLoaderFactories(
  726. int render_process_id,
  727. int render_frame_id,
  728. const absl::optional<url::Origin>& request_initiator_origin,
  729. NonNetworkURLLoaderFactoryMap* factories) {
  730. if (render_frame_id == MSG_ROUTING_NONE) {
  731. LOG(ERROR) << "Service worker not supported.";
  732. return;
  733. }
  734. content::RenderFrameHost* frame_host =
  735. content::RenderFrameHost::FromID(render_process_id, render_frame_id);
  736. factories->emplace(
  737. kChromeResourceScheme,
  738. content::CreateWebUIURLLoaderFactory(
  739. frame_host, kChromeResourceScheme,
  740. /*allowed_webui_hosts=*/base::flat_set<std::string>()));
  741. }
  742. void CastContentBrowserClient::OnNetworkServiceCreated(
  743. network::mojom::NetworkService* network_service) {
  744. // Need to set up global NetworkService state before anything else uses it.
  745. cast_network_contexts_->OnNetworkServiceCreated(network_service);
  746. }
  747. void CastContentBrowserClient::ConfigureNetworkContextParams(
  748. content::BrowserContext* context,
  749. bool in_memory,
  750. const base::FilePath& relative_partition_path,
  751. network::mojom::NetworkContextParams* network_context_params,
  752. cert_verifier::mojom::CertVerifierCreationParams*
  753. cert_verifier_creation_params) {
  754. return cast_network_contexts_->ConfigureNetworkContextParams(
  755. context, in_memory, relative_partition_path, network_context_params,
  756. cert_verifier_creation_params);
  757. }
  758. bool CastContentBrowserClient::DoesSiteRequireDedicatedProcess(
  759. content::BrowserContext* browser_context,
  760. const GURL& effective_site_url) {
  761. return false;
  762. }
  763. bool CastContentBrowserClient::IsWebUIAllowedToMakeNetworkRequests(
  764. const url::Origin& origin) {
  765. return false;
  766. }
  767. bool CastContentBrowserClient::ShouldAllowInsecurePrivateNetworkRequests(
  768. content::BrowserContext* browser_context,
  769. const url::Origin& origin) {
  770. // Some Cast apps hosted over HTTP needs to access the private network so that
  771. // media can be streamed from a local media server.
  772. return true;
  773. }
  774. std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
  775. CastContentBrowserClient::CreateURLLoaderThrottles(
  776. const network::ResourceRequest& request,
  777. content::BrowserContext* browser_context,
  778. const base::RepeatingCallback<content::WebContents*()>& wc_getter,
  779. content::NavigationUIData* navigation_ui_data,
  780. int frame_tree_node_id) {
  781. std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles;
  782. if (frame_tree_node_id == content::RenderFrameHost::kNoFrameTreeNodeId) {
  783. // No support for service workers.
  784. return throttles;
  785. }
  786. auto* cast_web_contents = CastWebContents::FromWebContents(wc_getter.Run());
  787. // |cast_web_contents| may be nullptr in browser tests.
  788. if (cast_web_contents) {
  789. const auto& rules =
  790. cast_web_contents->url_rewrite_rules_manager()->GetCachedRules();
  791. if (rules) {
  792. throttles.emplace_back(std::make_unique<url_rewrite::URLLoaderThrottle>(
  793. rules, base::BindRepeating(&IsCorsExemptHeader)));
  794. }
  795. }
  796. return throttles;
  797. }
  798. std::string CastContentBrowserClient::GetUserAgent() {
  799. return chromecast::GetUserAgent();
  800. }
  801. void CastContentBrowserClient::CreateGeneralAudienceBrowsingService() {
  802. DCHECK(!general_audience_browsing_service_);
  803. general_audience_browsing_service_ =
  804. std::make_unique<GeneralAudienceBrowsingService>(
  805. browser_main_parts()->connector(),
  806. cast_network_contexts_->GetSystemSharedURLLoaderFactory());
  807. }
  808. void CastContentBrowserClient::BindMediaRenderer(
  809. mojo::PendingReceiver<::media::mojom::Renderer> receiver) {
  810. auto media_task_runner = GetMediaTaskRunner();
  811. if (!media_task_runner->BelongsToCurrentThread()) {
  812. media_task_runner->PostTask(
  813. FROM_HERE, base::BindOnce(&CastContentBrowserClient::BindMediaRenderer,
  814. base::Unretained(this), std::move(receiver)));
  815. return;
  816. }
  817. ::media::MojoRendererService::Create(
  818. nullptr /* mojo_cdm_service_context */,
  819. std::make_unique<media::CastRenderer>(
  820. GetCmaBackendFactory(), std::move(media_task_runner),
  821. GetVideoModeSwitcher(), GetVideoResolutionPolicy(),
  822. base::UnguessableToken::Create(), nullptr /* frame_interfaces */,
  823. browser_main_parts()->connector(), true /* is_buffering_enabled */),
  824. std::move(receiver));
  825. }
  826. } // namespace shell
  827. } // namespace chromecast