Add WebAuthn Tab

This is the first commit for the WebAuthn DevTools front-end feature.

This patch:
- registers the feature as an experiment
- creates the top toolbar with a (non-functioning) toggle
- makes the feature accessible through the DevTools panel

Design Doc: https://docs.google.com/document/d/1A-cn0rxuHHAyGhywayk7xcTqSsR2X7va6H4kSMThOoY
Bug: 1034663

Change-Id: I91daca8e54b0dc6c0e2fd1e71b34e0e932fd8734
Reviewed-on: https://chromium-review.googlesource.com/c/devtools/devtools-frontend/+/2231519
Reviewed-by: Tim van der Lippe <[email protected]>
Reviewed-by: Jan Scheffler <[email protected]>
Reviewed-by: Nina Satragno <[email protected]>
Commit-Queue: Tim van der Lippe <[email protected]>
Auto-Submit: Fawaz Mohammad <[email protected]>
diff --git a/BUILD.gn b/BUILD.gn
index 067e61f..b1d357b 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -367,6 +367,8 @@
   "front_end/web_audio/audioContextSelector.css",
   "front_end/web_audio/module.json",
   "front_end/web_audio/webAudio.css",
+  "front_end/webauthn/module.json",
+  "front_end/webauthn/webauthnPane.css",
   "front_end/worker_main/module.json",
   "front_end/worker_service/module.json",
   "front_end/workspace_diff/module.json",
@@ -570,6 +572,8 @@
   "wasmparser_worker/wasmparser_worker.js",
   "web_audio/web_audio.js",
   "web_audio/web_audio-legacy.js",
+  "webauthn/webauthn.js",
+  "webauthn/webauthn-legacy.js",
   "worker_main/worker_main.js",
   "worker_main/worker_main-legacy.js",
   "worker_service/worker_service.js",
@@ -839,6 +843,7 @@
   "$resources_out_dir/timeline_model/timeline_model_module.js",
   "$resources_out_dir/timeline/timeline_module.js",
   "$resources_out_dir/web_audio/web_audio_module.js",
+  "$resources_out_dir/webauthn/webauthn_module.js",
   "$resources_out_dir/workspace_diff/workspace_diff_module.js",
 ]
 
@@ -1607,6 +1612,7 @@
   "web_audio/graph_visualizer/NodeView.js",
   "web_audio/WebAudioModel.js",
   "web_audio/WebAudioView.js",
+  "webauthn/WebauthnPane.js",
   "worker_main/WorkerMain.js",
   "worker_service/ServiceDispatcher.js",
   "workspace_diff/WorkspaceDiff.js",
diff --git a/front_end/devtools_app.json b/front_end/devtools_app.json
index e6ede6f..d2d9513 100644
--- a/front_end/devtools_app.json
+++ b/front_end/devtools_app.json
@@ -26,6 +26,7 @@
     { "name": "timeline" },
     { "name": "timeline_model" },
     { "name": "web_audio" },
+    { "name": "webauthn"},
     { "name": "media" }
   ],
   "extends": "shell"
diff --git a/front_end/langpacks/devtools_ui_strings.grd b/front_end/langpacks/devtools_ui_strings.grd
index 8e49576..c225a4c 100644
--- a/front_end/langpacks/devtools_ui_strings.grd
+++ b/front_end/langpacks/devtools_ui_strings.grd
@@ -70,6 +70,7 @@
       <part file="../timeline_model/timeline_model_strings.grdp" />
       <part file="../ui/ui_strings.grdp" />
       <part file="../web_audio/web_audio_strings.grdp" />
+      <part file="../webauthn/webauthn_strings.grdp" />
       <part file="../workspace/workspace_strings.grdp" />
       <part file="shared_strings.grdp" />
     </messages>
diff --git a/front_end/main/MainImpl.js b/front_end/main/MainImpl.js
index d01501e..f4b50b3 100644
--- a/front_end/main/MainImpl.js
+++ b/front_end/main/MainImpl.js
@@ -162,6 +162,7 @@
         'Show option to take heap snapshot where globals are not treated as root');
     Root.Runtime.experiments.register('sourceDiff', 'Source diff');
     Root.Runtime.experiments.register('spotlight', 'Spotlight', true);
+    Root.Runtime.experiments.register('webauthnPane', 'WebAuthn Pane');
     Root.Runtime.experiments.register(
         'customKeyboardShortcuts', 'Enable custom keyboard shortcuts settings tab (requires reload)');
 
diff --git a/front_end/webauthn/WebauthnPane.js b/front_end/webauthn/WebauthnPane.js
new file mode 100644
index 0000000..ba46541
--- /dev/null
+++ b/front_end/webauthn/WebauthnPane.js
@@ -0,0 +1,26 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import * as Common from '../common/common.js';
+import * as UI from '../ui/ui.js';
+
+export class WebauthnPaneImpl extends UI.Widget.VBox {
+  constructor() {
+    super(true);
+    this.registerRequiredCSS('webauthn/webauthnPane.css');
+
+    const topToolbar = new UI.Toolbar.Toolbar('webauthn-toolbar', this.contentElement);
+    this._virtualAuthEnvEnabledSetting =
+        Common.Settings.Settings.instance().createSetting('virtualAuthEnvEnabled', false);
+    this._virtualAuthEnvEnabledSetting.addChangeListener(() => this._toggleVirtualAuthEnv());
+    const enableCheckbox = new UI.Toolbar.ToolbarSettingCheckbox(
+        this._virtualAuthEnvEnabledSetting, Common.UIString.UIString('Enable Virtual Authenticator Environment'),
+        Common.UIString.UIString('Enable Virtual Authenticator Environment'));
+    topToolbar.appendToolbarItem(enableCheckbox);
+  }
+
+  _toggleVirtualAuthEnv() {
+    // TODO(crbug.com/1034663): toggle the virtual authenticator environment
+  }
+}
diff --git a/front_end/webauthn/module.json b/front_end/webauthn/module.json
new file mode 100644
index 0000000..2fcd3e6
--- /dev/null
+++ b/front_end/webauthn/module.json
@@ -0,0 +1,29 @@
+{
+  "extensions": [
+    {
+      "type": "view",
+      "location": "drawer-view",
+      "id": "webauthn-pane",
+      "title": "WebAuthn",
+      "order": 100,
+      "persistence": "closeable",
+      "className": "Webauthn.WebauthnPane",
+      "experiment": "webauthnPane"
+    }
+  ],
+  "dependencies": [
+    "common",
+    "platform",
+    "ui",
+    "host"
+  ],
+  "scripts": [],
+  "modules": [
+    "webauthn.js",
+    "WebauthnPane.js",
+    "webauthn-legacy.js"
+  ],
+  "resources": [
+    "webauthnPane.css"
+  ]
+}
diff --git a/front_end/webauthn/webauthn-legacy.js b/front_end/webauthn/webauthn-legacy.js
new file mode 100644
index 0000000..193773e
--- /dev/null
+++ b/front_end/webauthn/webauthn-legacy.js
@@ -0,0 +1,13 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import * as WebauthnModule from './webauthn.js';
+
+self.Webauthn = self.Webauthn || {};
+Webauthn = Webauthn || {};
+
+/**
+ * @constructor
+ */
+Webauthn.WebauthnPane = WebauthnModule.WebauthnPane.WebauthnPaneImpl;
diff --git a/front_end/webauthn/webauthn.js b/front_end/webauthn/webauthn.js
new file mode 100644
index 0000000..2ef8352
--- /dev/null
+++ b/front_end/webauthn/webauthn.js
@@ -0,0 +1,7 @@
+// Copyright 2020 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import * as WebauthnPane from './WebauthnPane.js';
+
+export {WebauthnPane};
diff --git a/front_end/webauthn/webauthnPane.css b/front_end/webauthn/webauthnPane.css
new file mode 100644
index 0000000..9260091
--- /dev/null
+++ b/front_end/webauthn/webauthnPane.css
@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) 2020 The Chromium Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+.webauthn-toolbar {
+    border-bottom: var(--divider-border);
+}
diff --git a/front_end/webauthn/webauthn_strings.grdp b/front_end/webauthn/webauthn_strings.grdp
new file mode 100644
index 0000000..fb53644
--- /dev/null
+++ b/front_end/webauthn/webauthn_strings.grdp
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="utf-8"?>
+<grit-part>
+  <message name="IDS_DEVTOOLS_0f9d05f79599511a36679baf1c599552" desc="Label for checkbox that enables virtual authenticator environment">
+    Enable Virtual Authenticator Environment
+  </message>
+  <message name="IDS_DEVTOOLS_7981a42fd27d757338f9a99563a24ac8" desc="Title of WebAuthn tool in bottom drawer">
+    WebAuthn
+  </message>
+</grit-part>
\ No newline at end of file