[Extensions] Initial refactoring to combine task queue interfaces.

This CL unifies LazyContextTaskQueue::PendingTask and LazyBackgroundTaskQueue:PendingTask.

Change-Id: I4dac0f4494a575783781b9961345ddd48920d822
Reviewed-on: https://chromium-review.googlesource.com/c/1345531
Reviewed-by: Istiaque Ahmed <[email protected]>
Reviewed-by: Ben Wells <[email protected]>
Reviewed-by: Stuart Langley <[email protected]>
Commit-Queue: David Bertoni <[email protected]>
Cr-Commit-Position: refs/heads/master@{#617141}
diff --git a/extensions/browser/BUILD.gn b/extensions/browser/BUILD.gn
index 456bf91..d776a49 100644
--- a/extensions/browser/BUILD.gn
+++ b/extensions/browser/BUILD.gn
@@ -273,6 +273,7 @@
     "lazy_background_task_queue_factory.h",
     "lazy_context_id.cc",
     "lazy_context_id.h",
+    "lazy_context_task_queue.cc",
     "lazy_context_task_queue.h",
     "load_monitoring_extension_host_queue.cc",
     "load_monitoring_extension_host_queue.h",
diff --git a/extensions/browser/api/messaging/message_service.cc b/extensions/browser/api/messaging/message_service.cc
index 7d69dd6..95e8cc9 100644
--- a/extensions/browser/api/messaging/message_service.cc
+++ b/extensions/browser/api/messaging/message_service.cc
@@ -32,7 +32,6 @@
 #include "extensions/browser/api/messaging/messaging_delegate.h"
 #include "extensions/browser/event_router.h"
 #include "extensions/browser/extension_api_frame_id_map.h"
-#include "extensions/browser/extension_host.h"
 #include "extensions/browser/extension_registry.h"
 #include "extensions/browser/extension_system.h"
 #include "extensions/browser/extension_util.h"
@@ -943,17 +942,20 @@
 void MessageService::PendingLazyBackgroundPageOpenChannel(
     std::unique_ptr<OpenChannelParams> params,
     int source_process_id,
-    ExtensionHost* host) {
+    std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
   DCHECK_CURRENTLY_ON(BrowserThread::UI);
 
-  if (!host)
+  if (context_info == nullptr)
     return;  // TODO(mpcomplete): notify source of disconnect?
 
-  params->receiver.reset(
-      new ExtensionMessagePort(
-          weak_factory_.GetWeakPtr(), params->receiver_port_id,
-          params->target_extension_id, host->render_process_host()));
-  OpenChannelImpl(host->browser_context(), std::move(params), host->extension(),
+  params->receiver.reset(new ExtensionMessagePort(
+      weak_factory_.GetWeakPtr(), params->receiver_port_id,
+      params->target_extension_id, context_info->render_process_host));
+  const Extension* const extension =
+      extensions::ExtensionRegistry::Get(context_info->browser_context)
+          ->enabled_extensions()
+          .GetByID(context_info->extension_id);
+  OpenChannelImpl(context_info->browser_context, std::move(params), extension,
                   true /* did_enqueue */);
 }
 
diff --git a/extensions/browser/api/messaging/message_service.h b/extensions/browser/api/messaging/message_service.h
index d3d9d25..104b6954 100644
--- a/extensions/browser/api/messaging/message_service.h
+++ b/extensions/browser/api/messaging/message_service.h
@@ -18,6 +18,7 @@
 #include "extensions/browser/api/messaging/message_property_provider.h"
 #include "extensions/browser/api/messaging/native_message_host.h"
 #include "extensions/browser/browser_context_keyed_api_factory.h"
+#include "extensions/browser/lazy_context_task_queue.h"
 #include "extensions/common/api/messaging/message.h"
 #include "extensions/common/api/messaging/port_id.h"
 #include "extensions/common/extension_id.h"
@@ -201,21 +202,23 @@
   void PendingLazyBackgroundPageOpenChannel(
       std::unique_ptr<OpenChannelParams> params,
       int source_process_id,
-      extensions::ExtensionHost* host);
-  void PendingLazyBackgroundPageClosePort(const PortId& port_id,
-                                          int process_id,
-                                          int routing_id,
-                                          bool force_close,
-                                          const std::string& error_message,
-                                          extensions::ExtensionHost* host) {
-    if (host)
+      std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info);
+  void PendingLazyBackgroundPageClosePort(
+      const PortId& port_id,
+      int process_id,
+      int routing_id,
+      bool force_close,
+      const std::string& error_message,
+      std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
+    if (context_info)
       ClosePortImpl(port_id, process_id, routing_id, force_close,
                     error_message);
   }
-  void PendingLazyBackgroundPagePostMessage(const PortId& port_id,
-                                            const Message& message,
-                                            extensions::ExtensionHost* host) {
-    if (host)
+  void PendingLazyBackgroundPagePostMessage(
+      const PortId& port_id,
+      const Message& message,
+      std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
+    if (context_info)
       PostMessage(port_id, message);
   }
 
diff --git a/extensions/browser/api/runtime/runtime_api.cc b/extensions/browser/api/runtime/runtime_api.cc
index 9c0b235a..7416632 100644
--- a/extensions/browser/api/runtime/runtime_api.cc
+++ b/extensions/browser/api/runtime/runtime_api.cc
@@ -98,13 +98,14 @@
 // API without a kiosk app.
 bool allow_non_kiosk_apps_restart_api_for_test = false;
 
-void DispatchOnStartupEventImpl(BrowserContext* browser_context,
-                                const std::string& extension_id,
-                                bool first_call,
-                                ExtensionHost* host) {
-  // A NULL host from the LazyBackgroundTaskQueue means the page failed to
-  // load. Give up.
-  if (!host && !first_call)
+void DispatchOnStartupEventImpl(
+    BrowserContext* browser_context,
+    const std::string& extension_id,
+    bool first_call,
+    std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
+  // A NULL ContextInfo from the LazyBackgroundTaskQueue means the page failed
+  // to load. Give up.
+  if (!context_info && !first_call)
     return;
 
   // Don't send onStartup events to incognito browser contexts.
@@ -427,7 +428,7 @@
 void RuntimeEventRouter::DispatchOnStartupEvent(
     content::BrowserContext* context,
     const std::string& extension_id) {
-  DispatchOnStartupEventImpl(context, extension_id, true, NULL);
+  DispatchOnStartupEventImpl(context, extension_id, true, nullptr);
 }
 
 // static
@@ -602,7 +603,7 @@
             base::BindOnce(&RuntimeGetBackgroundPageFunction::OnPageLoaded,
                            this));
   } else if (host) {
-    OnPageLoaded(host);
+    OnPageLoaded(std::make_unique<LazyContextTaskQueue::ContextInfo>(host));
   } else {
     return RespondNow(Error(kNoBackgroundPageError));
   }
@@ -610,8 +611,9 @@
   return RespondLater();
 }
 
-void RuntimeGetBackgroundPageFunction::OnPageLoaded(ExtensionHost* host) {
-  if (host) {
+void RuntimeGetBackgroundPageFunction::OnPageLoaded(
+    std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
+  if (context_info) {
     Respond(NoArguments());
   } else {
     Respond(Error(kPageLoadError));
diff --git a/extensions/browser/api/runtime/runtime_api.h b/extensions/browser/api/runtime/runtime_api.h
index 4246125..8e927a8 100644
--- a/extensions/browser/api/runtime/runtime_api.h
+++ b/extensions/browser/api/runtime/runtime_api.h
@@ -5,6 +5,7 @@
 #ifndef EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
 #define EXTENSIONS_BROWSER_API_RUNTIME_RUNTIME_API_H_
 
+#include <memory>
 #include <string>
 
 #include "base/macros.h"
@@ -16,6 +17,7 @@
 #include "extensions/browser/events/lazy_event_dispatch_util.h"
 #include "extensions/browser/extension_function.h"
 #include "extensions/browser/extension_registry_observer.h"
+#include "extensions/browser/lazy_context_task_queue.h"
 #include "extensions/browser/process_manager.h"
 #include "extensions/browser/process_manager_observer.h"
 #include "extensions/browser/update_observer.h"
@@ -40,7 +42,6 @@
 }
 
 class Extension;
-class ExtensionHost;
 class ExtensionRegistry;
 
 // Runtime API dispatches onStartup, onInstalled, and similar events to
@@ -226,7 +227,8 @@
   ResponseAction Run() override;
 
  private:
-  void OnPageLoaded(ExtensionHost*);
+  void OnPageLoaded(
+      std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info);
 };
 
 class RuntimeOpenOptionsPageFunction : public UIThreadExtensionFunction {
diff --git a/extensions/browser/guest_view/app_view/app_view_guest.cc b/extensions/browser/guest_view/app_view/app_view_guest.cc
index 6114ded5..13f0910 100644
--- a/extensions/browser/guest_view/app_view/app_view_guest.cc
+++ b/extensions/browser/guest_view/app_view/app_view_guest.cc
@@ -208,7 +208,9 @@
   ExtensionHost* host =
       process_manager->GetBackgroundHostForExtension(guest_extension->id());
   DCHECK(host);
-  LaunchAppAndFireEvent(data->CreateDeepCopy(), std::move(callback), host);
+  LaunchAppAndFireEvent(
+      data->CreateDeepCopy(), std::move(callback),
+      std::make_unique<LazyContextTaskQueue::ContextInfo>(host));
 }
 
 void AppViewGuest::DidInitialize(const base::DictionaryValue& create_params) {
@@ -253,10 +255,10 @@
 void AppViewGuest::LaunchAppAndFireEvent(
     std::unique_ptr<base::DictionaryValue> data,
     WebContentsCreatedCallback callback,
-    ExtensionHost* extension_host) {
+    std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
   bool has_event_listener = EventRouter::Get(browser_context())
                                 ->ExtensionHasEventListener(
-                                    extension_host->extension()->id(),
+                                    context_info->extension_id,
                                     app_runtime::OnEmbedRequested::kEventName);
   if (!has_event_listener) {
     std::move(callback).Run(nullptr);
@@ -268,8 +270,12 @@
   embed_request->SetInteger(appview::kGuestInstanceID, guest_instance_id());
   embed_request->SetString(appview::kEmbedderID, owner_host());
   embed_request->Set(appview::kData, std::move(data));
+  const Extension* const extension =
+      extensions::ExtensionRegistry::Get(context_info->browser_context)
+          ->enabled_extensions()
+          .GetByID(context_info->extension_id);
   AppRuntimeEventRouter::DispatchOnEmbedRequestedEvent(
-      browser_context(), std::move(embed_request), extension_host->extension());
+      browser_context(), std::move(embed_request), extension);
 }
 
 void AppViewGuest::SetAppDelegateForTest(AppDelegate* delegate) {
diff --git a/extensions/browser/guest_view/app_view/app_view_guest.h b/extensions/browser/guest_view/app_view/app_view_guest.h
index 6131834..1603f25 100644
--- a/extensions/browser/guest_view/app_view/app_view_guest.h
+++ b/extensions/browser/guest_view/app_view/app_view_guest.h
@@ -5,14 +5,16 @@
 #ifndef EXTENSIONS_BROWSER_GUEST_VIEW_APP_VIEW_APP_VIEW_GUEST_H_
 #define EXTENSIONS_BROWSER_GUEST_VIEW_APP_VIEW_APP_VIEW_GUEST_H_
 
+#include <memory>
+
 #include "base/containers/id_map.h"
 #include "base/macros.h"
 #include "components/guest_view/browser/guest_view.h"
 #include "extensions/browser/guest_view/app_view/app_view_guest_delegate.h"
+#include "extensions/browser/lazy_context_task_queue.h"
 
 namespace extensions {
 class Extension;
-class ExtensionHost;
 
 // An AppViewGuest provides the browser-side implementation of <appview> API.
 // AppViewGuest is created on attachment. That is, when a guest WebContents is
@@ -71,9 +73,10 @@
                                  const Extension* guest_extension,
                                  WebContentsCreatedCallback callback);
 
-  void LaunchAppAndFireEvent(std::unique_ptr<base::DictionaryValue> data,
-                             WebContentsCreatedCallback callback,
-                             ExtensionHost* extension_host);
+  void LaunchAppAndFireEvent(
+      std::unique_ptr<base::DictionaryValue> data,
+      WebContentsCreatedCallback callback,
+      std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info);
 
   GURL url_;
   std::string guest_extension_id_;
diff --git a/extensions/browser/lazy_background_task_queue.cc b/extensions/browser/lazy_background_task_queue.cc
index c578821..bfc6afc 100644
--- a/extensions/browser/lazy_background_task_queue.cc
+++ b/extensions/browser/lazy_background_task_queue.cc
@@ -28,21 +28,6 @@
 
 namespace {
 
-// Adapts a LazyBackgroundTaskQueue pending task callback to
-// LazyContextTaskQueue's callback.
-void PendingTaskAdapter(LazyContextTaskQueue::PendingTask original_task,
-                        ExtensionHost* host) {
-  if (!host) {
-    std::move(original_task).Run(nullptr);
-  } else {
-    std::move(original_task)
-        .Run(std::make_unique<LazyContextTaskQueue::ContextInfo>(
-            host->extension()->id(), host->render_process_host(),
-            blink::mojom::kInvalidServiceWorkerVersionId, kMainThreadId,
-            host->GetURL()));
-  }
-}
-
 // Attempts to create a background host for a lazy background page. Returns true
 // if the background host is created.
 bool CreateLazyBackgroundHost(ProcessManager* pm, const Extension* extension) {
@@ -101,7 +86,7 @@
     const LazyContextId& context_id,
     LazyContextTaskQueue::PendingTask task) {
   AddPendingTask(context_id.browser_context(), context_id.extension_id(),
-                 base::BindOnce(&PendingTaskAdapter, std::move(task)));
+                 std::move(task));
 }
 
 void LazyBackgroundTaskQueue::AddPendingTask(
@@ -161,7 +146,7 @@
   PendingTasksList tasks;
   tasks.swap(*map_it->second);
   for (auto& task : tasks)
-    std::move(task).Run(host);
+    std::move(task).Run(host ? std::make_unique<ContextInfo>(host) : nullptr);
 
   pending_tasks_.erase(key);
 
diff --git a/extensions/browser/lazy_background_task_queue.h b/extensions/browser/lazy_background_task_queue.h
index 377756e7..b9173320 100644
--- a/extensions/browser/lazy_background_task_queue.h
+++ b/extensions/browser/lazy_background_task_queue.h
@@ -42,8 +42,6 @@
                                 public content::NotificationObserver,
                                 public ExtensionRegistryObserver {
  public:
-  using PendingTask = base::OnceCallback<void(ExtensionHost*)>;
-
   explicit LazyBackgroundTaskQueue(content::BrowserContext* browser_context);
   ~LazyBackgroundTaskQueue() override;
 
@@ -57,18 +55,17 @@
   // cancels that suspension.
   bool ShouldEnqueueTask(content::BrowserContext* context,
                          const Extension* extension) override;
+
   // TODO(lazyboy): Find a better way to use AddPendingTask instead of this.
-  // Currently AddPendingTask has lots of consumers that depend on
-  // ExtensionHost.
-  void AddPendingTaskToDispatchEvent(
-      const LazyContextId& context_id,
-      LazyContextTaskQueue::PendingTask task) override;
+  void AddPendingTaskToDispatchEvent(const LazyContextId& context_id,
+                                     PendingTask task) override;
 
   // Adds a task to the queue for a given extension. If this is the first
   // task added for the extension, its lazy background page will be loaded.
   // The task will be called either when the page is loaded, or when the
   // page fails to load for some reason (e.g. a crash or browser
-  // shutdown). In the latter case, the ExtensionHost parameter is NULL.
+  // shutdown). In the latter case, |task| will be called with an empty
+  // std::unique_ptr<ContextItem> parameter.
   void AddPendingTask(content::BrowserContext* context,
                       const std::string& extension_id,
                       PendingTask task);
diff --git a/extensions/browser/lazy_background_task_queue_unittest.cc b/extensions/browser/lazy_background_task_queue_unittest.cc
index 51e81a58..740e115 100644
--- a/extensions/browser/lazy_background_task_queue_unittest.cc
+++ b/extensions/browser/lazy_background_task_queue_unittest.cc
@@ -73,7 +73,7 @@
   TestProcessManager* process_manager() { return process_manager_; }
 
   // A simple callback for AddPendingTask.
-  void RunPendingTask(ExtensionHost* host) {
+  void RunPendingTask(std::unique_ptr<LazyContextTaskQueue::ContextInfo>) {
     task_run_count_++;
   }
 
diff --git a/extensions/browser/lazy_context_task_queue.cc b/extensions/browser/lazy_context_task_queue.cc
new file mode 100644
index 0000000..f9585dfa
--- /dev/null
+++ b/extensions/browser/lazy_context_task_queue.cc
@@ -0,0 +1,34 @@
+// Copyright 2018 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.
+
+#include "extensions/browser/lazy_context_task_queue.h"
+#include "extensions/browser/extension_host.h"
+#include "extensions/common/constants.h"
+#include "extensions/common/extension.h"
+#include "third_party/blink/public/mojom/service_worker/service_worker_object.mojom.h"
+
+namespace extensions {
+
+LazyContextTaskQueue::ContextInfo::ContextInfo(ExtensionHost* host)
+    : extension_id(host->extension()->id()),
+      render_process_host(host->render_process_host()),
+      service_worker_version_id(blink::mojom::kInvalidServiceWorkerVersionId),
+      worker_thread_id(kMainThreadId),
+      url(host->initial_url()),
+      browser_context(host->browser_context()),
+      web_contents(host->host_contents()) {}
+
+LazyContextTaskQueue::ContextInfo::ContextInfo(
+    const ExtensionId& extension_id,
+    content::RenderProcessHost* render_process_host,
+    int64_t service_worker_version_id,
+    int worker_thread_id,
+    const GURL& url)
+    : extension_id(extension_id),
+      render_process_host(render_process_host),
+      service_worker_version_id(service_worker_version_id),
+      worker_thread_id(worker_thread_id),
+      url(url) {}
+
+}  // namespace extensions
diff --git a/extensions/browser/lazy_context_task_queue.h b/extensions/browser/lazy_context_task_queue.h
index 6f44cea..f6ef47f 100644
--- a/extensions/browser/lazy_context_task_queue.h
+++ b/extensions/browser/lazy_context_task_queue.h
@@ -12,10 +12,12 @@
 namespace content {
 class BrowserContext;
 class RenderProcessHost;
+class WebContents;
 }  // namespace content
 
 namespace extensions {
 class Extension;
+class ExtensionHost;
 class LazyContextId;
 
 // Interface for performing tasks after loading lazy contexts of an extension.
@@ -33,16 +35,20 @@
     const int64_t service_worker_version_id;
     const int worker_thread_id;
     const GURL url;
+    // TODO(dbertoni): This needs to be initialized for the Service Worker
+    // version of the constructor.
+    content::BrowserContext* const browser_context = nullptr;
+    // This data member will have a nullptr value for Service Worker-related
+    // tasks.
+    content::WebContents* const web_contents = nullptr;
+
+    explicit ContextInfo(ExtensionHost* host);
+
     ContextInfo(const ExtensionId& extension_id,
                 content::RenderProcessHost* render_process_host,
                 int64_t service_worker_version_id,
                 int worker_thread_id,
-                const GURL& url)
-        : extension_id(extension_id),
-          render_process_host(render_process_host),
-          service_worker_version_id(service_worker_version_id),
-          worker_thread_id(worker_thread_id),
-          url(url) {}
+                const GURL& url);
   };
   using PendingTask =
       base::OnceCallback<void(std::unique_ptr<ContextInfo> params)>;
diff --git a/extensions/browser/process_manager.cc b/extensions/browser/process_manager.cc
index fde870c..882c7e7 100644
--- a/extensions/browser/process_manager.cc
+++ b/extensions/browser/process_manager.cc
@@ -114,9 +114,10 @@
                                   BackgroundInfo::GetBackgroundURL(extension));
 }
 
-void PropagateExtensionWakeResult(base::OnceCallback<void(bool)> callback,
-                                  extensions::ExtensionHost* host) {
-  std::move(callback).Run(host != nullptr);
+void PropagateExtensionWakeResult(
+    base::OnceCallback<void(bool)> callback,
+    std::unique_ptr<LazyContextTaskQueue::ContextInfo> context_info) {
+  std::move(callback).Run(context_info != nullptr);
 }
 
 }  // namespace