Begin to enable extension APIs in Extension Service Worker.

This CL adds "tabs" API support in extension SW and adds an end-to-end
test for it.
This CL also puts the feature behind a runtime flag which is disabled for non trunk builds by default.

Some known issues:
1) Lifetime improvement of UIThreadWorkerResponseCallbackWrapper is missing.
I am currently cleaning up on RPH shutdown, but this is not idea, we should
be cleaning up on worker thread shutdown.

2) IPC send<->receive from/to Worker Thread can be made better, see
comment above WorkerThreadDispatcher in patch set #1.

3) Currently if an extension is not "active" in a process, then API calls
from that process is not classified correctly. I'm using
"extension_service_worker" context, which allows running tabs API. In
theory since a worker cannot be spawned from outside of the extension
process (TODO: Verify this), we can <fingers_crossed>safely</fingers_crossed>
classify this as a blessed context.

BUG=602442
Test=Register an extension with "tabs" permission, register a service
worker from the extension and call chrome.tabs.create() from SW code!
Expect it to work

Review-Url: https://codereview.chromium.org/1880933002
Cr-Commit-Position: refs/heads/master@{#395494}
diff --git a/chrome/browser/extensions/service_worker_apitest.cc b/chrome/browser/extensions/service_worker_apitest.cc
index 01100147..68c6e0a 100644
--- a/chrome/browser/extensions/service_worker_apitest.cc
+++ b/chrome/browser/extensions/service_worker_apitest.cc
@@ -593,6 +593,29 @@
       "service_worker/web_accessible_resources/fetch/", "page.html"));
 }
 
+IN_PROC_BROWSER_TEST_F(ServiceWorkerTest, TabsCreate) {
+  // Extensions APIs from SW are only enabled on trunk.
+  ScopedCurrentChannel current_channel_override(version_info::Channel::UNKNOWN);
+  const Extension* extension = LoadExtensionWithFlags(
+      test_data_dir_.AppendASCII("service_worker/tabs_create"), kFlagNone);
+  ASSERT_TRUE(extension);
+  ui_test_utils::NavigateToURL(browser(),
+                               extension->GetResourceURL("page.html"));
+  content::WebContents* web_contents =
+      browser()->tab_strip_model()->GetActiveWebContents();
+
+  int starting_tab_count = browser()->tab_strip_model()->count();
+  std::string result;
+  ASSERT_TRUE(content::ExecuteScriptAndExtractString(
+      web_contents, "window.runServiceWorker()", &result));
+  ASSERT_EQ("chrome.tabs.create callback", result);
+  EXPECT_EQ(starting_tab_count + 1, browser()->tab_strip_model()->count());
+
+  // Check extension shutdown path.
+  UnloadExtension(extension->id());
+  EXPECT_EQ(starting_tab_count, browser()->tab_strip_model()->count());
+}
+
 // This test loads a web page that has an iframe pointing to a
 // chrome-extension:// URL. The URL is listed in the extension's
 // web_accessible_resources. Initially the iframe is served from the extension's