Create a protocol + handler for Background Service recording.

- Create protocol for starting/stopping/querying recording mode
- Add handler which talks to the DevTools context
- Add a SDK model that the view communicates with
- flat_map -> array to avoid multi-thread access issues

Bug: 927726
Change-Id: I11e55a747c7c5c60465508485d6b869b976d40dd
Reviewed-on: https://chromium-review.googlesource.com/c/1477851
Reviewed-by: Dmitry Gozman <[email protected]>
Commit-Queue: Rayan Kanso <[email protected]>
Cr-Original-Commit-Position: refs/heads/master@{#637287}
Cr-Mirrored-From: https://chromium.googlesource.com/chromium/src
Cr-Mirrored-Commit: 31ad82ae99ed2a328d95fa6f73360a7c13561436
diff --git a/front_end/resources/BackgroundServiceView.js b/front_end/resources/BackgroundServiceView.js
index 62c2db9..11b47d8 100644
--- a/front_end/resources/BackgroundServiceView.js
+++ b/front_end/resources/BackgroundServiceView.js
@@ -4,15 +4,25 @@
 
 Resources.BackgroundServiceView = class extends UI.VBox {
   /**
-   * @param {string} serviceName
+   * @param {!Protocol.BackgroundService.ServiceName} serviceName
+   * @param {!Resources.BackgroundServiceModel} model
    */
-  constructor(serviceName) {
+  constructor(serviceName, model) {
     super(true);
     this.registerRequiredCSS('resources/backgroundServiceView.css');
 
-    /** @const {string} */
+    /** @const {!Protocol.BackgroundService.ServiceName} */
     this._serviceName = serviceName;
 
+    /** @const {!Resources.BackgroundServiceModel} */
+    this._model = model;
+    this._model.addEventListener(
+        Resources.BackgroundServiceModel.Events.RecordingStateChanged, this._onRecordingStateChanged, this);
+    this._model.enable(this._serviceName);
+
+    /** @type {?UI.ToolbarToggle} */
+    this._recordButton = null;
+
     /** @const {!UI.Toolbar} */
     this._toolbar = new UI.Toolbar('background-service-toolbar', this.contentElement);
     this._setupToolbar();
@@ -21,13 +31,12 @@
   /**
    * Creates the toolbar UI element.
    */
-  _setupToolbar() {
-    const recordButton =
+  async _setupToolbar() {
+    this._recordButton =
         new UI.ToolbarToggle(Common.UIString('Toggle Record'), 'largeicon-start-recording', 'largeicon-stop-recording');
-    recordButton.addEventListener(
-        UI.ToolbarButton.Events.Click, () => recordButton.setToggled(!recordButton.toggled()));
-    recordButton.setToggleWithRedColor(true);
-    this._toolbar.appendToolbarItem(recordButton);
+    this._recordButton.addEventListener(UI.ToolbarButton.Events.Click, () => this._toggleRecording());
+    this._recordButton.setToggleWithRedColor(true);
+    this._toolbar.appendToolbarItem(this._recordButton);
 
     const refreshButton = new UI.ToolbarButton(Common.UIString('Refresh'), 'largeicon-refresh');
     refreshButton.addEventListener(UI.ToolbarButton.Events.Click, () => {});
@@ -43,4 +52,21 @@
     deleteButton.addEventListener(UI.ToolbarButton.Events.Click, () => {});
     this._toolbar.appendToolbarItem(deleteButton);
   }
+
+  /**
+   * Called when the `Toggle Record` button is clicked.
+   */
+  _toggleRecording() {
+    this._model.setRecording(!this._recordButton.toggled(), this._serviceName);
+  }
+
+  /**
+   * @param {!Common.Event} event
+   */
+  _onRecordingStateChanged(event) {
+    const state = /** @type {!Resources.BackgroundServiceModel.RecordingState} */ (event.data);
+    if (state.serviceName !== this._serviceName)
+      return;
+    this._recordButton.setToggled(state.isRecording);
+  }
 };