[Extensions] Introduce LoadMonitoringExtensionHostQueue.

This is an ExtensionHostQueue implementation which gathers metrics about
ExtensionHost load timing and behavior. It delegates its queuing logic to the
existing SerialExtensionHostQueue.

BUG=453073
[email protected]

Review URL: https://codereview.chromium.org/954813002

Cr-Commit-Position: refs/heads/master@{#318473}
diff --git a/extensions/browser/extension_host.cc b/extensions/browser/extension_host.cc
index 3d18bf9..973c1a49 100644
--- a/extensions/browser/extension_host.cc
+++ b/extensions/browser/extension_host.cc
@@ -27,6 +27,7 @@
 #include "extensions/browser/extension_host_queue.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extensions_browser_client.h"
+#include "extensions/browser/load_monitoring_extension_host_queue.h"
 #include "extensions/browser/notification_types.h"
 #include "extensions/browser/process_manager.h"
 #include "extensions/browser/runtime_data.h"
@@ -97,6 +98,9 @@
       content::Details<ExtensionHost>(this));
   FOR_EACH_OBSERVER(ExtensionHostObserver, observer_list_,
                     OnExtensionHostDestroyed(this));
+  FOR_EACH_OBSERVER(DeferredStartRenderHostObserver,
+                    deferred_start_render_host_observer_list_,
+                    OnDeferredStartRenderHostDestroyed(this));
   delegate_->GetExtensionHostQueue()->Remove(this);
   // Immediately stop observing |host_contents_| because its destruction events
   // (like DidStopLoading, it turns out) can call back into ExtensionHost
@@ -148,6 +152,16 @@
   }
 }
 
+void ExtensionHost::AddDeferredStartRenderHostObserver(
+    DeferredStartRenderHostObserver* observer) {
+  deferred_start_render_host_observer_list_.AddObserver(observer);
+}
+
+void ExtensionHost::RemoveDeferredStartRenderHostObserver(
+    DeferredStartRenderHostObserver* observer) {
+  deferred_start_render_host_observer_list_.RemoveObserver(observer);
+}
+
 void ExtensionHost::Close() {
   content::NotificationService::current()->Notify(
       extensions::NOTIFICATION_EXTENSION_HOST_VIEW_SHOULD_CLOSE,
@@ -242,6 +256,12 @@
       content::Details<ExtensionHost>(this));
 }
 
+void ExtensionHost::DidStartLoading(content::RenderViewHost* render_view_host) {
+  FOR_EACH_OBSERVER(DeferredStartRenderHostObserver,
+                    deferred_start_render_host_observer_list_,
+                    OnDeferredStartRenderHostDidStartLoading(this));
+}
+
 void ExtensionHost::DidStopLoading(content::RenderViewHost* render_view_host) {
   bool notify = !did_stop_loading_;
   did_stop_loading_ = true;
@@ -260,12 +280,13 @@
       UMA_HISTOGRAM_MEDIUM_TIMES("Extensions.PopupLoadTime2",
                                  load_start_->Elapsed());
     }
-    // Send the notification last, because it might result in this being
-    // deleted.
     content::NotificationService::current()->Notify(
         extensions::NOTIFICATION_EXTENSION_HOST_DID_STOP_LOADING,
         content::Source<BrowserContext>(browser_context_),
         content::Details<ExtensionHost>(this));
+    FOR_EACH_OBSERVER(DeferredStartRenderHostObserver,
+                      deferred_start_render_host_observer_list_,
+                      OnDeferredStartRenderHostDidStopLoading(this));
   }
 }