Revert "SelectFileDialog: Convert from RefCounted to std::unique_ptr"

This reverts commit 270245f69a17180ac3e037e7746b20da0061e38f.

Reason for revert: Causing crashes crbug.com/1368648

Manually merged to preserve the cross-thread issue fixed in
CL:3924783.

Original change's description:
> SelectFileDialog: Convert from RefCounted to std::unique_ptr
>
> SelectFileDialog (SFD) being ref-counted has caused multiple issues
> due to its unclear life-cycle and because usually its owner implements
> the Listener which SFD also has a pointer to it.
>
> Changing to unique_ptr makes clearer the SFD ownership and its
> termination, solving the UAF that was one of the common issues.
>
> This CL change in summary:
> * Change declaration from scoped_refptr<> to unique_ptr<>.
> * For Closure/Bind referring to instances of SFD, replace with
> base::AsWeakPtr(instance)
>
> NOTE: The SelectFileDialogFactory should be refactored to return an
> unique_ptr instead of raw pointer. This will be in a follow up CL since
> this CL is already too big.
>
> The SelectFileDialogLinuxKde implementation was using Bind() to a
> method with return value and this is incompatible with WeakPtr, to
> work around this, I changed the return value `KDialogOutputParams` to
> be passed as a ref-counted output argument like explained in [1].
>
> [1] -https://source.chromium.org/chromium/chromium/src/+/main:base/task/task_runner.h;l=77
>
> Bug: 1316211
> Change-Id: Ia59877a392364d7ab7af98cbc19e7f9146f465cc
> Cq-Do-Not-Cancel-Tryjobs: true
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3764409
> Reviewed-by: James Cook <jamescook@chromium.org>
> Reviewed-by: Scott Violet <sky@chromium.org>
> Reviewed-by: Tomas Gunnarsson <tommi@chromium.org>
> Auto-Submit: Luciano Pacheco <lucmult@chromium.org>
> Reviewed-by: Austin Sullivan <asully@chromium.org>
> Commit-Queue: Austin Sullivan <asully@chromium.org>
> Cr-Commit-Position: refs/heads/main@{#1051347}

Bug: 1316211, 1368648
Change-Id: I89b0b1f6d1732ab62e2c44f7a2a1629d3ce32626
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3930092
Owners-Override: Robert Lin <robertlin@google.com>
Commit-Queue: Luciano Pacheco <lucmult@chromium.org>
Reviewed-by: Huanpo Lin <robertlin@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1054522}
diff --git a/ash/capture_mode/folder_selection_dialog_controller.h b/ash/capture_mode/folder_selection_dialog_controller.h
index dcbb00a..0a3ee7d 100644
--- a/ash/capture_mode/folder_selection_dialog_controller.h
+++ b/ash/capture_mode/folder_selection_dialog_controller.h
@@ -82,7 +82,7 @@
   WindowDimmer dialog_background_dimmer_;
 
   // Provides us with the APIs needed to construct a folder selection dialog.
-  std::unique_ptr<ui::SelectFileDialog> select_folder_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_folder_dialog_;
 
   // This is the window of the dialog that gets created by
   // |select_folder_dialog_| as a transient child of the dimming window.
diff --git a/ash/webui/diagnostics_ui/backend/session_log_handler.h b/ash/webui/diagnostics_ui/backend/session_log_handler.h
index a96b3fb..366647e 100644
--- a/ash/webui/diagnostics_ui/backend/session_log_handler.h
+++ b/ash/webui/diagnostics_ui/backend/session_log_handler.h
@@ -94,7 +94,7 @@
   std::unique_ptr<NetworkingLog> networking_log_;
   ash::HoldingSpaceClient* const holding_space_client_;
   std::string save_session_log_callback_id_;
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   base::OnceClosure log_created_closure_;
   // Task runner for tasks posted by save session log handler. Used to ensure
   // posted tasks are handled while SessionLogHandler is in scope to stop
diff --git a/ash/webui/scanning/scanning_handler.h b/ash/webui/scanning/scanning_handler.h
index 12785891..5789f64 100644
--- a/ash/webui/scanning/scanning_handler.h
+++ b/ash/webui/scanning/scanning_handler.h
@@ -98,7 +98,7 @@
 
   std::string scan_location_callback_id_;
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 
   // Provides browser functionality from //chrome to the Scan app UI.
   std::unique_ptr<ScanningAppDelegate> scanning_app_delegate_;
diff --git a/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.cc b/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.cc
index faff54ea..2a8fc47 100644
--- a/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.cc
+++ b/chrome/browser/apps/platform_apps/api/media_galleries/media_galleries_api.cc
@@ -253,7 +253,7 @@
   friend class base::RefCounted<SelectDirectoryDialog>;
   ~SelectDirectoryDialog() override = default;
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   raw_ptr<WebContents> web_contents_;
   Callback callback_;
 };
diff --git a/chrome/browser/ash/arc/fileapi/arc_select_files_handler.cc b/chrome/browser/ash/arc/fileapi/arc_select_files_handler.cc
index 8701dcf4..0650b99 100644
--- a/chrome/browser/ash/arc/fileapi/arc_select_files_handler.cc
+++ b/chrome/browser/ash/arc/fileapi/arc_select_files_handler.cc
@@ -373,9 +373,10 @@
 }
 
 SelectFileDialogHolder::SelectFileDialogHolder(
-    ui::SelectFileDialog::Listener* listener)
-    : select_file_dialog_(
-          SelectFileDialogExtension::Create(listener, nullptr)) {}
+    ui::SelectFileDialog::Listener* listener) {
+  select_file_dialog_ = static_cast<SelectFileDialogExtension*>(
+      ui::SelectFileDialog::Create(listener, nullptr).get());
+}
 
 SelectFileDialogHolder::~SelectFileDialogHolder() {
   // select_file_dialog_ can be nullptr only in unit tests.
diff --git a/chrome/browser/ash/arc/fileapi/arc_select_files_handler.h b/chrome/browser/ash/arc/fileapi/arc_select_files_handler.h
index 7b080fc5..e304ae15 100644
--- a/chrome/browser/ash/arc/fileapi/arc_select_files_handler.h
+++ b/chrome/browser/ash/arc/fileapi/arc_select_files_handler.h
@@ -5,11 +5,11 @@
 #ifndef CHROME_BROWSER_ASH_ARC_FILEAPI_ARC_SELECT_FILES_HANDLER_H_
 #define CHROME_BROWSER_ASH_ARC_FILEAPI_ARC_SELECT_FILES_HANDLER_H_
 
-#include <memory>
 #include <vector>
 
 #include "ash/components/arc/mojom/file_system.mojom.h"
 #include "base/files/file_path.h"
+#include "base/memory/scoped_refptr.h"
 #include "base/memory/weak_ptr.h"
 #include "chrome/browser/ui/views/select_file_dialog_extension.h"
 #include "content/public/browser/render_frame_host.h"
@@ -146,7 +146,7 @@
       content::RenderFrameHost::JavaScriptResultCallback callback);
 
  private:
-  std::unique_ptr<SelectFileDialogExtension> select_file_dialog_;
+  scoped_refptr<SelectFileDialogExtension> select_file_dialog_;
 };
 
 }  // namespace arc
diff --git a/chrome/browser/ash/arc/fileapi/arc_select_files_handler_unittest.cc b/chrome/browser/ash/arc/fileapi/arc_select_files_handler_unittest.cc
index 4d914cc..eca76e3 100644
--- a/chrome/browser/ash/arc/fileapi/arc_select_files_handler_unittest.cc
+++ b/chrome/browser/ash/arc/fileapi/arc_select_files_handler_unittest.cc
@@ -111,8 +111,7 @@
         std::make_unique<ArcSelectFilesHandler>(profile);
 
     std::unique_ptr<MockSelectFileDialogHolder> mock_dialog_holder =
-        std::make_unique<MockSelectFileDialogHolder>(
-            arc_select_files_handler_.get());
+        std::make_unique<MockSelectFileDialogHolder>(nullptr);
     mock_dialog_holder_ = mock_dialog_holder.get();
     arc_select_files_handler_->SetDialogHolderForTesting(
         std::move(mock_dialog_holder));
diff --git a/chrome/browser/ash/crosapi/select_file_ash.cc b/chrome/browser/ash/crosapi/select_file_ash.cc
index 3108f1fe..ea8b0a8 100644
--- a/chrome/browser/ash/crosapi/select_file_ash.cc
+++ b/chrome/browser/ash/crosapi/select_file_ash.cc
@@ -4,7 +4,6 @@
 
 #include "chrome/browser/ash/crosapi/select_file_ash.h"
 
-#include <memory>
 #include <utility>
 #include <vector>
 
@@ -13,6 +12,7 @@
 #include "ash/wm/desks/desks_util.h"
 #include "base/cxx17_backports.h"
 #include "base/files/file_path.h"
+#include "base/memory/ref_counted.h"
 #include "chrome/browser/ash/crosapi/window_util.h"
 #include "chrome/browser/ui/views/select_file_dialog_extension.h"
 #include "chromeos/crosapi/mojom/select_file.mojom-shared.h"
@@ -165,7 +165,7 @@
   mojom::SelectFile::SelectCallback select_callback_;
 
   // The file select dialog.
-  std::unique_ptr<SelectFileDialogExtension> select_file_dialog_;
+  scoped_refptr<SelectFileDialogExtension> select_file_dialog_;
 
   // Optional file type extension filters.
   std::unique_ptr<ui::SelectFileDialog::FileTypeInfo> file_types_;
diff --git a/chrome/browser/ash/crostini/crostini_export_import.h b/chrome/browser/ash/crostini/crostini_export_import.h
index cda269c1..cde3ddb 100644
--- a/chrome/browser/ash/crostini/crostini_export_import.h
+++ b/chrome/browser/ash/crostini/crostini_export_import.h
@@ -258,7 +258,7 @@
       TrackerMap::iterator it);
 
   Profile* profile_;
-  std::unique_ptr<ui::SelectFileDialog> select_folder_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_folder_dialog_;
   TrackerMap status_trackers_;
   // |operation_data_storage_| persists the data required to complete an
   // operation while the file selection dialog is open/operation is in progress.
diff --git a/chrome/browser/ash/crostini/crostini_file_selector.h b/chrome/browser/ash/crostini/crostini_file_selector.h
index 92eb247..892c537 100644
--- a/chrome/browser/ash/crostini/crostini_file_selector.h
+++ b/chrome/browser/ash/crostini/crostini_file_selector.h
@@ -41,7 +41,7 @@
   raw_ptr<content::WebUI> web_ui_;
   base::OnceCallback<void(const base::FilePath&)> selected_callback_;
   base::OnceCallback<void(void)> cancelled_callback_;
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 };
 
 }  // namespace crostini
diff --git a/chrome/browser/ash/dbus/vm/vm_applications_service_provider.cc b/chrome/browser/ash/dbus/vm/vm_applications_service_provider.cc
index 13bb776..adf0546 100644
--- a/chrome/browser/ash/dbus/vm/vm_applications_service_provider.cc
+++ b/chrome/browser/ash/dbus/vm/vm_applications_service_provider.cc
@@ -40,7 +40,7 @@
 namespace {
 
 struct SelectFileData {
-  std::unique_ptr<ui::SelectFileDialog> dialog;
+  scoped_refptr<ui::SelectFileDialog> dialog;
   vm_tools::cicerone::FileSelectedSignal signal;
 };
 
diff --git a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
index fb8a347c..d822668 100644
--- a/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
+++ b/chrome/browser/ash/file_manager/file_manager_browsertest_base.cc
@@ -35,7 +35,6 @@
 #include "base/json/json_value_converter.h"
 #include "base/json/json_writer.h"
 #include "base/json/values_util.h"
-#include "base/memory/weak_ptr.h"
 #include "base/no_destructor.h"
 #include "base/path_service.h"
 #include "base/ranges/algorithm.h"
@@ -162,10 +161,9 @@
   ui::SelectFileDialog* Create(
       ui::SelectFileDialog::Listener* listener,
       std::unique_ptr<ui::SelectFilePolicy> policy) override {
-    std::unique_ptr<SelectFileDialogExtension> dialog =
+    last_select_ =
         SelectFileDialogExtension::Create(listener, std::move(policy));
-    last_select_ = base::AsWeakPtr(dialog.get());
-    return dialog.release();
+    return last_select_.get();
   }
 
   content::RenderFrameHost* GetFrameHost() {
@@ -173,7 +171,7 @@
   }
 
  private:
-  base::WeakPtr<SelectFileDialogExtension> last_select_;
+  scoped_refptr<SelectFileDialogExtension> last_select_;
 };
 
 namespace file_manager {
diff --git a/chrome/browser/ash/login/users/avatar/user_image_file_selector.h b/chrome/browser/ash/login/users/avatar/user_image_file_selector.h
index 27d9dff6..1782f9c 100644
--- a/chrome/browser/ash/login/users/avatar/user_image_file_selector.h
+++ b/chrome/browser/ash/login/users/avatar/user_image_file_selector.h
@@ -46,7 +46,7 @@
 
   base::OnceCallback<void(void)> canceled_cb_;
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 };
 
 }  // namespace ash
diff --git a/chrome/browser/devtools/devtools_file_helper.cc b/chrome/browser/devtools/devtools_file_helper.cc
index 9784c21a..4e2d706 100644
--- a/chrome/browser/devtools/devtools_file_helper.cc
+++ b/chrome/browser/devtools/devtools_file_helper.cc
@@ -125,7 +125,7 @@
         platform_util::GetTopLevel(web_contents->GetNativeView()), nullptr);
   }
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   SelectedCallback selected_callback_;
   CanceledCallback canceled_callback_;
 };
diff --git a/chrome/browser/download/download_file_picker.h b/chrome/browser/download/download_file_picker.h
index f7de56c..f6ad7db 100644
--- a/chrome/browser/download/download_file_picker.h
+++ b/chrome/browser/download/download_file_picker.h
@@ -70,7 +70,7 @@
   ConfirmationCallback file_selected_callback_;
 
   // For managing select file dialogs.
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 
   // The item to be downloaded.
   raw_ptr<download::DownloadItem> download_item_;
diff --git a/chrome/browser/download/save_package_file_picker.h b/chrome/browser/download/save_package_file_picker.h
index ec2968c3..f74b237 100644
--- a/chrome/browser/download/save_package_file_picker.h
+++ b/chrome/browser/download/save_package_file_picker.h
@@ -57,7 +57,7 @@
   std::vector<content::SavePageType> save_types_;
 
   // For managing select file dialogs.
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 };
 
 #endif  // CHROME_BROWSER_DOWNLOAD_SAVE_PACKAGE_FILE_PICKER_H_
diff --git a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
index 691f8ec..2d6caef7 100644
--- a/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
+++ b/chrome/browser/extensions/api/bookmarks/bookmarks_api.h
@@ -334,7 +334,7 @@
  protected:
   ~BookmarksIOFunction() override;
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 };
 
 class BookmarksImportFunction : public BookmarksIOFunction {
diff --git a/chrome/browser/extensions/api/developer_private/entry_picker.h b/chrome/browser/extensions/api/developer_private/entry_picker.h
index baebd27..cce72a1 100644
--- a/chrome/browser/extensions/api/developer_private/entry_picker.h
+++ b/chrome/browser/extensions/api/developer_private/entry_picker.h
@@ -54,7 +54,7 @@
   void MultiFilesSelected(const std::vector<base::FilePath>& files,
                           void* params) override;
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   raw_ptr<EntryPickerClient> client_;
 };
 
diff --git a/chrome/browser/extensions/api/file_manager/file_selector_impl.h b/chrome/browser/extensions/api/file_manager/file_selector_impl.h
index b5635a3..6ce8b1f 100644
--- a/chrome/browser/extensions/api/file_manager/file_selector_impl.h
+++ b/chrome/browser/extensions/api/file_manager/file_selector_impl.h
@@ -60,7 +60,7 @@
   void SendResponse(bool success, const base::FilePath& selected_path);
 
   // Dialog shown by selector.
-  std::unique_ptr<ui::SelectFileDialog> dialog_;
+  scoped_refptr<ui::SelectFileDialog> dialog_;
 
   // Callback to receive results.
   OnSelectedCallback callback_;
diff --git a/chrome/browser/extensions/api/file_system/file_entry_picker.h b/chrome/browser/extensions/api/file_system/file_entry_picker.h
index 13b17623..47290ef 100644
--- a/chrome/browser/extensions/api/file_system/file_entry_picker.h
+++ b/chrome/browser/extensions/api/file_system/file_entry_picker.h
@@ -60,7 +60,7 @@
 
   FileSystemDelegate::FilesSelectedCallback files_selected_callback_;
   base::OnceClosure file_selection_canceled_callback_;
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 };
 
 }  // namespace extensions
diff --git a/chrome/browser/file_select_helper.h b/chrome/browser/file_select_helper.h
index cd7acbfc..a1fff2a 100644
--- a/chrome/browser/file_select_helper.h
+++ b/chrome/browser/file_select_helper.h
@@ -301,7 +301,7 @@
   scoped_refptr<content::FileSelectListener> listener_;
 
   // Dialog box used for choosing files to upload from file form fields.
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   std::unique_ptr<ui::SelectFileDialog::FileTypeInfo> select_file_types_;
 
   // The type of file dialog last shown. This is SELECT_NONE if an
diff --git a/chrome/browser/media_galleries/media_galleries_permission_controller.h b/chrome/browser/media_galleries/media_galleries_permission_controller.h
index 8d7f368..0f55cb8 100644
--- a/chrome/browser/media_galleries/media_galleries_permission_controller.h
+++ b/chrome/browser/media_galleries/media_galleries_permission_controller.h
@@ -216,7 +216,7 @@
   // The view that's showing.
   std::unique_ptr<MediaGalleriesDialog> dialog_;
 
-  std::unique_ptr<ui::SelectFileDialog> select_folder_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_folder_dialog_;
 
   std::unique_ptr<MediaGalleryContextMenu> context_menu_;
 
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index 18ae737..a385392 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -2296,7 +2296,7 @@
   // Transfer the ownership of select file dialog so that the ref count is
   // released after the function returns. This is needed because the passed-in
   // data such as |file_info| and |params| could be owned by the dialog.
-  std::unique_ptr<ui::SelectFileDialog> dialog = std::move(select_file_dialog_);
+  scoped_refptr<ui::SelectFileDialog> dialog = std::move(select_file_dialog_);
 
   profile_->set_last_selected_directory(file_info.file_path.DirName());
 
diff --git a/chrome/browser/ui/browser.h b/chrome/browser/ui/browser.h
index b847b57..e80e3d1 100644
--- a/chrome/browser/ui/browser.h
+++ b/chrome/browser/ui/browser.h
@@ -1243,7 +1243,7 @@
   std::unique_ptr<FindBarController> find_bar_controller_;
 
   // Dialog box used for opening and saving files.
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 
   // Helper which implements the ContentSettingBubbleModel interface.
   std::unique_ptr<BrowserContentSettingBubbleModelDelegate>
diff --git a/chrome/browser/ui/certificate_dialogs.cc b/chrome/browser/ui/certificate_dialogs.cc
index 8909ffe7..668c0ea 100644
--- a/chrome/browser/ui/certificate_dialogs.cc
+++ b/chrome/browser/ui/certificate_dialogs.cc
@@ -92,7 +92,7 @@
 
   std::string GetCMSString(size_t start, size_t end) const;
 
-  std::unique_ptr<ui::SelectFileDialog> const select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> const select_file_dialog_;
 
   // The certificate hierarchy (leaf cert first).
   std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> cert_chain_list_;
diff --git a/chrome/browser/ui/chrome_select_file_policy_unittest.cc b/chrome/browser/ui/chrome_select_file_policy_unittest.cc
index d0bfe62..50a42c7 100644
--- a/chrome/browser/ui/chrome_select_file_policy_unittest.cc
+++ b/chrome/browser/ui/chrome_select_file_policy_unittest.cc
@@ -68,7 +68,7 @@
   }
 
  private:
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 
   bool file_selection_initialisation_in_progress;
 };
diff --git a/chrome/browser/ui/passwords/settings/password_manager_porter.h b/chrome/browser/ui/passwords/settings/password_manager_porter.h
index 220fce9a..54fe8af 100644
--- a/chrome/browser/ui/passwords/settings/password_manager_porter.h
+++ b/chrome/browser/ui/passwords/settings/password_manager_porter.h
@@ -84,7 +84,7 @@
 
   std::unique_ptr<password_manager::PasswordManagerExporter> exporter_;
   std::unique_ptr<password_manager::PasswordImporter> importer_;
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   raw_ptr<Profile> profile_;
 
   // We store |presenter_| and
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.cc b/chrome/browser/ui/views/select_file_dialog_extension.cc
index 204a3500..4621521 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension.cc
@@ -71,14 +71,15 @@
  public:
   static PendingDialog* GetInstance();
   void Add(SelectFileDialogExtension::RoutingID id,
-           SelectFileDialogExtension* dialog);
+           scoped_refptr<SelectFileDialogExtension> dialog);
   void Remove(SelectFileDialogExtension::RoutingID id);
-  SelectFileDialogExtension* Find(SelectFileDialogExtension::RoutingID id);
+  scoped_refptr<SelectFileDialogExtension> Find(
+      SelectFileDialogExtension::RoutingID id);
 
  private:
   friend struct base::DefaultSingletonTraits<PendingDialog>;
   using Map = std::map<SelectFileDialogExtension::RoutingID,
-                       raw_ptr<SelectFileDialogExtension>>;
+                       scoped_refptr<SelectFileDialogExtension>>;
   Map map_;
 };
 
@@ -89,8 +90,8 @@
 }
 
 void PendingDialog::Add(SelectFileDialogExtension::RoutingID id,
-                        SelectFileDialogExtension* dialog) {
-  DCHECK(dialog);
+                        scoped_refptr<SelectFileDialogExtension> dialog) {
+  DCHECK(dialog.get());
   if (map_.find(id) == map_.end())
     map_.insert(std::make_pair(id, dialog));
   else
@@ -101,7 +102,7 @@
   map_.erase(id);
 }
 
-SelectFileDialogExtension* PendingDialog::Find(
+scoped_refptr<SelectFileDialogExtension> PendingDialog::Find(
     SelectFileDialogExtension::RoutingID id) {
   Map::const_iterator it = map_.find(id);
   if (it == map_.end())
@@ -255,12 +256,10 @@
     SelectFileDialogExtension::Owner&&) = default;
 
 // static
-std::unique_ptr<SelectFileDialogExtension> SelectFileDialogExtension::Create(
+SelectFileDialogExtension* SelectFileDialogExtension::Create(
     Listener* listener,
     std::unique_ptr<ui::SelectFilePolicy> policy) {
-  // Using WrapUnique because the constructor is private.
-  return base::WrapUnique(
-      new SelectFileDialogExtension(listener, std::move(policy)));
+  return new SelectFileDialogExtension(listener, std::move(policy));
 }
 
 SelectFileDialogExtension::SelectFileDialogExtension(
@@ -304,9 +303,9 @@
     RoutingID routing_id,
     const ui::SelectedFileInfo& file,
     int index) {
-  SelectFileDialogExtension* dialog =
+  scoped_refptr<SelectFileDialogExtension> dialog =
       PendingDialog::GetInstance()->Find(routing_id);
-  if (!dialog)
+  if (!dialog.get())
     return;
   dialog->selection_type_ = SINGLE_FILE;
   dialog->selection_files_.clear();
@@ -318,9 +317,9 @@
 void SelectFileDialogExtension::OnMultiFilesSelected(
     RoutingID routing_id,
     const std::vector<ui::SelectedFileInfo>& files) {
-  SelectFileDialogExtension* dialog =
+  scoped_refptr<SelectFileDialogExtension> dialog =
       PendingDialog::GetInstance()->Find(routing_id);
-  if (!dialog)
+  if (!dialog.get())
     return;
   dialog->selection_type_ = MULTIPLE_FILES;
   dialog->selection_files_ = files;
@@ -329,9 +328,9 @@
 
 // static
 void SelectFileDialogExtension::OnFileSelectionCanceled(RoutingID routing_id) {
-  SelectFileDialogExtension* dialog =
+  scoped_refptr<SelectFileDialogExtension> dialog =
       PendingDialog::GetInstance()->Find(routing_id);
-  if (!dialog)
+  if (!dialog.get())
     return;
   dialog->selection_type_ = CANCEL;
   dialog->selection_files_.clear();
@@ -563,5 +562,5 @@
 
 // static
 bool SelectFileDialogExtension::PendingExists(RoutingID routing_id) {
-  return PendingDialog::GetInstance()->Find(routing_id) != nullptr;
+  return PendingDialog::GetInstance()->Find(routing_id).get() != nullptr;
 }
diff --git a/chrome/browser/ui/views/select_file_dialog_extension.h b/chrome/browser/ui/views/select_file_dialog_extension.h
index 8062b7a..b1982ff 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension.h
+++ b/chrome/browser/ui/views/select_file_dialog_extension.h
@@ -44,7 +44,7 @@
   SelectFileDialogExtension(const SelectFileDialogExtension&) = delete;
   SelectFileDialogExtension& operator=(SelectFileDialogExtension&) = delete;
 
-  static std::unique_ptr<SelectFileDialogExtension> Create(
+  static SelectFileDialogExtension* Create(
       ui::SelectFileDialog::Listener* listener,
       std::unique_ptr<ui::SelectFilePolicy> policy);
 
@@ -116,8 +116,6 @@
                                        bool show_android_picker_apps,
                                        bool use_media_store_filter = false);
 
-  ~SelectFileDialogExtension() override;
-
  protected:
   // ui::SelectFileDialog:
   void SelectFileImpl(Type type,
@@ -146,10 +144,11 @@
                            const std::string& id);
   void OnSystemDialogWillClose();
 
-  // Use Create().
+  // Object is ref-counted, use Create().
   explicit SelectFileDialogExtension(
       SelectFileDialog::Listener* listener,
       std::unique_ptr<ui::SelectFilePolicy> policy);
+  ~SelectFileDialogExtension() override;
 
   // Invokes the appropriate file selection callback on our listener.
   void NotifyListener();
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
index 488586f..80c8abb 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension_browsertest.cc
@@ -14,7 +14,6 @@
 #include "base/files/file_util.h"
 #include "base/files/scoped_temp_dir.h"
 #include "base/logging.h"
-#include "base/memory/ptr_util.h"
 #include "base/path_service.h"
 #include "base/run_loop.h"
 #include "base/strings/utf_string_conversions.h"
@@ -168,8 +167,7 @@
   void SetUp() override {
     // Create the dialog wrapper and listener objects.
     listener_ = std::make_unique<MockSelectFileDialogListener>();
-    dialog_ = base::WrapUnique(
-        new SelectFileDialogExtension(listener_.get(), nullptr));
+    dialog_ = new SelectFileDialogExtension(listener_.get(), nullptr);
 
     // One mount point will be needed. Files app looks for the "Downloads"
     // volume mount point by default, so use that.
@@ -295,8 +293,8 @@
 
   void TryOpeningSecondDialog(const gfx::NativeWindow& owning_window) {
     second_listener_ = std::make_unique<MockSelectFileDialogListener>();
-    second_dialog_ = base::WrapUnique(
-        new SelectFileDialogExtension(second_listener_.get(), nullptr));
+    second_dialog_ =
+        new SelectFileDialogExtension(second_listener_.get(), nullptr);
 
     // The dialog type is not relevant for this test but is required: use the
     // open file dialog type.
@@ -343,10 +341,10 @@
   base::FilePath downloads_dir_;
 
   std::unique_ptr<MockSelectFileDialogListener> listener_;
-  std::unique_ptr<SelectFileDialogExtension> dialog_;
+  scoped_refptr<SelectFileDialogExtension> dialog_;
 
   std::unique_ptr<MockSelectFileDialogListener> second_listener_;
-  std::unique_ptr<SelectFileDialogExtension> second_dialog_;
+  scoped_refptr<SelectFileDialogExtension> second_dialog_;
 
   bool use_file_type_filter_;
 
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_factory.cc b/chrome/browser/ui/views/select_file_dialog_extension_factory.cc
index 8e8c501..87b7ea1 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension_factory.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension_factory.cc
@@ -4,10 +4,7 @@
 
 #include "chrome/browser/ui/views/select_file_dialog_extension_factory.h"
 
-#include <memory>
-
 #include "chrome/browser/ui/views/select_file_dialog_extension.h"
-#include "ui/shell_dialogs/select_file_dialog.h"
 #include "ui/shell_dialogs/select_file_policy.h"
 
 SelectFileDialogExtensionFactory::SelectFileDialogExtensionFactory() {
@@ -19,6 +16,5 @@
 ui::SelectFileDialog* SelectFileDialogExtensionFactory::Create(
     ui::SelectFileDialog::Listener* listener,
     std::unique_ptr<ui::SelectFilePolicy> policy) {
-  return SelectFileDialogExtension::Create(listener, std::move(policy))
-      .release();
+  return SelectFileDialogExtension::Create(listener, std::move(policy));
 }
diff --git a/chrome/browser/ui/views/select_file_dialog_extension_unittest.cc b/chrome/browser/ui/views/select_file_dialog_extension_unittest.cc
index 0e8dcac..2e808cb4 100644
--- a/chrome/browser/ui/views/select_file_dialog_extension_unittest.cc
+++ b/chrome/browser/ui/views/select_file_dialog_extension_unittest.cc
@@ -7,8 +7,6 @@
 #include <memory>
 
 #include "base/files/file_path.h"
-#include "base/memory/ptr_util.h"
-#include "base/test/scoped_feature_list.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/shell_dialogs/select_file_policy.h"
 #include "ui/shell_dialogs/selected_file_info.h"
@@ -28,7 +26,7 @@
   SelectFileDialogExtensionTest& operator=(
       const SelectFileDialogExtensionTest&) = delete;
 
-  static std::unique_ptr<SelectFileDialogExtension> CreateDialog(
+  static SelectFileDialogExtension* CreateDialog(
       ui::SelectFileDialog::Listener* listener) {
     SelectFileDialogExtension* dialog =
         new SelectFileDialogExtension(listener, nullptr);
@@ -36,7 +34,7 @@
     EXPECT_FALSE(SelectFileDialogExtension::PendingExists(kDefaultRoutingID));
     dialog->AddPending(kDefaultRoutingID);
     EXPECT_TRUE(SelectFileDialogExtension::PendingExists(kDefaultRoutingID));
-    return base::WrapUnique(dialog);
+    return dialog;
   }
 };
 
@@ -89,13 +87,13 @@
   }
 
  private:
-  std::unique_ptr<SelectFileDialogExtension> dialog_;
+  scoped_refptr<SelectFileDialogExtension> dialog_;
 };
 
 TEST_F(SelectFileDialogExtensionTest, FileSelected) {
   const int kFileIndex = 5;
   auto listener = std::make_unique<TestListener>();
-  std::unique_ptr<SelectFileDialogExtension> dialog =
+  scoped_refptr<SelectFileDialogExtension> dialog =
       CreateDialog(listener.get());
   // Simulate selecting a file.
   ui::SelectedFileInfo info;
@@ -109,7 +107,7 @@
 
 TEST_F(SelectFileDialogExtensionTest, FileSelectionCanceled) {
   auto listener = std::make_unique<TestListener>();
-  std::unique_ptr<SelectFileDialogExtension> dialog =
+  scoped_refptr<SelectFileDialogExtension> dialog =
       CreateDialog(listener.get());
   // Simulate cancelling the dialog.
   SelectFileDialogExtension::OnFileSelectionCanceled(kDefaultRoutingID);
diff --git a/chrome/browser/ui/webui/certificates_handler.h b/chrome/browser/ui/webui/certificates_handler.h
index 5716c35..4155153 100644
--- a/chrome/browser/ui/webui/certificates_handler.h
+++ b/chrome/browser/ui/webui/certificates_handler.h
@@ -246,7 +246,7 @@
   bool use_hardware_backed_;
   std::string file_data_;
   net::ScopedCERTCertificateList selected_cert_list_;
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   crypto::ScopedPK11Slot slot_;
 
   // Used in reading and writing certificate files.
diff --git a/chrome/browser/ui/webui/memory_internals_ui.cc b/chrome/browser/ui/webui/memory_internals_ui.cc
index 16f3a069..f9bdcc07 100644
--- a/chrome/browser/ui/webui/memory_internals_ui.cc
+++ b/chrome/browser/ui/webui/memory_internals_ui.cc
@@ -163,7 +163,7 @@
 
   void SaveTraceFinished(bool success);
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 #if !BUILDFLAG(IS_ANDROID)
   raw_ptr<content::WebUI> web_ui_;  // The WebUI that owns us.
 #endif
diff --git a/chrome/browser/ui/webui/net_export_ui.cc b/chrome/browser/ui/webui/net_export_ui.cc
index 4537b72..463bb8a93 100644
--- a/chrome/browser/ui/webui/net_export_ui.cc
+++ b/chrome/browser/ui/webui/net_export_ui.cc
@@ -156,7 +156,7 @@
   net::NetLogCaptureMode capture_mode_;
   uint64_t max_log_file_size_;
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 
   base::WeakPtrFactory<NetExportMessageHandler> weak_ptr_factory_{this};
 };
diff --git a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h
index 1d70797..3769946 100644
--- a/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h
+++ b/chrome/browser/ui/webui/new_tab_page/new_tab_page_handler.h
@@ -195,7 +195,7 @@
   base::TimeTicks background_images_request_start_time_;
   absl::optional<base::TimeTicks> one_google_bar_load_start_time_;
   raw_ptr<Profile> profile_;
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   raw_ptr<content::WebContents> web_contents_;
   base::Time ntp_navigation_start_time_;
   NTPUserDataLogger logger_;
diff --git a/chrome/browser/ui/webui/policy/policy_ui_handler.h b/chrome/browser/ui/webui/policy/policy_ui_handler.h
index 5a70006..d512c18 100644
--- a/chrome/browser/ui/webui/policy/policy_ui_handler.h
+++ b/chrome/browser/ui/webui/policy/policy_ui_handler.h
@@ -80,7 +80,7 @@
 
   void WritePoliciesToJSONFile(const base::FilePath& path);
 
-  std::unique_ptr<ui::SelectFileDialog> export_policies_select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> export_policies_select_file_dialog_;
 
   std::unique_ptr<policy::PolicyValueAndStatusAggregator>
       policy_value_and_status_aggregator_;
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
index 9c8a564..c33c820 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler.h
@@ -84,7 +84,7 @@
   const raw_ptr<content::WebContents> preview_web_contents_;
 
   // The underlying dialog object. Protected so unit tests can access it.
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 
  private:
   void PostPrintToPdfTask();
diff --git a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc
index fec946d..1804e21 100644
--- a/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc
+++ b/chrome/browser/ui/webui/print_preview/pdf_printer_handler_win_unittest.cc
@@ -10,7 +10,8 @@
 
 #include "base/bind.h"
 #include "base/callback_helpers.h"
-#include "base/memory/ptr_util.h"
+#include "base/memory/ref_counted.h"
+#include "base/memory/ref_counted_memory.h"
 #include "base/run_loop.h"
 #include "chrome/browser/platform_util.h"
 #include "chrome/browser/ui/browser_commands.h"
@@ -76,9 +77,9 @@
     ui::SelectFileDialog::FileTypeInfo file_type_info;
     file_type_info.extensions.resize(1);
     file_type_info.extensions[0].push_back(FILE_PATH_LITERAL("pdf"));
-    select_file_dialog_ = base::WrapUnique(ui::CreateWinSelectFileDialog(
+    select_file_dialog_ = ui::CreateWinSelectFileDialog(
         this, nullptr /*policy already checked*/,
-        base::BindRepeating(&ExecuteCancelledSelectFileDialog)));
+        base::BindRepeating(&ExecuteCancelledSelectFileDialog));
     select_file_dialog_->SelectFile(
         ui::SelectFileDialog::SELECT_SAVEAS_FILE, std::u16string(),
         default_filename, &file_type_info, 0, base::FilePath::StringType(),
diff --git a/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h b/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h
index c31eecd..fd4acd64 100644
--- a/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h
+++ b/chrome/browser/ui/webui/settings/ash/cups_printers_handler.h
@@ -261,7 +261,7 @@
   // that has been resolved in the lifetime of this object.
   std::map<std::string, PpdProvider::ResolvedPrintersList> resolved_printers_;
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   std::string webui_callback_id_;
   CupsPrintersManager* printers_manager_;
   std::unique_ptr<local_discovery::EndpointResolver> endpoint_resolver_;
diff --git a/chrome/browser/ui/webui/settings/downloads_handler.h b/chrome/browser/ui/webui/settings/downloads_handler.h
index 0f53fb1..98d92d8 100644
--- a/chrome/browser/ui/webui/settings/downloads_handler.h
+++ b/chrome/browser/ui/webui/settings/downloads_handler.h
@@ -81,7 +81,7 @@
 
   PrefChangeRegistrar pref_registrar_;
 
-  std::unique_ptr<ui::SelectFileDialog> select_folder_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_folder_dialog_;
 
   base::WeakPtrFactory<DownloadsHandler> weak_factory_{this};
 };
diff --git a/chrome/browser/ui/webui/settings/import_data_handler.h b/chrome/browser/ui/webui/settings/import_data_handler.h
index 5421834..26544eb 100644
--- a/chrome/browser/ui/webui/settings/import_data_handler.h
+++ b/chrome/browser/ui/webui/settings/import_data_handler.h
@@ -76,7 +76,7 @@
   bool import_did_succeed_{false};
   bool importer_list_loaded_{false};
 
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 };
 
 }  // namespace settings
diff --git a/chrome/browser/ui/webui/support_tool/support_tool_ui.cc b/chrome/browser/ui/webui/support_tool/support_tool_ui.cc
index c389831a..04ae47da 100644
--- a/chrome/browser/ui/webui/support_tool/support_tool_ui.cc
+++ b/chrome/browser/ui/webui/support_tool/support_tool_ui.cc
@@ -118,7 +118,7 @@
   std::set<feedback::PIIType> selected_pii_to_keep_;
   base::FilePath data_path_;
   std::unique_ptr<SupportToolHandler> handler_;
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   base::WeakPtrFactory<SupportToolMessageHandler> weak_ptr_factory_{this};
 };
 
diff --git a/chrome/test/ppapi/ppapi_test_select_file_dialog_factory.cc b/chrome/test/ppapi/ppapi_test_select_file_dialog_factory.cc
index 686cff5..792c377 100644
--- a/chrome/test/ppapi/ppapi_test_select_file_dialog_factory.cc
+++ b/chrome/test/ppapi/ppapi_test_select_file_dialog_factory.cc
@@ -5,7 +5,6 @@
 #include "chrome/test/ppapi/ppapi_test_select_file_dialog_factory.h"
 
 #include "base/bind.h"
-#include "base/memory/weak_ptr.h"
 #include "base/threading/thread_task_runner_handle.h"
 #include "testing/gtest/include/gtest/gtest.h"
 #include "ui/shell_dialogs/select_file_dialog.h"
@@ -61,8 +60,8 @@
     base::ThreadTaskRunnerHandle::Get()->PostTask(
         FROM_HERE,
         base::BindOnce(
-            &PPAPITestSelectFileDialog::RespondToFileSelectionRequest,
-            base::AsWeakPtr(this), params));
+            &PPAPITestSelectFileDialog::RespondToFileSelectionRequest, this,
+            params));
   }
   bool HasMultipleFileTypeChoicesImpl() override { return false; }
 
diff --git a/content/browser/file_system_access/file_system_chooser.h b/content/browser/file_system_access/file_system_chooser.h
index 8acae58..18f71a3 100644
--- a/content/browser/file_system_access/file_system_chooser.h
+++ b/content/browser/file_system_access/file_system_chooser.h
@@ -107,7 +107,7 @@
   base::ScopedClosureRunner fullscreen_block_
       GUARDED_BY_CONTEXT(sequence_checker_);
 
-  std::unique_ptr<ui::SelectFileDialog> dialog_;
+  scoped_refptr<ui::SelectFileDialog> dialog_;
 };
 
 }  // namespace content
diff --git a/content/browser/webrtc/webrtc_internals.h b/content/browser/webrtc/webrtc_internals.h
index 83a660a6..1047945c 100644
--- a/content/browser/webrtc/webrtc_internals.h
+++ b/content/browser/webrtc/webrtc_internals.h
@@ -234,7 +234,7 @@
   base::Value::List get_user_media_requests_;
 
   // For managing select file dialog.
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
   enum class SelectionType {
     kRtcEventLogs,
     kAudioDebugRecordings
diff --git a/ui/shell_dialogs/base_shell_dialog_win.cc b/ui/shell_dialogs/base_shell_dialog_win.cc
index b960f3fb..aa20fab4 100644
--- a/ui/shell_dialogs/base_shell_dialog_win.cc
+++ b/ui/shell_dialogs/base_shell_dialog_win.cc
@@ -78,7 +78,6 @@
   return run_state;
 }
 
-// static
 void BaseShellDialogImpl::EndRun(std::unique_ptr<RunState> run_state) {
   if (run_state->owner) {
     DCHECK(IsRunningDialogForOwner(run_state->owner));
@@ -88,8 +87,7 @@
   }
 }
 
-// static
-bool BaseShellDialogImpl::IsRunningDialogForOwner(HWND owner) {
+bool BaseShellDialogImpl::IsRunningDialogForOwner(HWND owner) const {
   return (owner && GetOwners().find(owner) != GetOwners().end());
 }
 
diff --git a/ui/shell_dialogs/base_shell_dialog_win.h b/ui/shell_dialogs/base_shell_dialog_win.h
index 7aec2865..404a117 100644
--- a/ui/shell_dialogs/base_shell_dialog_win.h
+++ b/ui/shell_dialogs/base_shell_dialog_win.h
@@ -59,21 +59,21 @@
     scoped_refptr<base::SingleThreadTaskRunner> dialog_task_runner;
   };
 
-  // Cleans up after a dialog run. If the run_state has a valid HWND this makes
-  // sure that the window is enabled. This is essential because BeginRun
-  // aggressively guards against multiple modal dialogs per HWND. Must be called
-  // on the UI thread after the result of the dialog has been determined.
-  static void EndRun(std::unique_ptr<RunState> run_state);
-
-  // Returns true if a modal shell dialog is currently active for the specified
-  // owner. Must be called on the UI thread.
-  static bool IsRunningDialogForOwner(HWND owner);
-
   // Called at the beginning of a modal dialog run. Disables the owner window
   // and tracks it. Returns the dedicated single-threaded sequence that the
   // dialog will be run on.
   std::unique_ptr<RunState> BeginRun(HWND owner);
 
+  // Cleans up after a dialog run. If the run_state has a valid HWND this makes
+  // sure that the window is enabled. This is essential because BeginRun
+  // aggressively guards against multiple modal dialogs per HWND. Must be called
+  // on the UI thread after the result of the dialog has been determined.
+  void EndRun(std::unique_ptr<RunState> run_state);
+
+  // Returns true if a modal shell dialog is currently active for the specified
+  // owner. Must be called on the UI thread.
+  bool IsRunningDialogForOwner(HWND owner) const;
+
  private:
   typedef std::set<HWND> Owners;
 
diff --git a/ui/shell_dialogs/select_file_dialog.cc b/ui/shell_dialogs/select_file_dialog.cc
index 0101272..6260f90 100644
--- a/ui/shell_dialogs/select_file_dialog.cc
+++ b/ui/shell_dialogs/select_file_dialog.cc
@@ -86,14 +86,12 @@
 }
 
 // static
-std::unique_ptr<SelectFileDialog> SelectFileDialog::Create(
+scoped_refptr<SelectFileDialog> SelectFileDialog::Create(
     Listener* listener,
-    std::unique_ptr<SelectFilePolicy> policy) {
-  if (dialog_factory_) {
-    return base::WrapUnique(
-        dialog_factory_->Create(listener, std::move(policy)));
-  }
-  return base::WrapUnique(CreateSelectFileDialog(listener, std::move(policy)));
+    std::unique_ptr<ui::SelectFilePolicy> policy) {
+  if (dialog_factory_)
+    return dialog_factory_->Create(listener, std::move(policy));
+  return CreateSelectFileDialog(listener, std::move(policy));
 }
 
 base::FilePath SelectFileDialog::GetShortenedFilePath(
@@ -128,7 +126,6 @@
     gfx::NativeWindow owning_window,
     void* params,
     const GURL* caller) {
-  CheckCalledOnValidSequence();
   DCHECK(listener_);
 
   if (select_file_policy_.get() &&
@@ -139,8 +136,8 @@
     // Post a task rather than calling FileSelectionCanceled directly to ensure
     // that the listener is called asynchronously.
     base::ThreadTaskRunnerHandle::Get()->PostTask(
-        FROM_HERE, base::BindOnce(&SelectFileDialog::CancelFileSelection,
-                                  AsWeakPtr(), params));
+        FROM_HERE,
+        base::BindOnce(&SelectFileDialog::CancelFileSelection, this, params));
     return;
   }
 
@@ -161,12 +158,9 @@
   DCHECK(listener_);
 }
 
-SelectFileDialog::~SelectFileDialog() {
-  CheckCalledOnValidSequence();
-}
+SelectFileDialog::~SelectFileDialog() {}
 
 void SelectFileDialog::CancelFileSelection(void* params) {
-  CheckCalledOnValidSequence();
   if (listener_)
     listener_->FileSelectionCanceled(params);
 }
diff --git a/ui/shell_dialogs/select_file_dialog.h b/ui/shell_dialogs/select_file_dialog.h
index 5558f30..cff3cfc2 100644
--- a/ui/shell_dialogs/select_file_dialog.h
+++ b/ui/shell_dialogs/select_file_dialog.h
@@ -11,8 +11,7 @@
 
 #include "base/files/file_path.h"
 #include "base/memory/raw_ptr.h"
-#include "base/memory/weak_ptr.h"
-#include "base/sequence_checker.h"
+#include "base/memory/ref_counted.h"
 #include "ui/gfx/native_widget_types.h"
 #include "ui/shell_dialogs/base_shell_dialog.h"
 #include "ui/shell_dialogs/shell_dialogs_export.h"
@@ -27,7 +26,7 @@
 
 // Shows a dialog box for selecting a file or a folder.
 class SHELL_DIALOGS_EXPORT SelectFileDialog
-    : public base::SupportsWeakPtr<SelectFileDialog>,
+    : public base::RefCountedThreadSafe<SelectFileDialog>,
       public BaseShellDialog {
  public:
   enum Type {
@@ -110,14 +109,14 @@
   //
   // The lifetime of the Listener is not managed by this class. The calling
   // code should call always ListenerDestroyed() (on the base class
-  // BaseShellDialog) when the listener is destroyed.
-  static std::unique_ptr<SelectFileDialog> Create(
+  // BaseShellDialog) when the listener is destroyed since the SelectFileDialog
+  // is refcounted and uses a background thread.
+  static scoped_refptr<SelectFileDialog> Create(
       Listener* listener,
       std::unique_ptr<SelectFilePolicy> policy);
 
   SelectFileDialog(const SelectFileDialog&) = delete;
   SelectFileDialog& operator=(const SelectFileDialog&) = delete;
-  ~SelectFileDialog() override;
 
   // Holds information about allowed extensions on a file save dialog.
   struct SHELL_DIALOGS_EXPORT FileTypeInfo {
@@ -212,8 +211,11 @@
   bool HasMultipleFileTypeChoices();
 
  protected:
+  friend class base::RefCountedThreadSafe<SelectFileDialog>;
+
   explicit SelectFileDialog(Listener* listener,
                             std::unique_ptr<SelectFilePolicy> policy);
+  ~SelectFileDialog() override;
 
   // Displays the actual file-selection dialog.
   // This is overridden in the platform-specific descendants of FileSelectDialog
@@ -230,18 +232,15 @@
       void* params,
       const GURL* caller) = 0;
 
-  // SelectFileDialog and each platform implementation should be accessed only
-  // in the main thread. Implementations often use background threads to
-  // interface with the system or for IO, but the SelectFileDialog uses
-  // unique_ptr and WeakPtr, which are only guaranteed to be valid in the thread
-  // that constructed it (main thread).
-  void CheckCalledOnValidSequence() {
-    DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  }
   // The listener to be notified of selection completion.
   raw_ptr<Listener> listener_;
 
  private:
+  // Tests if the file selection dialog can be displayed by
+  // testing if the AllowFileSelectionDialogs-Policy is
+  // either unset or set to true.
+  bool CanOpenSelectFileDialog();
+
   // Informs the |listener_| that the file selection dialog was canceled. Moved
   // to a function for being able to post it to the message loop.
   void CancelFileSelection(void* params);
@@ -249,8 +248,6 @@
   // Returns true if the dialog has multiple file type choices.
   virtual bool HasMultipleFileTypeChoicesImpl() = 0;
 
-  SEQUENCE_CHECKER(sequence_checker_);
-
   std::unique_ptr<SelectFilePolicy> select_file_policy_;
 };
 
diff --git a/ui/shell_dialogs/select_file_dialog_android.cc b/ui/shell_dialogs/select_file_dialog_android.cc
index 7fe6118..4b2b8932d 100644
--- a/ui/shell_dialogs/select_file_dialog_android.cc
+++ b/ui/shell_dialogs/select_file_dialog_android.cc
@@ -108,7 +108,6 @@
 }
 
 void SelectFileDialogImpl::ListenerDestroyed() {
-  CheckCalledOnValidSequence();
   listener_ = nullptr;
 }
 
@@ -122,7 +121,6 @@
     gfx::NativeWindow owning_window,
     void* params,
     const GURL* caller) {
-  CheckCalledOnValidSequence();
   JNIEnv* env = base::android::AttachCurrentThread();
 
   // The first element in the pair is a list of accepted types, the second
diff --git a/ui/shell_dialogs/select_file_dialog_lacros.cc b/ui/shell_dialogs/select_file_dialog_lacros.cc
index 779803a8..2c3d56a 100644
--- a/ui/shell_dialogs/select_file_dialog_lacros.cc
+++ b/ui/shell_dialogs/select_file_dialog_lacros.cc
@@ -7,7 +7,6 @@
 #include <utility>
 
 #include "base/bind.h"
-#include "base/memory/weak_ptr.h"
 #include "base/notreached.h"
 #include "chromeos/crosapi/mojom/select_file.mojom-shared.h"
 #include "chromeos/crosapi/mojom/select_file.mojom.h"
@@ -122,7 +121,6 @@
     gfx::NativeWindow owning_window,
     void* params,
     const GURL* caller) {
-  CheckCalledOnValidSequence();
   params_ = params;
 
   crosapi::mojom::SelectFileOptionsPtr options =
@@ -154,15 +152,13 @@
   chromeos::LacrosService::Get()
       ->GetRemote<crosapi::mojom::SelectFile>()
       ->Select(std::move(options),
-               base::BindOnce(&SelectFileDialogLacros::OnSelected,
-                              base::AsWeakPtr(this)));
+               base::BindOnce(&SelectFileDialogLacros::OnSelected, this));
 }
 
 void SelectFileDialogLacros::OnSelected(
     crosapi::mojom::SelectFileResult result,
     std::vector<crosapi::mojom::SelectedFileInfoPtr> mojo_files,
     int file_type_index) {
-  CheckCalledOnValidSequence();
   owning_shell_window_id_.clear();
   if (!listener_)
     return;
diff --git a/ui/shell_dialogs/select_file_dialog_linux_kde.cc b/ui/shell_dialogs/select_file_dialog_linux_kde.cc
index ce6ef04..b4b7704 100644
--- a/ui/shell_dialogs/select_file_dialog_linux_kde.cc
+++ b/ui/shell_dialogs/select_file_dialog_linux_kde.cc
@@ -10,9 +10,6 @@
 #include "base/callback_helpers.h"
 #include "base/command_line.h"
 #include "base/logging.h"
-#include "base/memory/ref_counted.h"
-#include "base/memory/scoped_refptr.h"
-#include "base/memory/weak_ptr.h"
 #include "base/nix/mime_util_xdg.h"
 #include "base/nix/xdg_util.h"
 #include "base/process/launch.h"
@@ -102,9 +99,6 @@
     int exit_code;
   };
 
-  using RefCountedKDialogOutputParams =
-      base::RefCountedData<KDialogOutputParams>;
-
   // Get the filters from |file_types_| and concatenate them into
   // |filter_string|.
   std::string GetMimeTypeFilterString();
@@ -119,8 +113,8 @@
                              base::CommandLine* command_line);
 
   // Call KDialog on the FILE thread and return the results.
-  void CallKDialogOutput(const KDialogParams& params,
-                         scoped_refptr<RefCountedKDialogOutputParams>);
+  std::unique_ptr<KDialogOutputParams> CallKDialogOutput(
+      const KDialogParams& params);
 
   // Notifies the listener that a single file was chosen.
   void FileSelected(const base::FilePath& path, void* params);
@@ -157,23 +151,22 @@
 
   // Common function for OnSelectSingleFileDialogResponse and
   // OnSelectSingleFolderDialogResponse.
-  void SelectSingleFileHelper(
-      void* params,
-      bool allow_folder,
-      scoped_refptr<RefCountedKDialogOutputParams> results);
+  void SelectSingleFileHelper(void* params,
+                              bool allow_folder,
+                              std::unique_ptr<KDialogOutputParams> results);
 
   void OnSelectSingleFileDialogResponse(
       gfx::AcceleratedWidget parent,
       void* params,
-      scoped_refptr<RefCountedKDialogOutputParams> results);
+      std::unique_ptr<KDialogOutputParams> results);
   void OnSelectMultiFileDialogResponse(
       gfx::AcceleratedWidget parent,
       void* params,
-      scoped_refptr<RefCountedKDialogOutputParams> results);
+      std::unique_ptr<KDialogOutputParams> results);
   void OnSelectSingleFolderDialogResponse(
       gfx::AcceleratedWidget parent,
       void* params,
-      scoped_refptr<RefCountedKDialogOutputParams> results);
+      std::unique_ptr<KDialogOutputParams> results);
 
   // Should be either DESKTOP_ENVIRONMENT_KDE3, KDE4, or KDE5.
   base::nix::DesktopEnvironment desktop_;
@@ -385,9 +378,8 @@
   return base::JoinString(filters, "|");
 }
 
-void SelectFileDialogLinuxKde::CallKDialogOutput(
-    const KDialogParams& params,
-    scoped_refptr<RefCountedKDialogOutputParams> results) {
+std::unique_ptr<SelectFileDialogLinuxKde::KDialogOutputParams>
+SelectFileDialogLinuxKde::CallKDialogOutput(const KDialogParams& params) {
   DCHECK(pipe_task_runner_->RunsTasksInCurrentSequence());
   base::CommandLine::StringVector cmd_vector;
   cmd_vector.push_back(kKdialogBinary);
@@ -396,11 +388,13 @@
                         params.parent, params.file_operation,
                         params.multiple_selection, &command_line);
 
-  //  Get output from KDialog
-  base::GetAppOutputWithExitCode(command_line, &results->data.output,
-                                 &results->data.exit_code);
-  if (!results->data.output.empty())
-    results->data.output.erase(results->data.output.size() - 1);
+  auto results = std::make_unique<KDialogOutputParams>();
+  // Get output from KDialog
+  base::GetAppOutputWithExitCode(command_line, &results->output,
+                                 &results->exit_code);
+  if (!results->output.empty())
+    results->output.erase(results->output.size() - 1);
+  return results;
 }
 
 void SelectFileDialogLinuxKde::GetKDialogCommandLine(
@@ -481,20 +475,17 @@
   int title_message_id = (type == SELECT_UPLOAD_FOLDER)
                              ? IDS_SELECT_UPLOAD_FOLDER_DIALOG_TITLE
                              : IDS_SELECT_FOLDER_DIALOG_TITLE;
-  scoped_refptr<RefCountedKDialogOutputParams> results =
-      base::MakeRefCounted<RefCountedKDialogOutputParams>();
-  pipe_task_runner_->PostTaskAndReply(
+  pipe_task_runner_->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(
-          &SelectFileDialogLinuxKde::CallKDialogOutput, base::AsWeakPtr(this),
+          &SelectFileDialogLinuxKde::CallKDialogOutput, this,
           KDialogParams(
               "--getexistingdirectory", GetTitle(title, title_message_id),
               default_path.empty() ? *last_opened_path() : default_path, parent,
-              false, false),
-          results),
+              false, false)),
       base::BindOnce(
-          &SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse,
-          base::AsWeakPtr(this), parent, params, results));
+          &SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse, this,
+          parent, params));
 }
 
 void SelectFileDialogLinuxKde::CreateFileOpenDialog(
@@ -502,20 +493,17 @@
     const base::FilePath& default_path,
     gfx::AcceleratedWidget parent,
     void* params) {
-  scoped_refptr<RefCountedKDialogOutputParams> results =
-      base::MakeRefCounted<RefCountedKDialogOutputParams>();
-  pipe_task_runner_->PostTaskAndReply(
+  pipe_task_runner_->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(
-          &SelectFileDialogLinuxKde::CallKDialogOutput, base::AsWeakPtr(this),
+          &SelectFileDialogLinuxKde::CallKDialogOutput, this,
           KDialogParams(
               "--getopenfilename", GetTitle(title, IDS_OPEN_FILE_DIALOG_TITLE),
               default_path.empty() ? *last_opened_path() : default_path, parent,
-              true, false),
-          results),
+              true, false)),
       base::BindOnce(
-          &SelectFileDialogLinuxKde::OnSelectSingleFileDialogResponse,
-          base::AsWeakPtr(this), parent, params, results));
+          &SelectFileDialogLinuxKde::OnSelectSingleFileDialogResponse, this,
+          parent, params));
 }
 
 void SelectFileDialogLinuxKde::CreateMultiFileOpenDialog(
@@ -523,19 +511,16 @@
     const base::FilePath& default_path,
     gfx::AcceleratedWidget parent,
     void* params) {
-  scoped_refptr<RefCountedKDialogOutputParams> results =
-      base::MakeRefCounted<RefCountedKDialogOutputParams>();
-  pipe_task_runner_->PostTaskAndReply(
+  pipe_task_runner_->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(
-          &SelectFileDialogLinuxKde::CallKDialogOutput, base::AsWeakPtr(this),
+          &SelectFileDialogLinuxKde::CallKDialogOutput, this,
           KDialogParams(
               "--getopenfilename", GetTitle(title, IDS_OPEN_FILES_DIALOG_TITLE),
               default_path.empty() ? *last_opened_path() : default_path, parent,
-              true, true),
-          results),
+              true, true)),
       base::BindOnce(&SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse,
-                     base::AsWeakPtr(this), parent, params, results));
+                     this, parent, params));
 }
 
 void SelectFileDialogLinuxKde::CreateSaveAsDialog(
@@ -543,33 +528,30 @@
     const base::FilePath& default_path,
     gfx::AcceleratedWidget parent,
     void* params) {
-  scoped_refptr<RefCountedKDialogOutputParams> results =
-      base::MakeRefCounted<RefCountedKDialogOutputParams>();
-  pipe_task_runner_->PostTaskAndReply(
+  pipe_task_runner_->PostTaskAndReplyWithResult(
       FROM_HERE,
       base::BindOnce(
-          &SelectFileDialogLinuxKde::CallKDialogOutput, base::AsWeakPtr(this),
+          &SelectFileDialogLinuxKde::CallKDialogOutput, this,
           KDialogParams(
               "--getsavefilename", GetTitle(title, IDS_SAVE_AS_DIALOG_TITLE),
               default_path.empty() ? *last_saved_path() : default_path, parent,
-              true, false),
-          results),
+              true, false)),
       base::BindOnce(
-          &SelectFileDialogLinuxKde::OnSelectSingleFileDialogResponse,
-          base::AsWeakPtr(this), parent, params, results));
+          &SelectFileDialogLinuxKde::OnSelectSingleFileDialogResponse, this,
+          parent, params));
 }
 
 void SelectFileDialogLinuxKde::SelectSingleFileHelper(
     void* params,
     bool allow_folder,
-    scoped_refptr<RefCountedKDialogOutputParams> results) {
-  VLOG(1) << "[kdialog] SingleFileResponse: " << results->data.output;
-  if (results->data.exit_code || results->data.output.empty()) {
+    std::unique_ptr<KDialogOutputParams> results) {
+  VLOG(1) << "[kdialog] SingleFileResponse: " << results->output;
+  if (results->exit_code || results->output.empty()) {
     FileNotSelected(params);
     return;
   }
 
-  base::FilePath path(results->data.output);
+  base::FilePath path(results->output);
   if (allow_folder) {
     FileSelected(path, params);
     return;
@@ -584,7 +566,7 @@
 void SelectFileDialogLinuxKde::OnSelectSingleFileDialogResponse(
     gfx::AcceleratedWidget parent,
     void* params,
-    scoped_refptr<RefCountedKDialogOutputParams> results) {
+    std::unique_ptr<KDialogOutputParams> results) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   parents_.erase(parent);
   SelectSingleFileHelper(params, false, std::move(results));
@@ -593,7 +575,7 @@
 void SelectFileDialogLinuxKde::OnSelectSingleFolderDialogResponse(
     gfx::AcceleratedWidget parent,
     void* params,
-    scoped_refptr<RefCountedKDialogOutputParams> results) {
+    std::unique_ptr<KDialogOutputParams> results) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
   parents_.erase(parent);
   SelectSingleFileHelper(params, true, std::move(results));
@@ -602,20 +584,20 @@
 void SelectFileDialogLinuxKde::OnSelectMultiFileDialogResponse(
     gfx::AcceleratedWidget parent,
     void* params,
-    scoped_refptr<RefCountedKDialogOutputParams> results) {
+    std::unique_ptr<KDialogOutputParams> results) {
   DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
-  VLOG(1) << "[kdialog] MultiFileResponse: " << results->data.output;
+  VLOG(1) << "[kdialog] MultiFileResponse: " << results->output;
 
   parents_.erase(parent);
 
-  if (results->data.exit_code || results->data.output.empty()) {
+  if (results->exit_code || results->output.empty()) {
     FileNotSelected(params);
     return;
   }
 
   std::vector<base::FilePath> filenames_fp;
   for (const base::StringPiece& line :
-       base::SplitStringPiece(results->data.output, "\n", base::KEEP_WHITESPACE,
+       base::SplitStringPiece(results->output, "\n", base::KEEP_WHITESPACE,
                               base::SPLIT_WANT_NONEMPTY)) {
     base::FilePath path(line);
     if (CallDirectoryExistsOnUIThread(path))
diff --git a/ui/shell_dialogs/select_file_dialog_linux_portal.cc b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
index d1c0e41..b7f6e65 100644
--- a/ui/shell_dialogs/select_file_dialog_linux_portal.cc
+++ b/ui/shell_dialogs/select_file_dialog_linux_portal.cc
@@ -7,7 +7,6 @@
 #include "base/containers/contains.h"
 #include "base/functional/bind.h"
 #include "base/logging.h"
-#include "base/memory/weak_ptr.h"
 #include "base/no_destructor.h"
 #include "base/notreached.h"
 #include "base/strings/string_piece.h"
@@ -202,13 +201,11 @@
     gfx::NativeWindow owning_window,
     void* params,
     const GURL* caller) {
-  CheckCalledOnValidSequence();
-
   auto info = base::MakeRefCounted<DialogInfo>(
       base::BindOnce(&SelectFileDialogLinuxPortal::CompleteOpenOnMainThread,
-                     base::AsWeakPtr(this)),
+                     this),
       base::BindOnce(&SelectFileDialogLinuxPortal::CancelOpenOnMainThread,
-                     base::AsWeakPtr(this)));
+                     this));
   info_ = info;
   info->type = type;
   info->main_task_runner = base::SequencedTaskRunnerHandle::Get();
@@ -236,8 +233,7 @@
             *parent_,
             base::BindOnce(
                 &SelectFileDialogLinuxPortal::SelectFileImplWithParentHandle,
-                base::AsWeakPtr(this), title, default_path, filter_set,
-                default_extension))) {
+                this, title, default_path, filter_set, default_extension))) {
       // Return early to skip the fallback below.
       return;
     } else {
@@ -433,7 +429,6 @@
     PortalFilterSet filter_set,
     base::FilePath::StringType default_extension,
     std::string parent_handle) {
-  CheckCalledOnValidSequence();
   bool default_path_exists = CallDirectoryExistsOnUIThread(default_path);
   dbus_thread_linux::GetTaskRunner()->PostTask(
       FROM_HERE,
@@ -657,7 +652,6 @@
 void SelectFileDialogLinuxPortal::CompleteOpenOnMainThread(
     std::vector<base::FilePath> paths,
     std::string current_filter) {
-  CheckCalledOnValidSequence();
   UnparentOnMainThread();
 
   if (listener_) {
diff --git a/ui/shell_dialogs/select_file_dialog_mac.h b/ui/shell_dialogs/select_file_dialog_mac.h
index 5047380..98dc5fce 100644
--- a/ui/shell_dialogs/select_file_dialog_mac.h
+++ b/ui/shell_dialogs/select_file_dialog_mac.h
@@ -39,8 +39,6 @@
   bool IsRunning(gfx::NativeWindow parent_window) const override;
   void ListenerDestroyed() override;
 
-  ~SelectFileDialogImpl() override;
-
  protected:
   // SelectFileDialog implementation.
   // |params| is user data we pass back via the Listener interface.
@@ -76,6 +74,8 @@
     mojo::Remote<remote_cocoa::mojom::SelectFileDialog> select_file_dialog;
   };
 
+  ~SelectFileDialogImpl() override;
+
   // Callback made when a panel is closed.
   void FileWasSelected(DialogData* dialog_data,
                        bool is_multi,
@@ -94,7 +94,6 @@
   // only.
   base::RepeatingClosure dialog_closed_callback_for_testing_;
 
-  // TODO(lucmult): Remove this weak_factory_.
   base::WeakPtrFactory<SelectFileDialogImpl> weak_factory_;
 };
 
diff --git a/ui/shell_dialogs/select_file_dialog_mac.mm b/ui/shell_dialogs/select_file_dialog_mac.mm
index ee81ded..3cd217d5 100644
--- a/ui/shell_dialogs/select_file_dialog_mac.mm
+++ b/ui/shell_dialogs/select_file_dialog_mac.mm
@@ -39,7 +39,6 @@
 }
 
 void SelectFileDialogImpl::ListenerDestroyed() {
-  CheckCalledOnValidSequence();
   listener_ = nullptr;
 }
 
diff --git a/ui/shell_dialogs/select_file_dialog_mac_unittest.mm b/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
index a0a41a7a..cbe810bc0 100644
--- a/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
+++ b/ui/shell_dialogs/select_file_dialog_mac_unittest.mm
@@ -2,7 +2,6 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-#include <memory>
 #include "base/memory/raw_ptr.h"
 
 #import "ui/shell_dialogs/select_file_dialog_mac.h"
@@ -137,14 +136,14 @@
   }
 
   void ResetDialog() {
-    dialog_ = std::make_unique<SelectFileDialogImpl>(this, nullptr);
+    dialog_ = new SelectFileDialogImpl(this, nullptr);
 
     // Spin the run loop to get any pending Mojo IPC sent.
     base::RunLoop().RunUntilIdle();
   }
 
  private:
-  std::unique_ptr<SelectFileDialogImpl> dialog_;
+  scoped_refptr<SelectFileDialogImpl> dialog_;
 
   std::vector<base::scoped_nsobject<NSWindow>> parent_windows_;
 };
diff --git a/ui/shell_dialogs/select_file_dialog_win.cc b/ui/shell_dialogs/select_file_dialog_win.cc
index 8071c243..5deb21f 100644
--- a/ui/shell_dialogs/select_file_dialog_win.cc
+++ b/ui/shell_dialogs/select_file_dialog_win.cc
@@ -12,7 +12,6 @@
 #include "base/files/file_path.h"
 #include "base/files/file_util.h"
 #include "base/i18n/case_conversion.h"
-#include "base/memory/weak_ptr.h"
 #include "base/notreached.h"
 #include "base/strings/string_util.h"
 #include "base/strings/utf_string_conversions.h"
@@ -246,7 +245,6 @@
     gfx::NativeWindow owning_window,
     void* params,
     const GURL* caller) {
-  CheckCalledOnValidSequence();
   has_multiple_file_type_choices_ =
       file_types ? file_types->extensions.size() > 1 : true;
 
@@ -266,8 +264,7 @@
                      filter, file_type_index, default_extension, owner,
                      base::ThreadTaskRunnerHandle::Get(),
                      base::BindOnce(&SelectFileDialogImpl::OnSelectFileExecuted,
-                                    base::AsWeakPtr(this), type,
-                                    std::move(run_state), params)));
+                                    this, type, std::move(run_state), params)));
 }
 
 bool SelectFileDialogImpl::HasMultipleFileTypeChoicesImpl() {
@@ -284,7 +281,6 @@
 void SelectFileDialogImpl::ListenerDestroyed() {
   // Our associated listener has gone away, so we shouldn't call back to it if
   // our worker thread returns after the listener is dead.
-  CheckCalledOnValidSequence();
   listener_ = nullptr;
 }
 
diff --git a/ui/shell_dialogs/select_file_dialog_win_unittest.cc b/ui/shell_dialogs/select_file_dialog_win_unittest.cc
index dd79a2fe..4527e1f 100644
--- a/ui/shell_dialogs/select_file_dialog_win_unittest.cc
+++ b/ui/shell_dialogs/select_file_dialog_win_unittest.cc
@@ -231,7 +231,7 @@
 
     const auto& test_case = kTestCases[i];
 
-    std::unique_ptr<ui::SelectFileDialog> dialog =
+    scoped_refptr<ui::SelectFileDialog> dialog =
         ui::SelectFileDialog::Create(this, nullptr);
 
     std::unique_ptr<ui::SelectFileDialog::FileTypeInfo> file_type_info;
@@ -269,7 +269,7 @@
   ASSERT_TRUE(scoped_temp_dir.CreateUniqueTempDir());
   base::FilePath default_path = scoped_temp_dir.GetPath();
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_UPLOAD_FOLDER,
                      std::u16string(), default_path, nullptr, 0, L"",
@@ -310,7 +310,7 @@
   std::string contents = "Hello test!";
   ASSERT_TRUE(base::WriteFile(default_path, contents));
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE, kTitle,
                      default_path, nullptr, 0, L"", native_window(), nullptr);
@@ -338,7 +338,7 @@
   std::string contents = "Hello test!";
   ASSERT_TRUE(base::WriteFile(default_path, contents));
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE, std::u16string(),
                      default_path, nullptr, 0, L"", native_window(), nullptr);
@@ -365,7 +365,7 @@
   ui::SelectFileDialog::FileTypeInfo file_type_info;
   file_type_info.extensions.push_back({L"html"});
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_SAVEAS_FILE, std::u16string(),
                      default_path, &file_type_info, 1, L"", native_window(),
@@ -389,7 +389,7 @@
   ui::SelectFileDialog::FileTypeInfo file_type_info;
   file_type_info.extensions.push_back({L"html"});
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_SAVEAS_FILE, std::u16string(),
                      default_path, &file_type_info, 1, L"", native_window(),
@@ -416,7 +416,7 @@
   ui::SelectFileDialog::FileTypeInfo file_type_info;
   file_type_info.extensions.push_back({L"exe"});
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_SAVEAS_FILE, std::u16string(),
                      default_path, &file_type_info, 1, L"html", native_window(),
@@ -443,7 +443,7 @@
   ui::SelectFileDialog::FileTypeInfo file_type_info;
   file_type_info.extensions.push_back({L"exe"});
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE, std::u16string(),
                      default_path, &file_type_info, 1, L"html", native_window(),
@@ -466,7 +466,7 @@
   base::FilePath default_path =
       scoped_temp_dir.GetPath().Append(L"does-not-exist.html");
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_OPEN_FILE, std::u16string(),
                      default_path, nullptr, 0, L"", native_window(), nullptr);
@@ -502,7 +502,7 @@
   ui::SelectFileDialog::FileTypeInfo file_type_info;
   file_type_info.extensions.push_back({L"txt"});
 
-  std::unique_ptr<ui::SelectFileDialog> dialog =
+  scoped_refptr<ui::SelectFileDialog> dialog =
       ui::SelectFileDialog::Create(this, nullptr);
   dialog->SelectFile(ui::SelectFileDialog::SELECT_SAVEAS_FILE, std::u16string(),
                      default_path, &file_type_info, 1, L"", native_window(),
diff --git a/weblayer/browser/file_select_helper.h b/weblayer/browser/file_select_helper.h
index 3c952ae2..37d3fef 100644
--- a/weblayer/browser/file_select_helper.h
+++ b/weblayer/browser/file_select_helper.h
@@ -90,7 +90,7 @@
   scoped_refptr<content::FileSelectListener> listener_;
 
   // Dialog box used for choosing files to upload from file form fields.
-  std::unique_ptr<ui::SelectFileDialog> select_file_dialog_;
+  scoped_refptr<ui::SelectFileDialog> select_file_dialog_;
 
   // The type of file dialog last shown.
   ui::SelectFileDialog::Type dialog_type_ =