Make content::FileSelectListener a RefCounted

We can avoid a raw pointer reference to FileSelectListener.

* content/public/browser/file_select_listener.h
  Make content:FileSelectListener a RefCounted.

* content/browser/web_contents/file_chooser_impl.{cc,h}
  - Adjust a FileSelectListener subclass for RefCounted.
  - Change the FileSelectListenerImpl raw pointer member to
    scoped_refptr<FileSelectListenerImpl>.
  - Remove FileChooserImpl::ResetListenerImpl(). It was called when
    FileSelectLisetnerImpl was deleted in order to clear
    FileChooserImpl::listener_impl_ raw pointer member. Now
    FileChooserImpl has ownership of FileSelectListenerImpl.

* chrome/browser/file_select_helper_unittest.cc
* content/browser/web_contents/web_contents_impl_browsertest.cc
  Adjust FileSelectListener subclasses for RefCounted.

* Other files
  Mechanical changes; std::unique_ptr<> ==> scoped_refptr<>

This CL doesn't have any user-visible behavior changes.


Change-Id: I643aeb7aa0c717dad9716028317cab061d8df510
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2275338
Reviewed-by: Avi Drissman <[email protected]>
Reviewed-by: Istiaque Ahmed <[email protected]>
Reviewed-by: Bo <[email protected]>
Commit-Queue: Kent Tamura <[email protected]>
Cr-Commit-Position: refs/heads/master@{#784640}
diff --git a/content/browser/web_contents/file_chooser_impl.cc b/content/browser/web_contents/file_chooser_impl.cc
index 5a229b4..753c9a7c 100644
--- a/content/browser/web_contents/file_chooser_impl.cc
+++ b/content/browser/web_contents/file_chooser_impl.cc
@@ -26,8 +26,6 @@
   // blink::mojom::FileChooser are. https://crbug.com/1054811
   /* DCHECK(was_fullscreen_block_set_) << "The fullscreen block was not set"; */
 #endif
-  if (owner_)
-    owner_->ResetListenerImpl();
 }
 
 void FileChooserImpl::FileSelectListenerImpl::SetFullscreenBlock(
@@ -106,7 +104,7 @@
     return;
   }
   callback_ = std::move(callback);
-  auto listener = std::make_unique<FileSelectListenerImpl>(this);
+  auto listener = base::MakeRefCounted<FileSelectListenerImpl>(this);
   listener_impl_ = listener.get();
   // Do not allow messages with absolute paths in them as this can permit a
   // renderer to coerce the browser to perform I/O on a renderer controlled
@@ -135,7 +133,7 @@
     return;
   }
   callback_ = std::move(callback);
-  auto listener = std::make_unique<FileSelectListenerImpl>(this);
+  auto listener = base::MakeRefCounted<FileSelectListenerImpl>(this);
   listener_impl_ = listener.get();
   auto* policy = ChildProcessSecurityPolicyImpl::GetInstance();
   if (policy->CanReadFile(render_frame_host_->GetProcess()->GetID(),
@@ -189,10 +187,6 @@
   std::move(callback_).Run(nullptr);
 }
 
-void FileChooserImpl::ResetListenerImpl() {
-  listener_impl_ = nullptr;
-}
-
 void FileChooserImpl::RenderFrameHostChanged(RenderFrameHost* old_host,
                                              RenderFrameHost* new_host) {
   if (old_host == render_frame_host_)
diff --git a/content/browser/web_contents/file_chooser_impl.h b/content/browser/web_contents/file_chooser_impl.h
index 97ea05e..cb49b6cf 100644
--- a/content/browser/web_contents/file_chooser_impl.h
+++ b/content/browser/web_contents/file_chooser_impl.h
@@ -25,10 +25,11 @@
   using FileChooserResult = blink::mojom::FileChooserResult;
 
  public:
+  // A FileSelectListenerImpl instance is owned by a FileChooserImpl and/or a
+  // WebContents.
   class CONTENT_EXPORT FileSelectListenerImpl : public FileSelectListener {
    public:
     explicit FileSelectListenerImpl(FileChooserImpl* owner) : owner_(owner) {}
-    ~FileSelectListenerImpl() override;
     void SetFullscreenBlock(base::ScopedClosureRunner fullscreen_block);
     void ResetOwner() { owner_ = nullptr; }
 
@@ -41,6 +42,7 @@
     void FileSelectionCanceled() override;
 
    protected:
+    ~FileSelectListenerImpl() override;
     // This sets |was_file_select_listener_function_called_| to true so that
     // tests can pass with mocked overrides of this class.
     void SetListenerFunctionCalledTrueForTesting();
@@ -67,8 +69,6 @@
 
   void FileSelectionCanceled();
 
-  void ResetListenerImpl();
-
   // blink::mojom::FileChooser overrides:
 
   void OpenFileChooser(blink::mojom::FileChooserParamsPtr params,
@@ -88,7 +88,7 @@
   void WebContentsDestroyed() override;
 
   RenderFrameHostImpl* render_frame_host_;
-  FileSelectListenerImpl* listener_impl_ = nullptr;
+  scoped_refptr<FileSelectListenerImpl> listener_impl_;
   base::OnceCallback<void(blink::mojom::FileChooserResultPtr)> callback_;
 };
 
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 4f56a70..cf4d0c4 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -5019,7 +5019,7 @@
 
 void WebContentsImpl::EnumerateDirectory(
     RenderFrameHost* render_frame_host,
-    std::unique_ptr<FileChooserImpl::FileSelectListenerImpl> listener,
+    scoped_refptr<FileChooserImpl::FileSelectListenerImpl> listener,
     const base::FilePath& directory_path) {
   // Any explicit focusing of another window while this WebContents is in
   // fullscreen can be used to confuse the user, so drop fullscreen.
@@ -5723,7 +5723,7 @@
 
 void WebContentsImpl::RunFileChooser(
     RenderFrameHost* render_frame_host,
-    std::unique_ptr<FileChooserImpl::FileSelectListenerImpl> listener,
+    scoped_refptr<FileChooserImpl::FileSelectListenerImpl> listener,
     const blink::mojom::FileChooserParams& params) {
   // Any explicit focusing of another window while this WebContents is in
   // fullscreen can be used to confuse the user, so drop fullscreen.
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 6b36736a..ef837fbb 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -1126,7 +1126,7 @@
   // Called when a file selection is to be done.
   void RunFileChooser(
       RenderFrameHost* render_frame_host,
-      std::unique_ptr<FileChooserImpl::FileSelectListenerImpl> listener,
+      scoped_refptr<FileChooserImpl::FileSelectListenerImpl> listener,
       const blink::mojom::FileChooserParams& params);
 
   // Request to enumerate a directory.  This is equivalent to running the file
@@ -1134,7 +1134,7 @@
   // directory.
   void EnumerateDirectory(
       RenderFrameHost* render_frame_host,
-      std::unique_ptr<FileChooserImpl::FileSelectListenerImpl> listener,
+      scoped_refptr<FileChooserImpl::FileSelectListenerImpl> listener,
       const base::FilePath& directory_path);
 
 #if defined(OS_ANDROID)
diff --git a/content/browser/web_contents/web_contents_impl_browsertest.cc b/content/browser/web_contents/web_contents_impl_browsertest.cc
index 3635399..f068f9a 100644
--- a/content/browser/web_contents/web_contents_impl_browsertest.cc
+++ b/content/browser/web_contents/web_contents_impl_browsertest.cc
@@ -1631,6 +1631,9 @@
                     const base::FilePath& base_dir,
                     blink::mojom::FileChooserParams::Mode mode) override {}
   void FileSelectionCanceled() override {}
+
+ private:
+  ~MockFileSelectListener() override = default;
 };
 
 IN_PROC_BROWSER_TEST_F(WebContentsImplBrowserTest,
@@ -2475,7 +2478,7 @@
   wc->EnterFullscreenMode(wc->GetMainFrame(), {});
   EXPECT_TRUE(wc->IsFullscreen());
   wc->RunFileChooser(wc->GetMainFrame(),
-                     std::make_unique<MockFileSelectListener>(),
+                     base::MakeRefCounted<MockFileSelectListener>(),
                      blink::mojom::FileChooserParams());
   EXPECT_FALSE(wc->IsFullscreen());
 }