Initialize COM in the Main of UtilWin process.

Previously, COM was initialized in the scope of methods running in
the UtilWin process. This is believed to be incorrect
(go/chrome-util-win-com-init-chat). COM should be initialized
"before you call any of the library functions [...]" [1] and
uninitialized "on application shutdown" [2] . Also, a COM STA thread
should "have a message loop" [3].

This CL introduces 2 features which:
- Request a UI pump for the UtilWin process, instead of a
  default pump.
- Initialize COM for the full lifetime of utility processes that
  use a UI pump.

It also introduces a UMA histogram to see if that reduces hangs in
the file select dialog.

[1] https://learn.microsoft.com/en-us/windows/win32/api/objbase/nf-objbase-coinitialize
[2] https://learn.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-couninitialize
[3].

Bug: 348014083
Change-Id: Id78568c1aace1834b057f5d21e9642ece6a36986
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5599006
Reviewed-by: Patrick Monette <[email protected]>
Reviewed-by: Avi Drissman <[email protected]>
Reviewed-by: Robert Kaplow <[email protected]>
Commit-Queue: Francois Pierre Doray <[email protected]>
Reviewed-by: Greg Thompson <[email protected]>
Auto-Submit: Francois Pierre Doray <[email protected]>
Cr-Commit-Position: refs/heads/main@{#1330478}
diff --git a/chrome/browser/win/util_win_service.cc b/chrome/browser/win/util_win_service.cc
index fb110d5..afa9702 100644
--- a/chrome/browser/win/util_win_service.cc
+++ b/chrome/browser/win/util_win_service.cc
@@ -4,16 +4,22 @@
 
 #include "chrome/browser/win/util_win_service.h"
 
+#include "chrome/common/chrome_features.h"
 #include "chrome/grit/generated_resources.h"
 #include "chrome/services/util_win/public/mojom/util_win.mojom.h"
 #include "content/public/browser/service_process_host.h"
+#include "content/public/common/content_switches.h"
 
 mojo::Remote<chrome::mojom::UtilWin> LaunchUtilWinServiceInstance() {
+  content::ServiceProcessHost::Options options;
+  options.WithDisplayName(IDS_UTILITY_PROCESS_UTILITY_WIN_NAME);
+  if (base::FeatureList::IsEnabled(features::kUtilWinProcessUsesUiPump)) {
+    options.WithExtraCommandLineSwitches({switches::kMessageLoopTypeUi});
+  }
+
   // Runs with kNoSandbox from sandbox.mojom.Sandbox.
   return content::ServiceProcessHost::Launch<chrome::mojom::UtilWin>(
-      content::ServiceProcessHost::Options()
-          .WithDisplayName(IDS_UTILITY_PROCESS_UTILITY_WIN_NAME)
-          .Pass());
+      options.Pass());
 }
 
 mojo::Remote<chrome::mojom::ProcessorMetrics> LaunchProcessorMetricsService() {