Web Intents: Preparatory work.
* Added --enable-web-intents switch.
* Added enable_web_intents build variable, for use in WebKit mostly.
* Added registration InfoBar and piping to the WebKit side, which is not hooked
  up on that side yet.

BUG=none
TEST=RegisterIntentHandlerInfoBarDelegateTest.*

Review URL: http://codereview.chromium.org/7461093

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@94867 0039d316-1c4b-4281-b951-d872f2087c98
diff --git a/build/common.gypi b/build/common.gypi
index d8cacd2..9eb94f3b 100644
--- a/build/common.gypi
+++ b/build/common.gypi
@@ -187,6 +187,9 @@
       # Enable navigator.registerProtocolHandler and supporting UI.
       'enable_register_protocol_handler%': 1,
 
+      # Enable Web Intents and supporting UI.
+      'enable_web_intents%': 0,
+
       # Smooth scrolling is disabled by default.
       'enable_smooth_scrolling%': 0,
 
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd
index aa82202..d51b997 100644
--- a/chrome/app/generated_resources.grd
+++ b/chrome/app/generated_resources.grd
@@ -13117,27 +13117,30 @@
     <message name="IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM" desc="The message to display when asking a user to confirm the registration of a protocol handler.">
       Allow <ph name="HANDLER_TITLE">$1<ex>Google Search</ex></ph> (<ph name="HANDLER_HOSTNAME">$2<ex>google.com</ex></ph>) to open all <ph name="PROTOCOL">$3<ex>search</ex></ph> links?
     </message>
-
     <message name="IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM_REPLACE" desc="The message to display when asking a user to confirm the registration of a protocol handler.">
       Allow <ph name="HANDLER_TITLE">$1<ex>Google Search</ex></ph> (<ph name="HANDLER_HOSTNAME">$2<ex>google.com</ex></ph>) to open all <ph name="PROTOCOL">$3<ex>search</ex></ph> links instead of <ph name="REPLACED_HANDLER_TITLE">$4<ex>Elgoog Search</ex></ph>?
     </message>
-
     <message name="IDS_REGISTER_PROTOCOL_HANDLER_ACCEPT" desc="Text to show for the accept button for the register protocol handler request infobar.">
-        Use <ph name="HANDLER_TITLE">$1<ex>Google Search</ex></ph>
+      Use <ph name="HANDLER_TITLE">$1<ex>Google Search</ex></ph>
     </message>
-
     <message name="IDS_REGISTER_PROTOCOL_HANDLER_DENY" desc="Text to show for the deny button for the register protocol handler request infobar.">
-        No
+      No
     </message>
-
-    <message name="IDS_REGISTER_PROTOCOL_HANDLER_NEVER" desc="Text to show for the never button for the register protocol handler request infobar.">
-        Never
-    </message>
-
     <message name="IDS_REGISTER_PROTOCOL_HANDLER_ALREADY_REGISTERED" desc="Text to show when the user tries to register a protocol handler that they have already registered.">
       <ph name="HANDLER_TITLE">$1<ex>Google Search</ex></ph> is already being used to handle <ph name="PROTOCOL">$2<ex>search</ex></ph>: links.
     </message>
 
+    <!-- Web Intents -->
+    <message name="IDS_REGISTER_INTENT_HANDLER_CONFIRM" desc="The message to display when asking the user to confirm registration of an intent handler.">
+      Allow <ph name="INTENT_HANDLE_TITLE">$1<ex>Google Search</ex></ph> (<ph name="INTENT_HANDLE_HOSTNAME">$2<ex>google.com</ex></ph>) to handle intents?
+    </message>
+    <message name="IDS_REGISTER_INTENT_HANDLER_ACCEPT" desc="Text to show for the accept button for the register intent handler request infobar.">
+      Use <ph name="INTENT_HANDLER_TITLE">$1<ex>Google Search</ex></ph>
+    </message>
+    <message name="IDS_REGISTER_INTENT_HANDLER_DENY" desc="Text to show for the deny button for the register intent handler request infobar.">
+      No
+    </message>
+
     <!-- PDF with unsupported feature Info Bar -->
     <message name="IDS_PDF_INFOBAR_QUESTION_READER_INSTALLED" desc="Question asked on the info bar when a user views a PDF with an unsupported feature and they have Adobe Reader installed.">
       Parts of this PDF document could not be displayed.  Open in Adobe Reader?
diff --git a/chrome/browser/intents/register_intent_handler_infobar_delegate.cc b/chrome/browser/intents/register_intent_handler_infobar_delegate.cc
new file mode 100644
index 0000000..2097e3e
--- /dev/null
+++ b/chrome/browser/intents/register_intent_handler_infobar_delegate.cc
@@ -0,0 +1,49 @@
+// Copyright (c) 2011 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 "chrome/browser/intents/register_intent_handler_infobar_delegate.h"
+
+#include "base/logging.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "grit/generated_resources.h"
+#include "ui/base/l10n/l10n_util.h"
+
+RegisterIntentHandlerInfoBarDelegate::RegisterIntentHandlerInfoBarDelegate(
+    TabContents* tab_contents)
+    : ConfirmInfoBarDelegate(tab_contents),
+      tab_contents_(tab_contents) {
+}
+
+InfoBarDelegate::Type
+    RegisterIntentHandlerInfoBarDelegate::GetInfoBarType() const {
+  return PAGE_ACTION_TYPE;
+}
+
+string16 RegisterIntentHandlerInfoBarDelegate::GetMessageText() const {
+  return l10n_util::GetStringFUTF16(IDS_REGISTER_PROTOCOL_HANDLER_CONFIRM,
+                                    string16(), string16());
+}
+
+string16 RegisterIntentHandlerInfoBarDelegate::GetButtonLabel(
+    InfoBarButton button) const {
+  if (button == BUTTON_OK) {
+    return l10n_util::GetStringFUTF16(IDS_REGISTER_INTENT_HANDLER_ACCEPT,
+                                      string16());
+  }
+
+  DCHECK(button == BUTTON_CANCEL);
+  return l10n_util::GetStringUTF16(IDS_REGISTER_INTENT_HANDLER_DENY);
+}
+
+string16 RegisterIntentHandlerInfoBarDelegate::GetLinkText() const {
+  return l10n_util::GetStringUTF16(IDS_LEARN_MORE);
+}
+
+bool RegisterIntentHandlerInfoBarDelegate::LinkClicked(
+    WindowOpenDisposition disposition) {
+  // TODO(jhawkins): Open the Web Intents Help Center article once it is
+  // written.
+  // TODO(jhawkins): Add associated bug for the article here.
+  return false;
+}
diff --git a/chrome/browser/intents/register_intent_handler_infobar_delegate.h b/chrome/browser/intents/register_intent_handler_infobar_delegate.h
new file mode 100644
index 0000000..315691a
--- /dev/null
+++ b/chrome/browser/intents/register_intent_handler_infobar_delegate.h
@@ -0,0 +1,36 @@
+// Copyright (c) 2011 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.
+
+#ifndef CHROME_BROWSER_INTENTS_REGISTER_INTENT_HANDLER_INFOBAR_DELEGATE_H_
+#define CHROME_BROWSER_INTENTS_REGISTER_INTENT_HANDLER_INFOBAR_DELEGATE_H_
+#pragma once
+
+#include "base/basictypes.h"
+#include "base/string16.h"
+#include "chrome/browser/tab_contents/confirm_infobar_delegate.h"
+
+class TabContents;
+
+// The InfoBar used to request permission for a site to be registered as an
+// Intent handler.
+class RegisterIntentHandlerInfoBarDelegate : public ConfirmInfoBarDelegate {
+ public:
+  // TODO(jhawkins): Pass in WebIntentData.
+  explicit RegisterIntentHandlerInfoBarDelegate(TabContents* tab_contents);
+
+  // ConfirmInfoBarDelegate implementation.
+  virtual Type GetInfoBarType() const OVERRIDE;
+  virtual string16 GetMessageText() const OVERRIDE;
+  virtual string16 GetButtonLabel(InfoBarButton button) const OVERRIDE;
+  virtual string16 GetLinkText() const OVERRIDE;
+  virtual bool LinkClicked(WindowOpenDisposition disposition) OVERRIDE;
+
+ private:
+  // The TabContents that contains this InfoBar. Weak pointer.
+  TabContents* tab_contents_;
+
+  DISALLOW_COPY_AND_ASSIGN(RegisterIntentHandlerInfoBarDelegate);
+};
+
+#endif  // CHROME_BROWSER_INTENTS_REGISTER_INTENT_HANDLER_INFOBAR_DELEGATE_H_
diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
index 651aa09..27050c55 100644
--- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
+++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.cc
@@ -21,6 +21,7 @@
 #include "chrome/browser/file_select_helper.h"
 #include "chrome/browser/google/google_util.h"
 #include "chrome/browser/history/history_tab_helper.h"
+#include "chrome/browser/intents/register_intent_handler_infobar_delegate.h"
 #include "chrome/browser/omnibox_search_hint.h"
 #include "chrome/browser/password_manager/password_manager.h"
 #include "chrome/browser/password_manager_delegate_impl.h"
@@ -407,6 +408,8 @@
     IPC_MESSAGE_HANDLER(ViewHostMsg_JSOutOfMemory, OnJSOutOfMemory)
     IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterProtocolHandler,
                         OnRegisterProtocolHandler)
+    IPC_MESSAGE_HANDLER(ViewHostMsg_RegisterIntentHandler,
+                        OnRegisterIntentHandler)
     IPC_MESSAGE_HANDLER(ViewHostMsg_Snapshot, OnSnapshot)
     IPC_MESSAGE_HANDLER(ViewHostMsg_PDFHasUnsupportedFeature,
                         OnPDFHasUnsupportedFeature)
@@ -581,6 +584,19 @@
   }
 }
 
+void TabContentsWrapper::OnRegisterIntentHandler(const string16& action,
+                                                 const string16& type,
+                                                 const string16& href,
+                                                 const string16& title) {
+  if (profile()->IsOffTheRecord())
+    return;
+
+  if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kEnableWebIntents))
+    return;
+
+  AddInfoBar(new RegisterIntentHandlerInfoBarDelegate(tab_contents()));
+}
+
 void TabContentsWrapper::OnSnapshot(const SkBitmap& bitmap) {
   NotificationService::current()->Notify(
       chrome::NOTIFICATION_TAB_SNAPSHOT_TAKEN,
diff --git a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h
index 24fa53c..5a553c6 100644
--- a/chrome/browser/ui/tab_contents/tab_contents_wrapper.h
+++ b/chrome/browser/ui/tab_contents/tab_contents_wrapper.h
@@ -243,6 +243,10 @@
   void OnRegisterProtocolHandler(const std::string& protocol,
                                  const GURL& url,
                                  const string16& title);
+  void OnRegisterIntentHandler(const string16& action,
+                               const string16& type,
+                               const string16& href,
+                               const string16& title);
   void OnSnapshot(const SkBitmap& bitmap);
   void OnPDFHasUnsupportedFeature();
   void OnDidBlockDisplayingInsecureContent();
diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi
index 8a1200c..94a7158 100644
--- a/chrome/chrome_browser.gypi
+++ b/chrome/chrome_browser.gypi
@@ -1359,6 +1359,8 @@
         'browser/instant/instant_unload_handler.h',
         'browser/instant/promo_counter.cc',
         'browser/instant/promo_counter.h',
+        'browser/intents/register_intent_handler_infobar_delegate.cc',
+        'browser/intents/register_intent_handler_infobar_delegate.h',
         'browser/internal_auth.cc',
         'browser/internal_auth.h',
         'browser/intranet_redirect_detector.cc',
diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc
index 4c0bd6c..c8667c8 100644
--- a/chrome/common/chrome_switches.cc
+++ b/chrome/common/chrome_switches.cc
@@ -531,6 +531,9 @@
 // Order of the listed sub-arguments does not matter.
 const char kEnableWatchdog[]                = "enable-watchdog";
 
+// Enable Web Intents.
+const char kEnableWebIntents[]              = "enable-web-intents";
+
 // Use WebSocket over SPDY.
 const char kEnableWebSocketOverSpdy[]       = "enable-websocket-over-spdy";
 
diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h
index f1a1c3b..4fa2c0b6 100644
--- a/chrome/common/chrome_switches.h
+++ b/chrome/common/chrome_switches.h
@@ -156,6 +156,7 @@
 extern const char kEnableTopSites[];
 extern const char kEnableVerticalTabs[];
 extern const char kEnableWatchdog[];
+extern const char kEnableWebIntents[];
 extern const char kEnableWebSocketOverSpdy[];
 extern const char kEnableWebUITaskManager[];
 extern const char kExperimentalSpellcheckerFeatures[];
diff --git a/content/common/view_messages.h b/content/common/view_messages.h
index 9afc29a..13c5d8d 100644
--- a/content/common/view_messages.h
+++ b/content/common/view_messages.h
@@ -1981,6 +1981,13 @@
                     GURL /* url */,
                     string16 /* title */)
 
+// Register a new handler for Intents with the given action and type filter.
+IPC_MESSAGE_ROUTED4(ViewHostMsg_RegisterIntentHandler,
+                    string16 /* action */,
+                    string16 /* type */,
+                    string16 /* href */,
+                    string16 /* title */)
+
 // Stores new inspector setting in the profile.
 // TODO(jam): this should be in the chrome module
 IPC_MESSAGE_ROUTED2(ViewHostMsg_UpdateInspectorSetting,
diff --git a/content/renderer/render_view.cc b/content/renderer/render_view.cc
index 6d698d9..52c4982 100644
--- a/content/renderer/render_view.cc
+++ b/content/renderer/render_view.cc
@@ -4325,6 +4325,18 @@
                                               title));
 }
 
+void RenderView::registerIntentHandler(const WebString& action,
+                                       const WebString& type,
+                                       const WebString& href,
+                                       const WebString& title) {
+  RenderThread::current()->Send(
+      new ViewHostMsg_RegisterIntentHandler(routing_id_,
+                                            action,
+                                            type,
+                                            href,
+                                            title));
+}
+
 WebKit::WebPageVisibilityState RenderView::visibilityState() const {
   WebKit::WebPageVisibilityState current_state = is_hidden() ?
       WebKit::WebPageVisibilityStateHidden :
diff --git a/content/renderer/render_view.h b/content/renderer/render_view.h
index 16501b80..7678950d 100644
--- a/content/renderer/render_view.h
+++ b/content/renderer/render_view.h
@@ -434,6 +434,10 @@
                                        const WebKit::WebString& base_url,
                                        const WebKit::WebString& url,
                                        const WebKit::WebString& title);
+  virtual void registerIntentHandler(const WebKit::WebString& action,
+                                     const WebKit::WebString& type,
+                                     const WebKit::WebString& href,
+                                     const WebKit::WebString& title);
   virtual WebKit::WebPageVisibilityState visibilityState() const;
 
   // WebKit::WebFrameClient implementation -------------------------------------