electron_autofill_driver_factory.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. // Copyright (c) 2019 GitHub, Inc.
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/electron_autofill_driver_factory.h"
  5. #include <memory>
  6. #include <utility>
  7. #include "content/public/browser/navigation_handle.h"
  8. #include "content/public/browser/render_frame_host.h"
  9. #include "content/public/browser/web_contents.h"
  10. #include "shell/browser/electron_autofill_driver.h"
  11. namespace electron {
  12. AutofillDriverFactory::~AutofillDriverFactory() = default;
  13. // static
  14. void AutofillDriverFactory::BindAutofillDriver(
  15. mojo::PendingAssociatedReceiver<mojom::ElectronAutofillDriver>
  16. pending_receiver,
  17. content::RenderFrameHost* render_frame_host) {
  18. DCHECK(render_frame_host);
  19. content::WebContents* web_contents =
  20. content::WebContents::FromRenderFrameHost(render_frame_host);
  21. DCHECK(web_contents);
  22. AutofillDriverFactory* factory = FromWebContents(web_contents);
  23. if (!factory) {
  24. // The message pipe will be closed and raise a connection error to peer
  25. // side. The peer side can reconnect later when needed.
  26. return;
  27. }
  28. if (auto* driver = factory->DriverForFrame(render_frame_host))
  29. driver->BindPendingReceiver(std::move(pending_receiver));
  30. }
  31. AutofillDriverFactory::AutofillDriverFactory(content::WebContents* web_contents)
  32. : content::WebContentsObserver(web_contents),
  33. content::WebContentsUserData<AutofillDriverFactory>(*web_contents) {}
  34. void AutofillDriverFactory::RenderFrameDeleted(
  35. content::RenderFrameHost* render_frame_host) {
  36. DeleteDriverForFrame(render_frame_host);
  37. }
  38. void AutofillDriverFactory::DidFinishNavigation(
  39. content::NavigationHandle* navigation_handle) {
  40. // For the purposes of this code, a navigation is not important if it has not
  41. // committed yet or if it's in a subframe.
  42. if (!navigation_handle->HasCommitted() ||
  43. !navigation_handle->IsInMainFrame()) {
  44. return;
  45. }
  46. CloseAllPopups();
  47. }
  48. AutofillDriver* AutofillDriverFactory::DriverForFrame(
  49. content::RenderFrameHost* render_frame_host) {
  50. auto insertion_result = driver_map_.emplace(render_frame_host, nullptr);
  51. std::unique_ptr<AutofillDriver>& driver = insertion_result.first->second;
  52. bool insertion_happened = insertion_result.second;
  53. if (insertion_happened) {
  54. // The `render_frame_host` may already be deleted (or be in the process of
  55. // being deleted). In this case, we must not create a new driver. Otherwise,
  56. // a driver might hold a deallocated RFH.
  57. //
  58. // For example, `render_frame_host` is deleted in the following sequence:
  59. // 1. `render_frame_host->~RenderFrameHostImpl()` starts and marks
  60. // `render_frame_host` as deleted.
  61. // 2. `ContentAutofillDriverFactory::RenderFrameDeleted(render_frame_host)`
  62. // destroys the driver of `render_frame_host`.
  63. // 3. `SomeOtherWebContentsObserver::RenderFrameDeleted(render_frame_host)`
  64. // calls `DriverForFrame(render_frame_host)`.
  65. // 5. `render_frame_host->~RenderFrameHostImpl()` finishes.
  66. if (render_frame_host->IsRenderFrameLive()) {
  67. driver = std::make_unique<AutofillDriver>(render_frame_host);
  68. DCHECK_EQ(driver_map_.find(render_frame_host)->second.get(),
  69. driver.get());
  70. } else {
  71. driver_map_.erase(insertion_result.first);
  72. DCHECK(!driver_map_.contains(render_frame_host));
  73. return nullptr;
  74. }
  75. }
  76. DCHECK(driver.get());
  77. return driver.get();
  78. }
  79. void AutofillDriverFactory::AddDriverForFrame(
  80. content::RenderFrameHost* render_frame_host,
  81. CreationCallback factory_method) {
  82. auto insertion_result =
  83. driver_map_.insert(std::make_pair(render_frame_host, nullptr));
  84. // This can be called twice for the key representing the main frame.
  85. if (insertion_result.second) {
  86. insertion_result.first->second = std::move(factory_method).Run();
  87. }
  88. }
  89. void AutofillDriverFactory::DeleteDriverForFrame(
  90. content::RenderFrameHost* render_frame_host) {
  91. driver_map_.erase(render_frame_host);
  92. }
  93. void AutofillDriverFactory::CloseAllPopups() {
  94. for (auto& it : driver_map_) {
  95. it.second->HideAutofillPopup();
  96. }
  97. }
  98. WEB_CONTENTS_USER_DATA_KEY_IMPL(AutofillDriverFactory);
  99. } // namespace electron