Files app: Add JS module for Metadata SharedWorker

Change the API to override the ContentMetadataProvider worker URL and
update Audio Player, Gallery and Files app.

Bug: 1133186
Change-Id: Ie8024f53bd11d8faebb3cd0020af35042dbccbd7
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2639058
Reviewed-by: Jeremie Boulic <jboulic@chromium.org>
Commit-Queue: Luciano Pacheco <lucmult@chromium.org>
Auto-Submit: Luciano Pacheco <lucmult@chromium.org>
Cr-Commit-Position: refs/heads/master@{#845084}
diff --git a/ui/file_manager/BUILD.gn b/ui/file_manager/BUILD.gn
index 9caade6..e886502 100644
--- a/ui/file_manager/BUILD.gn
+++ b/ui/file_manager/BUILD.gn
@@ -409,6 +409,7 @@
     "file_manager/foreground/js/deferred_elements.m.rollup.js",
     "file_manager/foreground/js/main.m.rollup.js",
     "file_manager/foreground/js/shared.m.rollup.js",
+    "file_manager/foreground/js/metadata_dispatcher.m.rollup.js",
 
     "video_player/js/main.m.rollup.js",
     "video_player/js/main_background.m.rollup.js",
@@ -422,6 +423,7 @@
     "file_manager/background/js/main_background.m.rollup.js|file_manager/background/js/main_background.m.js",
     "file_manager/foreground/js/deferred_elements.m.rollup.js|file_manager/foreground/js/deferred_elements.m.js",
     "file_manager/foreground/js/main.m.rollup.js|file_manager/foreground/js/main.m.js",
+    "file_manager/foreground/js/metadata_dispatcher.m.rollup.js|file_manager/foreground/js/metadata_dispatcher.m.js",
     "video_player/js/main.m.rollup.js|video_player/js/main.m.js",
     "video_player/js/main_background.m.rollup.js|video_player/js/main_background.m.js",
   ]
@@ -440,6 +442,7 @@
     "//ui/file_manager/file_manager/background/js:build",
     "//ui/file_manager/file_manager/foreground/elements:elements",
     "//ui/file_manager/file_manager/foreground/js:build",
+    "//ui/file_manager/file_manager/foreground/js:build_worker",
     "//ui/file_manager/image_loader:build",
     "//ui/file_manager/video_player/js:build",
     "//ui/file_manager/video_player/js:build_background",
diff --git a/ui/file_manager/audio_player/js/audio_player.js b/ui/file_manager/audio_player/js/audio_player.js
index f3ef8315..5518231 100644
--- a/ui/file_manager/audio_player/js/audio_player.js
+++ b/ui/file_manager/audio_player/js/audio_player.js
@@ -142,15 +142,11 @@
       this.player_.ariaExpandArtworkLabel =
           strings['AUDIO_PLAYER_ARTWORK_EXPAND_BUTTON_LABEL'];
 
-      /**
-       * Overrided metadata worker's path.
-       * @type {string}
-       */
-      ContentMetadataProvider.WORKER_SCRIPT =
+      // Override metadata worker's path.
+      ContentMetadataProvider.configure(
           util.isAudioPlayerJsModulesEnabled() ? '/js/metadata_worker.m.js' :
-                                                 '/js/metadata_worker.js';
-      ContentMetadataProvider.loadAsModule =
-          util.isAudioPlayerJsModulesEnabled();
+                                                 '/js/metadata_worker.js',
+          /*isModule=*/ util.isAudioPlayerJsModulesEnabled());
 
       this.metadataModel_ = MetadataModel.create(this.volumeManager_);
       this.resolveMetadataModel_();
diff --git a/ui/file_manager/file_manager/foreground/js/BUILD.gn b/ui/file_manager/file_manager/foreground/js/BUILD.gn
index 98a59bc..7496ff2 100644
--- a/ui/file_manager/file_manager/foreground/js/BUILD.gn
+++ b/ui/file_manager/file_manager/foreground/js/BUILD.gn
@@ -858,6 +858,7 @@
     ":spinner_controller.m",
     ":task_controller.m",
     ":toolbar_controller.m",
+    "metadata:content_metadata_provider.m",
     "metadata:metadata_model.m",
     "metadata:thumbnail_model.m",
     "ui:a11y_announce.m",
@@ -2172,3 +2173,19 @@
     "//ui/webui/resources:preprocess",
   ]
 }
+
+optimize_webui("build_worker") {
+  host = "file_manager"
+
+  input = preprocess_folder
+  js_module_in_files = [ "metadata/metadata_dispatcher.m.js" ]
+
+  js_out_files = [ "metadata_dispatcher.m.rollup.js" ]
+
+  deps = [
+    "metadata:metadata_dispatcher.m",
+    "//ui/file_manager:preprocess_generated",
+    "//ui/file_manager:preprocess_static",
+    "//ui/webui/resources:preprocess",
+  ]
+}
diff --git a/ui/file_manager/file_manager/foreground/js/file_manager.js b/ui/file_manager/file_manager/foreground/js/file_manager.js
index abb29b07..a2f62b0 100644
--- a/ui/file_manager/file_manager/foreground/js/file_manager.js
+++ b/ui/file_manager/file_manager/foreground/js/file_manager.js
@@ -49,6 +49,7 @@
 // #import {ProvidersModel} from './providers_model.m.js';
 // #import {ThumbnailModel} from './metadata/thumbnail_model.m.js';
 // #import {MetadataModel} from './metadata/metadata_model.m.js';
+// #import {ContentMetadataProvider} from './metadata/content_metadata_provider.m.js';
 // #import {FilteredVolumeManager} from '../../../base/js/filtered_volume_manager.m.js';
 // #import {LaunchParam} from './launch_param.m.js';
 // #import {contextMenuHandler} from 'chrome://resources/js/cr/ui/context_menu_handler.m.js';
@@ -1011,6 +1012,14 @@
       DialogType.FULL_PAGE,
     ]);
 
+    if (util.isFilesJsModulesEnabled()) {
+      ContentMetadataProvider.configure(
+          'foreground/js/metadata_dispatcher.m.js', /*isModule=*/ true);
+    } else if (window.isSWA) {
+      ContentMetadataProvider.configure(
+          'foreground/js/metadata/metadata_dispatcher.js');
+    }
+
     // Create the metadata cache.
     assert(this.volumeManager_);
     this.metadataModel_ = MetadataModel.create(this.volumeManager_);
diff --git a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
index cd607dfa..ca36e86 100644
--- a/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
+++ b/ui/file_manager/file_manager/foreground/js/metadata/content_metadata_provider.js
@@ -66,19 +66,35 @@
       return opt_messagePort;
     }
 
-    let script = ContentMetadataProvider.WORKER_SCRIPT;
-    if (window.isSWA) {
-      script = 'foreground/js/metadata/metadata_dispatcher.js';
-    }
+    const script = ContentMetadataProvider.getWorkerScript();
 
     /** @type {!WorkerOptions} */
     const options =
-        ContentMetadataProvider.loadAsModule ? {type: 'module'} : {};
+        ContentMetadataProvider.loadAsModule_ ? {type: 'module'} : {};
 
     return new SharedWorker(script, options).port;
   }
 
   /**
+   * Configures how the worker should be loaded.
+   *
+   * @param {string} scriptURL URL used to load the worker.
+   * @param {boolean=} isModule Indicate if the worker should be loaded as
+   *   module.
+   */
+  static configure(scriptURL, isModule) {
+    ContentMetadataProvider.workerScript_ = scriptURL;
+    ContentMetadataProvider.loadAsModule_ = !!isModule;
+  }
+
+  /** @public @return {string} */
+  static getWorkerScript() {
+    return ContentMetadataProvider.workerScript_ ?
+        ContentMetadataProvider.workerScript_ :
+        ContentMetadataProvider.DEFAULT_WORKER_SCRIPT_;
+  }
+
+  /**
    * Converts content metadata from parsers to the internal format.
    * @param {Object} metadata The content metadata.
    * @return {!MetadataItem} Converted metadata.
@@ -487,14 +503,20 @@
 
 /**
  * The metadata Worker script URL.
- * @public @const {string}
+ * @const @private {string}
  */
-ContentMetadataProvider.WORKER_SCRIPT =
+ContentMetadataProvider.DEFAULT_WORKER_SCRIPT_ =
     'chrome-extension://hhaomjibdihmijegdhdafkllkbggdgoj/' +
     'foreground/js/metadata/metadata_dispatcher.js';
 
 /**
- * Sets if the SharedWorker should start as a JS Module.
- * @public {boolean}
+ * Worker script URL that is overwritten by client code.
+ * @private {?string}
  */
-ContentMetadataProvider.loadAsModule = false;
+ContentMetadataProvider.workerScript_ = null;
+
+/**
+ * Sets if the SharedWorker should start as a JS Module.
+ * @private {boolean}
+ */
+ContentMetadataProvider.loadAsModule_ = false;
diff --git a/ui/file_manager/gallery/js/gallery.js b/ui/file_manager/gallery/js/gallery.js
index a52a5813..a0369f7 100644
--- a/ui/file_manager/gallery/js/gallery.js
+++ b/ui/file_manager/gallery/js/gallery.js
@@ -2,11 +2,8 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 
-/**
- * Overrided metadata worker's path.
- * @type {string}
- */
-ContentMetadataProvider.WORKER_SCRIPT = '/js/metadata_worker.js';
+// Override metadata worker's path.
+ContentMetadataProvider.configure('/js/metadata_worker.js');
 
 /**
  * Gallery for viewing and editing image files.