Merge WebFileChooserCompletionImpl into FileChooser.

This simplifies the code slightly.
This is a preparation to mojoify FileChooser IPCs [1].

[1] https://chromium-review.googlesource.com/1170454

Change-Id: I52058bedda4508991f88e1c45a09151be02d40e9
Reviewed-on: https://chromium-review.googlesource.com/1174081
Commit-Queue: Kent Tamura <tkent@chromium.org>
Reviewed-by: Yoshifumi Inoue <yosin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#582867}
diff --git a/third_party/blink/renderer/core/exported/BUILD.gn b/third_party/blink/renderer/core/exported/BUILD.gn
index 2e6006a..6b0519c 100644
--- a/third_party/blink/renderer/core/exported/BUILD.gn
+++ b/third_party/blink/renderer/core/exported/BUILD.gn
@@ -28,8 +28,6 @@
     "web_dom_message_event.cc",
     "web_element.cc",
     "web_element_collection.cc",
-    "web_file_chooser_completion_impl.cc",
-    "web_file_chooser_completion_impl.h",
     "web_form_control_element.cc",
     "web_form_element.cc",
     "web_form_element_observer_impl.cc",
diff --git a/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.cc b/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.cc
deleted file mode 100644
index 16d1e6f..0000000
--- a/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h"
-
-#include "third_party/blink/renderer/core/page/chrome_client_impl.h"
-#include "third_party/blink/renderer/platform/file_metadata.h"
-#include "third_party/blink/renderer/platform/wtf/date_math.h"
-
-namespace blink {
-
-WebFileChooserCompletionImpl::WebFileChooserCompletionImpl(
-    scoped_refptr<FileChooser> chooser,
-    ChromeClientImpl* chrome_client)
-    : file_chooser_(std::move(chooser)), chrome_client_impl_(chrome_client) {}
-
-WebFileChooserCompletionImpl::~WebFileChooserCompletionImpl() = default;
-
-void WebFileChooserCompletionImpl::DidChooseFile(
-    const WebVector<WebString>& file_names) {
-  Vector<FileChooserFileInfo> file_info;
-  for (size_t i = 0; i < file_names.size(); ++i)
-    file_info.push_back(FileChooserFileInfo(file_names[i]));
-  file_chooser_->ChooseFiles(file_info);
-  if (chrome_client_impl_)
-    chrome_client_impl_->DidCompleteFileChooser(*this);
-  // This object is no longer needed.
-  delete this;
-}
-
-void WebFileChooserCompletionImpl::DidChooseFile(
-    const WebVector<SelectedFileInfo>& files) {
-  Vector<FileChooserFileInfo> file_info;
-  for (size_t i = 0; i < files.size(); ++i) {
-    if (files[i].file_system_url.IsEmpty()) {
-      file_info.push_back(
-          FileChooserFileInfo(files[i].path, files[i].display_name));
-    } else {
-      FileMetadata metadata;
-      metadata.modification_time = files[i].modification_time * kMsPerSecond;
-      metadata.length = files[i].length;
-      metadata.type = files[i].is_directory ? FileMetadata::kTypeDirectory
-                                            : FileMetadata::kTypeFile;
-      file_info.push_back(
-          FileChooserFileInfo(files[i].file_system_url, metadata));
-    }
-  }
-  file_chooser_->ChooseFiles(file_info);
-  if (chrome_client_impl_)
-    chrome_client_impl_->DidCompleteFileChooser(*this);
-  // This object is no longer needed.
-  delete this;
-}
-
-}  // namespace blink
diff --git a/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h b/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h
deleted file mode 100644
index 17b0ef3..0000000
--- a/third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/*
- * Copyright (C) 2009 Google Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- *     * Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above
- * copyright notice, this list of conditions and the following disclaimer
- * in the documentation and/or other materials provided with the
- * distribution.
- *     * Neither the name of Google Inc. nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_FILE_CHOOSER_COMPLETION_IMPL_H_
-#define THIRD_PARTY_BLINK_RENDERER_CORE_EXPORTED_WEB_FILE_CHOOSER_COMPLETION_IMPL_H_
-
-#include "base/memory/scoped_refptr.h"
-#include "third_party/blink/public/platform/web_string.h"
-#include "third_party/blink/public/platform/web_vector.h"
-#include "third_party/blink/public/web/web_file_chooser_completion.h"
-#include "third_party/blink/renderer/core/core_export.h"
-#include "third_party/blink/renderer/core/html/forms/file_chooser.h"
-
-namespace blink {
-
-class ChromeClientImpl;
-class LocalFrame;
-
-class CORE_EXPORT WebFileChooserCompletionImpl final
-    : public WebFileChooserCompletion {
- public:
-  explicit WebFileChooserCompletionImpl(
-      scoped_refptr<FileChooser> chooser,
-      ChromeClientImpl* chrome_client = nullptr);
-  ~WebFileChooserCompletionImpl() override;
-  void DidChooseFile(const WebVector<WebString>& file_names) override;
-  void DidChooseFile(const WebVector<SelectedFileInfo>& files) override;
-
-  const WebFileChooserParams& Params() const { return file_chooser_->Params(); }
-  LocalFrame* FrameOrNull() const { return file_chooser_->FrameOrNull(); }
-
- private:
-  scoped_refptr<FileChooser> file_chooser_;
-
-  // chrome_client_impl_ is nullptr in a case of
-  // EnumerateChosenDirectory(). We don't need to call back ChromeClientImpl.
-  Persistent<ChromeClientImpl> chrome_client_impl_;
-};
-
-}  // namespace blink
-
-#endif
diff --git a/third_party/blink/renderer/core/html/forms/file_chooser.cc b/third_party/blink/renderer/core/html/forms/file_chooser.cc
index bfab0af..5301bf7 100644
--- a/third_party/blink/renderer/core/html/forms/file_chooser.cc
+++ b/third_party/blink/renderer/core/html/forms/file_chooser.cc
@@ -28,6 +28,11 @@
 
 #include "third_party/blink/renderer/core/html/forms/file_chooser.h"
 
+#include "third_party/blink/public/web/web_local_frame_client.h"
+#include "third_party/blink/renderer/core/frame/web_local_frame_impl.h"
+#include "third_party/blink/renderer/core/page/chrome_client_impl.h"
+#include "third_party/blink/renderer/platform/wtf/date_math.h"
+
 namespace blink {
 
 FileChooserClient::~FileChooserClient() = default;
@@ -58,6 +63,48 @@
 
 FileChooser::~FileChooser() = default;
 
+bool FileChooser::OpenFileChooser(ChromeClientImpl& chrome_client_impl) {
+  LocalFrame* frame = FrameOrNull();
+  if (!frame)
+    return false;
+  chrome_client_impl_ = chrome_client_impl;
+
+  WebLocalFrameClient* client =
+      frame ? WebLocalFrameImpl::FromFrame(frame)->Client() : nullptr;
+  if (!client || !client->RunFileChooser(params_, this))
+    return false;
+
+  // Should be released on file choosing.
+  AddRef();
+  return true;
+}
+
+void FileChooser::DidChooseFile(const WebVector<WebString>& file_names) {
+  Vector<FileChooserFileInfo> file_info;
+  for (size_t i = 0; i < file_names.size(); ++i)
+    file_info.push_back(FileChooserFileInfo(file_names[i]));
+  ChooseFiles(file_info);
+}
+
+void FileChooser::DidChooseFile(const WebVector<SelectedFileInfo>& files) {
+  Vector<FileChooserFileInfo> file_info;
+  for (size_t i = 0; i < files.size(); ++i) {
+    if (files[i].file_system_url.IsEmpty()) {
+      file_info.push_back(
+          FileChooserFileInfo(files[i].path, files[i].display_name));
+    } else {
+      FileMetadata metadata;
+      metadata.modification_time = files[i].modification_time * kMsPerSecond;
+      metadata.length = files[i].length;
+      metadata.type = files[i].is_directory ? FileMetadata::kTypeDirectory
+                                            : FileMetadata::kTypeFile;
+      file_info.push_back(
+          FileChooserFileInfo(files[i].file_system_url, metadata));
+    }
+  }
+  ChooseFiles(file_info);
+}
+
 void FileChooser::ChooseFiles(const Vector<FileChooserFileInfo>& files) {
   // FIXME: This is inelegant. We should not be looking at params_ here.
   if (params_.selected_files.size() == files.size()) {
@@ -68,12 +115,21 @@
         break;
       }
     }
-    if (!was_changed)
+    if (!was_changed) {
+      DidCloseChooser();
       return;
+    }
   }
 
   if (client_)
     client_->FilesChosen(files);
+  DidCloseChooser();
+}
+
+void FileChooser::DidCloseChooser() {
+  if (chrome_client_impl_)
+    chrome_client_impl_->DidCompleteFileChooser(*this);
+  Release();
 }
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/html/forms/file_chooser.h b/third_party/blink/renderer/core/html/forms/file_chooser.h
index 3335c8a..322d008 100644
--- a/third_party/blink/renderer/core/html/forms/file_chooser.h
+++ b/third_party/blink/renderer/core/html/forms/file_chooser.h
@@ -30,6 +30,7 @@
 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_FILE_CHOOSER_H_
 #define THIRD_PARTY_BLINK_RENDERER_CORE_HTML_FORMS_FILE_CHOOSER_H_
 
+#include "third_party/blink/public/web/web_file_chooser_completion.h"
 #include "third_party/blink/public/web/web_file_chooser_params.h"
 #include "third_party/blink/renderer/platform/file_metadata.h"
 #include "third_party/blink/renderer/platform/heap/handle.h"
@@ -41,6 +42,7 @@
 
 namespace blink {
 
+class ChromeClientImpl;
 class FileChooser;
 class LocalFrame;
 
@@ -78,28 +80,38 @@
   scoped_refptr<FileChooser> chooser_;
 };
 
-class FileChooser : public RefCounted<FileChooser> {
+class FileChooser : public RefCounted<FileChooser>,
+                    public WebFileChooserCompletion {
  public:
   static scoped_refptr<FileChooser> Create(FileChooserClient*,
                                            const WebFileChooserParams&);
-  ~FileChooser();
+  ~FileChooser() override;
 
   LocalFrame* FrameOrNull() const {
     return client_ ? client_->FrameOrNull() : nullptr;
   }
   void DisconnectClient() { client_ = nullptr; }
 
-  // FIXME: We should probably just pass file paths that could be virtual paths
-  // with proper display names rather than passing structs.
-  void ChooseFiles(const Vector<FileChooserFileInfo>& files);
-
   const WebFileChooserParams& Params() const { return params_; }
 
+  bool OpenFileChooser(ChromeClientImpl& chrome_client_impl);
+
  private:
   FileChooser(FileChooserClient*, const WebFileChooserParams&);
 
+  void DidCloseChooser();
+
+  // WebFileChooserCompletion implementation:
+  void DidChooseFile(const WebVector<WebString>& file_names) override;
+  void DidChooseFile(const WebVector<SelectedFileInfo>& files) override;
+
+  // FIXME: We should probably just pass file paths that could be virtual paths
+  // with proper display names rather than passing structs.
+  void ChooseFiles(const Vector<FileChooserFileInfo>& files);
+
   WeakPersistent<FileChooserClient> client_;
   WebFileChooserParams params_;
+  Persistent<ChromeClientImpl> chrome_client_impl_;
 };
 
 }  // namespace blink
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.cc b/third_party/blink/renderer/core/page/chrome_client_impl.cc
index 963828a..6abd7c7 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.cc
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.cc
@@ -57,7 +57,6 @@
 #include "third_party/blink/renderer/core/dom/document.h"
 #include "third_party/blink/renderer/core/dom/node.h"
 #include "third_party/blink/renderer/core/events/web_input_event_conversion.h"
-#include "third_party/blink/renderer/core/exported/web_file_chooser_completion_impl.h"
 #include "third_party/blink/renderer/core/exported/web_plugin_container_impl.h"
 #include "third_party/blink/renderer/core/exported/web_remote_frame_impl.h"
 #include "third_party/blink/renderer/core/exported/web_settings_impl.h"
@@ -584,18 +583,11 @@
     LocalFrame* frame,
     scoped_refptr<FileChooser> file_chooser) {
   NotifyPopupOpeningObservers();
-  WebLocalFrameClient* client = WebLocalFrameImpl::FromFrame(frame)->Client();
-  if (!client)
-    return;
 
   Document* doc = frame->GetDocument();
   if (doc)
     doc->MaybeQueueSendDidEditFieldInInsecureContext();
 
-  const WebFileChooserParams& params = file_chooser->Params();
-  WebFileChooserCompletionImpl* chooser_completion =
-      new WebFileChooserCompletionImpl(std::move(file_chooser), this);
-
   static const wtf_size_t kMaximumPendingFileChooseRequests = 4;
   if (file_chooser_queue_.size() > kMaximumPendingFileChooseRequests) {
     // This sanity check prevents too many file choose requests from getting
@@ -606,43 +598,33 @@
     //
     // TODO(brettw): We might possibly want to require a user gesture to open
     // a file picker, which will address this issue in a better way.
-    //
-    // Choosing failed, so do callback with an empty list.
-    chooser_completion->DidChooseFile(WebVector<WebString>());
     return;
   }
-  file_chooser_queue_.push_back(chooser_completion);
+  file_chooser_queue_.push_back(file_chooser.get());
   if (file_chooser_queue_.size() == 1) {
     // Actually show the browse dialog when this is the first request.
-    if (client->RunFileChooser(params, chooser_completion))
+    if (file_chooser->OpenFileChooser(*this))
       return;
-    // Choosing failed, so do callback with an empty list.
-    chooser_completion->DidChooseFile(WebVector<WebString>());
-    // WebFileChooserCompletionImpl will call
-    // ChromeClientImpl::DidCompleteFileChooser().
+    // Choosing failed, so try the next chooser.
+    DidCompleteFileChooser(*file_chooser);
   }
 }
 
-void ChromeClientImpl::DidCompleteFileChooser(
-    WebFileChooserCompletionImpl& completion) {
+void ChromeClientImpl::DidCompleteFileChooser(FileChooser& chooser) {
   if (!file_chooser_queue_.IsEmpty() &&
-      file_chooser_queue_.front() != &completion) {
-    // This function is called even if |completion| wasn't stored in
+      file_chooser_queue_.front() != &chooser) {
+    // This function is called even if |chooser| wasn't stored in
     // file_chooser_queue_.
     return;
   }
   file_chooser_queue_.EraseAt(0);
   if (file_chooser_queue_.IsEmpty())
     return;
-  WebFileChooserCompletionImpl* next_completion = file_chooser_queue_.front();
-  LocalFrame* frame = next_completion->FrameOrNull();
-  WebLocalFrameClient* client =
-      frame ? WebLocalFrameImpl::FromFrame(frame)->Client() : nullptr;
-  if (client &&
-      client->RunFileChooser(next_completion->Params(), next_completion))
+  FileChooser* next_chooser = file_chooser_queue_.front();
+  if (next_chooser->OpenFileChooser(*this))
     return;
-  // Choosing failed, so do callback with an empty list.
-  next_completion->DidChooseFile(WebVector<WebString>());
+  // Choosing failed, so try the next chooser.
+  DidCompleteFileChooser(*next_chooser);
 }
 
 void ChromeClientImpl::EnumerateChosenDirectory(FileChooser* file_chooser) {
@@ -650,16 +632,11 @@
   if (!client)
     return;
 
-  WebFileChooserCompletionImpl* chooser_completion =
-      new WebFileChooserCompletionImpl(file_chooser);
-
   DCHECK(file_chooser);
   DCHECK(file_chooser->Params().selected_files.size());
-
-  // If the enumeration can't happen, call the callback with an empty list.
-  if (!client->EnumerateChosenDirectory(
-          file_chooser->Params().selected_files[0], chooser_completion))
-    chooser_completion->DidChooseFile(WebVector<WebString>());
+  if (client->EnumerateChosenDirectory(file_chooser->Params().selected_files[0],
+                                       file_chooser))
+    file_chooser->AddRef();
 }
 
 Cursor ChromeClientImpl::LastSetCursorForTesting() const {
diff --git a/third_party/blink/renderer/core/page/chrome_client_impl.h b/third_party/blink/renderer/core/page/chrome_client_impl.h
index 56354be5..206f416 100644
--- a/third_party/blink/renderer/core/page/chrome_client_impl.h
+++ b/third_party/blink/renderer/core/page/chrome_client_impl.h
@@ -44,7 +44,6 @@
 class PagePopup;
 class PagePopupClient;
 class WebAutofillClient;
-class WebFileChooserCompletionImpl;
 class WebViewImpl;
 struct WebCursorInfo;
 
@@ -176,9 +175,9 @@
   // ChromeClientImpl:
   void SetNewWindowNavigationPolicy(WebNavigationPolicy);
 
-  // WebFileChooserCompletionImpl calls this function to kick pending
-  // file chooser requests.
-  void DidCompleteFileChooser(WebFileChooserCompletionImpl& completion);
+  // FileChooser calls this function to kick pending file chooser
+  // requests.
+  void DidCompleteFileChooser(FileChooser& file_chooser);
 
   void AutoscrollStart(WebFloatPoint viewport_point, LocalFrame*) override;
   void AutoscrollFling(WebFloatSize velocity, LocalFrame*) override;
@@ -249,7 +248,7 @@
 
   WebViewImpl* web_view_;  // Weak pointer.
   HeapHashSet<WeakMember<PopupOpeningObserver>> popup_opening_observers_;
-  Vector<WebFileChooserCompletionImpl*> file_chooser_queue_;
+  Vector<FileChooser*> file_chooser_queue_;
   Cursor last_set_mouse_cursor_for_testing_;
   bool cursor_overridden_;
   bool did_request_non_empty_tool_tip_;