context_impl.cc 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. // Copyright 2018 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 "fuchsia_web/webengine/browser/context_impl.h"
  5. #include <lib/fpromise/result.h>
  6. #include <lib/zx/channel.h>
  7. #include <lib/zx/handle.h>
  8. #include <memory>
  9. #include <utility>
  10. #include "base/bind.h"
  11. #include "base/fuchsia/fuchsia_logging.h"
  12. #include "base/fuchsia/koid.h"
  13. #include "base/fuchsia/mem_buffer_util.h"
  14. #include "base/strings/stringprintf.h"
  15. #include "components/cast_streaming/browser/public/network_context_getter.h"
  16. #include "content/public/browser/browser_context.h"
  17. #include "content/public/browser/browser_thread.h"
  18. #include "content/public/browser/storage_partition.h"
  19. #include "content/public/browser/web_contents.h"
  20. #include "fuchsia_web/webengine/browser/frame_impl.h"
  21. #include "fuchsia_web/webengine/browser/web_engine_devtools_controller.h"
  22. #include "third_party/blink/public/common/web_preferences/web_preferences.h"
  23. #include "third_party/blink/public/mojom/webpreferences/web_preferences.mojom.h"
  24. ContextImpl::ContextImpl(
  25. std::unique_ptr<content::BrowserContext> browser_context,
  26. inspect::Node inspect_node,
  27. WebEngineDevToolsController* devtools_controller)
  28. : browser_context_(std::move(browser_context)),
  29. devtools_controller_(devtools_controller),
  30. inspect_node_(std::move(inspect_node)),
  31. cookie_manager_(base::BindRepeating(&ContextImpl::GetNetworkContext,
  32. base::Unretained(this))) {
  33. DCHECK(browser_context_);
  34. DCHECK(devtools_controller_);
  35. }
  36. ContextImpl::~ContextImpl() = default;
  37. void ContextImpl::DestroyFrame(FrameImpl* frame) {
  38. auto iter = frames_.find(frame);
  39. DCHECK(iter != frames_.end());
  40. frames_.erase(iter);
  41. }
  42. bool ContextImpl::IsJavaScriptInjectionAllowed() {
  43. return allow_javascript_injection_;
  44. }
  45. void ContextImpl::SetCastStreamingEnabled() {
  46. cast_streaming_enabled_ = true;
  47. cast_streaming::SetNetworkContextGetter(base::BindRepeating(
  48. &ContextImpl::GetNetworkContext, base::Unretained(this)));
  49. }
  50. void ContextImpl::CreateFrame(
  51. fidl::InterfaceRequest<fuchsia::web::Frame> frame) {
  52. CreateFrameWithParams(fuchsia::web::CreateFrameParams(), std::move(frame));
  53. }
  54. void ContextImpl::CreateFrameWithParams(
  55. fuchsia::web::CreateFrameParams params,
  56. fidl::InterfaceRequest<fuchsia::web::Frame> frame) {
  57. // FrameImpl clones the params used to create it when creating popup Frames.
  58. // Ensure the params can be cloned to avoid problems when handling popups.
  59. // TODO(fxbug.dev/65750): Consider removing this restriction if clients
  60. // become responsible for providing parameters for [each] popup.
  61. fuchsia::web::CreateFrameParams cloned_params;
  62. zx_status_t status = params.Clone(&cloned_params);
  63. if (status != ZX_OK) {
  64. ZX_LOG(ERROR, status) << "CreateFrameParams Clone() failed";
  65. frame.Close(ZX_ERR_INVALID_ARGS);
  66. return;
  67. }
  68. // Create a WebContents to host the new Frame.
  69. content::WebContents::CreateParams create_params(browser_context_.get(),
  70. nullptr);
  71. create_params.initially_hidden = true;
  72. auto web_contents = content::WebContents::Create(create_params);
  73. CreateFrameForWebContents(std::move(web_contents), std::move(params),
  74. std::move(frame));
  75. }
  76. FrameImpl* ContextImpl::CreateFrameForWebContents(
  77. std::unique_ptr<content::WebContents> web_contents,
  78. fuchsia::web::CreateFrameParams params,
  79. fidl::InterfaceRequest<fuchsia::web::Frame> frame_request) {
  80. DCHECK(frame_request.is_valid());
  81. // Register the new Frame with the DevTools controller. The controller will
  82. // reject registration if user-debugging is requested, but it is not enabled
  83. // in the controller.
  84. const bool user_debugging_requested =
  85. params.has_enable_remote_debugging() && params.enable_remote_debugging();
  86. if (!devtools_controller_->OnFrameCreated(web_contents.get(),
  87. user_debugging_requested)) {
  88. frame_request.Close(ZX_ERR_INVALID_ARGS);
  89. return nullptr;
  90. }
  91. // |params.debug_name| is not currently supported.
  92. // TODO(crbug.com/1051533): Determine whether it is still needed.
  93. // Verify the explicit sites filter error page content. If the parameter is
  94. // present, it will be provided to the FrameImpl after it is created below.
  95. absl::optional<std::string> explicit_sites_filter_error_page;
  96. if (params.has_explicit_sites_filter_error_page()) {
  97. explicit_sites_filter_error_page =
  98. base::StringFromMemData(params.explicit_sites_filter_error_page());
  99. if (!explicit_sites_filter_error_page) {
  100. frame_request.Close(ZX_ERR_INVALID_ARGS);
  101. return nullptr;
  102. }
  103. }
  104. // FrameImpl clones the params used to create it when creating popup Frames.
  105. // Ensure the params can be cloned to avoid problems when creating popups.
  106. // TODO(http://fxbug.dev/65750): Remove this limitation once a soft migration
  107. // to a new solution has been completed.
  108. fuchsia::web::CreateFrameParams cloned_params;
  109. zx_status_t status = params.Clone(&cloned_params);
  110. if (status != ZX_OK) {
  111. ZX_LOG(ERROR, status) << "CreateFrameParams clone failed";
  112. frame_request.Close(ZX_ERR_INVALID_ARGS);
  113. return nullptr;
  114. }
  115. // Wrap the WebContents into a FrameImpl owned by |this|.
  116. auto inspect_node_name =
  117. base::StringPrintf("frame-%lu", *base::GetKoid(frame_request.channel()));
  118. auto frame_impl = std::make_unique<FrameImpl>(
  119. std::move(web_contents), this, std::move(params),
  120. inspect_node_.CreateChild(inspect_node_name), std::move(frame_request));
  121. if (explicit_sites_filter_error_page) {
  122. frame_impl->EnableExplicitSitesFilter(
  123. std::move(*explicit_sites_filter_error_page));
  124. }
  125. FrameImpl* frame_ptr = frame_impl.get();
  126. frames_.insert(std::move(frame_impl));
  127. return frame_ptr;
  128. }
  129. void ContextImpl::GetCookieManager(
  130. fidl::InterfaceRequest<fuchsia::web::CookieManager> request) {
  131. cookie_manager_bindings_.AddBinding(&cookie_manager_, std::move(request));
  132. }
  133. void ContextImpl::GetRemoteDebuggingPort(
  134. GetRemoteDebuggingPortCallback callback) {
  135. devtools_controller_->GetDevToolsPort(base::BindOnce(
  136. [](GetRemoteDebuggingPortCallback callback, uint16_t port) {
  137. if (port == 0) {
  138. callback(fpromise::error(
  139. fuchsia::web::ContextError::REMOTE_DEBUGGING_PORT_NOT_OPENED));
  140. } else {
  141. callback(fpromise::ok(port));
  142. }
  143. },
  144. std::move(callback)));
  145. }
  146. FrameImpl* ContextImpl::GetFrameImplForTest(
  147. fuchsia::web::FramePtr* frame_ptr) const {
  148. DCHECK(frame_ptr);
  149. // Find the FrameImpl whose channel is connected to |frame_ptr| by inspecting
  150. // the "related" KOIDs of active FrameImpls.
  151. zx_koid_t channel_koid = base::GetKoid(frame_ptr->channel()).value();
  152. for (const std::unique_ptr<FrameImpl>& frame : frames_) {
  153. zx_koid_t peer_koid =
  154. base::GetRelatedKoid(*frame->GetBindingChannelForTest()) // IN-TEST
  155. .value();
  156. if (peer_koid == channel_koid)
  157. return frame.get();
  158. }
  159. return nullptr;
  160. }
  161. network::mojom::NetworkContext* ContextImpl::GetNetworkContext() {
  162. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  163. return browser_context_->GetDefaultStoragePartition()->GetNetworkContext();
  164. }