summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorgbillock@chromium.org <gbillock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-28 20:46:07 +0000
committergbillock@chromium.org <gbillock@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-09-28 20:46:07 +0000
commit3ac1eef774ee13be784f4c2211f9909da27ad4dd (patch)
tree9fb9fbe03b789c5c82ffac568a71896d44c721be
parent19425758a72d1048197e9138740f6301f3eff77d (diff)
downloadchromium_src-3ac1eef774ee13be784f4c2211f9909da27ad4dd.zip
chromium_src-3ac1eef774ee13be784f4c2211f9909da27ad4dd.tar.gz
chromium_src-3ac1eef774ee13be784f4c2211f9909da27ad4dd.tar.bz2
Pass intent data through to the picker and launch a new tab
on service selection. R=jhawkins@chromium.org BUG=None TEST=None Review URL: http://codereview.chromium.org/7978014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@103171 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/ui/browser.cc4
-rw-r--r--chrome/browser/ui/intents/web_intent_picker_controller.cc31
-rw-r--r--chrome/browser/ui/intents/web_intent_picker_controller.h21
-rw-r--r--chrome/browser/ui/intents/web_intent_picker_controller_browsertest.cc135
-rw-r--r--chrome/browser/ui/intents/web_intent_picker_controller_unittest.cc24
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--content/browser/intents/intent_injector.cc14
-rw-r--r--content/browser/intents/intent_injector.h6
8 files changed, 199 insertions, 37 deletions
diff --git a/chrome/browser/ui/browser.cc b/chrome/browser/ui/browser.cc
index d5d96fc..00baca8 100644
--- a/chrome/browser/ui/browser.cc
+++ b/chrome/browser/ui/browser.cc
@@ -3816,7 +3816,9 @@ void Browser::WebIntentDispatch(TabContents* tab,
TabContentsWrapper* tcw =
TabContentsWrapper::GetCurrentWrapperForContents(tab);
-
+ tcw->web_intent_picker_controller()->SetIntent(routing_id,
+ intent,
+ intent_id);
tcw->web_intent_picker_controller()->ShowDialog(window()->GetNativeHandle(),
intent.action, intent.type);
}
diff --git a/chrome/browser/ui/intents/web_intent_picker_controller.cc b/chrome/browser/ui/intents/web_intent_picker_controller.cc
index f076dc9..cbc02ce 100644
--- a/chrome/browser/ui/intents/web_intent_picker_controller.cc
+++ b/chrome/browser/ui/intents/web_intent_picker_controller.cc
@@ -10,10 +10,12 @@
#include "chrome/browser/intents/web_intents_registry.h"
#include "chrome/browser/intents/web_intents_registry_factory.h"
#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser_navigator.h"
#include "chrome/browser/ui/intents/web_intent_picker.h"
#include "chrome/browser/ui/intents/web_intent_picker_factory.h"
#include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
#include "chrome/browser/webdata/web_data_service.h"
+#include "content/browser/intents/intent_injector.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_source.h"
#include "ui/gfx/codec/png_codec.h"
@@ -107,7 +109,9 @@ WebIntentPickerController::WebIntentPickerController(
favicon_fetcher_(
new FaviconFetcher(this, GetFaviconService(wrapper))),
picker_(NULL),
- pending_async_count_(0) {
+ pending_async_count_(0),
+ routing_id_(0),
+ intent_id_(0) {
NavigationController* controller = &wrapper->controller();
registrar_.Add(this, content::NOTIFICATION_LOAD_START,
Source<NavigationController>(controller));
@@ -118,6 +122,15 @@ WebIntentPickerController::WebIntentPickerController(
WebIntentPickerController::~WebIntentPickerController() {
}
+void WebIntentPickerController::SetIntent(
+ int routing_id,
+ const webkit_glue::WebIntentData& intent,
+ int intent_id) {
+ routing_id_ = routing_id;
+ intent_ = intent;
+ intent_id_ = intent_id;
+}
+
void WebIntentPickerController::ShowDialog(gfx::NativeWindow parent,
const string16& action,
const string16& type) {
@@ -145,8 +158,20 @@ void WebIntentPickerController::Observe(int type,
void WebIntentPickerController::OnServiceChosen(size_t index) {
DCHECK(index < urls_.size());
- // TODO(binji) Send the chosen service back to the renderer.
- LOG(INFO) << "Chose index: " << index << " url: " << urls_[index];
+ // TODO(gbillock): This really only handles the 'window' disposition in a
+ // quite prototype way. We need to flesh out what happens to the picker during
+ // the lifetime of the service url context, and that may mean we need to pass
+ // more information into the injector to find the picker again and close it.
+ browser::NavigateParams params(NULL, urls_[index],
+ PageTransition::AUTO_BOOKMARK);
+ params.disposition = NEW_FOREGROUND_TAB;
+ params.profile = wrapper_->profile();
+ browser::Navigate(&params);
+
+ IntentInjector* injector = new IntentInjector(
+ params.target_contents->tab_contents());
+ injector->SetIntent(routing_id_, intent_, intent_id_);
+
ClosePicker();
}
diff --git a/chrome/browser/ui/intents/web_intent_picker_controller.h b/chrome/browser/ui/intents/web_intent_picker_controller.h
index 4c9b989..b356550 100644
--- a/chrome/browser/ui/intents/web_intent_picker_controller.h
+++ b/chrome/browser/ui/intents/web_intent_picker_controller.h
@@ -15,6 +15,7 @@
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "ui/gfx/native_widget_types.h"
+#include "webkit/glue/web_intent_data.h"
class FaviconService;
class GURL;
@@ -35,6 +36,15 @@ class WebIntentPickerController : public NotificationObserver,
WebIntentPickerFactory* factory);
virtual ~WebIntentPickerController();
+ // Sets the intent data for which this picker was created. The picker will
+ // copy and hold this data until the user has made a service selection.
+ // |routing_id| is the IPC routing ID of the source renderer.
+ // |intent| is the intent data as created by the client content.
+ // |intent_id| is the ID assigned by the source renderer.
+ void SetIntent(int routing_id,
+ const webkit_glue::WebIntentData& intent,
+ int intent_id);
+
// Shows the web intent picker for the window |parent|, given the intent
// |action| and MIME-type |type|.
void ShowDialog(gfx::NativeWindow parent,
@@ -53,6 +63,7 @@ class WebIntentPickerController : public NotificationObserver,
private:
friend class WebIntentPickerControllerTest;
+ friend class WebIntentPickerControllerBrowserTest;
class WebIntentDataFetcher;
class FaviconFetcher;
@@ -96,6 +107,16 @@ class WebIntentPickerController : public NotificationObserver,
// A count of the outstanding asynchronous calls.
int pending_async_count_;
+ // The routing id of the renderer which launched the intent. Should be the
+ // renderer associated with the TabContents which owns this object.
+ int routing_id_;
+
+ // The intent data from the client.
+ webkit_glue::WebIntentData intent_;
+
+ // The intent ID assigned to this intent by the renderer.
+ int intent_id_;
+
DISALLOW_COPY_AND_ASSIGN(WebIntentPickerController);
};
diff --git a/chrome/browser/ui/intents/web_intent_picker_controller_browsertest.cc b/chrome/browser/ui/intents/web_intent_picker_controller_browsertest.cc
new file mode 100644
index 0000000..3ebbfda
--- /dev/null
+++ b/chrome/browser/ui/intents/web_intent_picker_controller_browsertest.cc
@@ -0,0 +1,135 @@
+// 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 "base/bind.h"
+#include "base/callback.h"
+#include "base/memory/scoped_ptr.h"
+#include "base/utf_string_conversions.h"
+#include "chrome/browser/favicon/favicon_service.h"
+#include "chrome/browser/intents/web_intents_registry.h"
+#include "chrome/browser/intents/web_intents_registry_factory.h"
+#include "chrome/browser/profiles/profile.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/intents/web_intent_picker.h"
+#include "chrome/browser/ui/intents/web_intent_picker_controller.h"
+#include "chrome/browser/ui/intents/web_intent_picker_factory.h"
+#include "chrome/browser/webdata/web_data_service.h"
+#include "chrome/test/base/in_process_browser_test.h"
+#include "chrome/test/base/ui_test_utils.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+#include "webkit/glue/web_intent_service_data.h"
+
+using testing::_;
+using testing::DoAll;
+using testing::Return;
+using testing::SaveArg;
+
+namespace {
+
+const string16 kAction1(ASCIIToUTF16("http://www.example.com/share"));
+const string16 kAction2(ASCIIToUTF16("http://www.example.com/foobar"));
+const string16 kType(ASCIIToUTF16("image/png"));
+const GURL kServiceURL1("http://www.google.com");
+const GURL kServiceURL2("http://www.chromium.org");
+
+MATCHER_P(VectorIsOfSize, n, "") {
+ return arg.size() == static_cast<size_t>(n);
+}
+
+} // namespace
+
+class WebIntentPickerMock : public WebIntentPicker {
+ public:
+ MOCK_METHOD1(SetServiceURLs, void(const std::vector<GURL>& urls));
+ MOCK_METHOD2(SetServiceIcon, void(size_t index, const SkBitmap& icon));
+ MOCK_METHOD1(SetDefaultServiceIcon, void(size_t index));
+ MOCK_METHOD0(Show, void(void));
+ MOCK_METHOD0(Close, void(void));
+};
+
+class WebIntentPickerFactoryMock : public WebIntentPickerFactory {
+ public:
+ MOCK_METHOD3(Create,
+ WebIntentPicker*(gfx::NativeWindow parent,
+ TabContentsWrapper* wrapper,
+ WebIntentPickerDelegate* delegate));
+ MOCK_METHOD1(ClosePicker, void(WebIntentPicker* picker));
+};
+
+class WebIntentPickerControllerBrowserTest : public InProcessBrowserTest {
+ protected:
+ void AddWebIntentService(const string16& action,
+ const GURL& service_url) {
+ WebIntentServiceData web_intent_service_data;
+ web_intent_service_data.action = action;
+ web_intent_service_data.type = kType;
+ web_intent_service_data.service_url = service_url;
+ web_data_service_->AddWebIntent(web_intent_service_data);
+ }
+
+ void SetPickerExpectations(int expected_service_count,
+ int expected_default_favicons) {
+ EXPECT_CALL(*picker_factory_, Create(_, _, _)).
+ WillOnce(DoAll(SaveArg<2>(&delegate_), Return(&picker_)));
+ EXPECT_CALL(picker_,
+ SetServiceURLs(VectorIsOfSize(expected_service_count))).
+ Times(1);
+ EXPECT_CALL(picker_, SetDefaultServiceIcon(_)).
+ Times(expected_default_favicons);
+ EXPECT_CALL(*picker_factory_, ClosePicker(_));
+ }
+
+ void CheckPendingAsync() {
+ if (controller_->pending_async_count() > 0) {
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ base::Bind(&WebIntentPickerControllerBrowserTest::CheckPendingAsync,
+ base::Unretained(this)));
+ return;
+ }
+
+ MessageLoop::current()->Quit();
+ }
+
+ void WaitForDialogToShow() {
+ CheckPendingAsync();
+ MessageLoop::current()->Run();
+ }
+
+ WebIntentPickerMock picker_;
+
+ // |controller_| takes ownership.
+ WebIntentPickerFactoryMock* picker_factory_;
+
+ scoped_ptr<WebIntentPickerController> controller_;
+ WebIntentPickerDelegate* delegate_;
+ WebDataService* web_data_service_;
+ FaviconService* favicon_service_;
+};
+
+IN_PROC_BROWSER_TEST_F(WebIntentPickerControllerBrowserTest, ChooseService) {
+ web_data_service_ =
+ browser()->profile()->GetWebDataService(Profile::EXPLICIT_ACCESS);
+ AddWebIntentService(kAction1, kServiceURL1);
+ AddWebIntentService(kAction1, kServiceURL2);
+
+ favicon_service_ =
+ browser()->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS);
+
+ picker_factory_ = new WebIntentPickerFactoryMock();
+ controller_.reset(new WebIntentPickerController(
+ browser()->GetSelectedTabContentsWrapper(), picker_factory_));
+
+ SetPickerExpectations(2, 2);
+
+ controller_->ShowDialog(NULL, kAction1, kType);
+ WaitForDialogToShow();
+
+ delegate_->OnServiceChosen(1);
+ ASSERT_EQ(2, browser()->tab_count());
+ EXPECT_EQ(GURL(kServiceURL2),
+ browser()->GetSelectedTabContents()->GetURL());
+}
diff --git a/chrome/browser/ui/intents/web_intent_picker_controller_unittest.cc b/chrome/browser/ui/intents/web_intent_picker_controller_unittest.cc
index 979783f..1419877 100644
--- a/chrome/browser/ui/intents/web_intent_picker_controller_unittest.cc
+++ b/chrome/browser/ui/intents/web_intent_picker_controller_unittest.cc
@@ -73,7 +73,7 @@ MATCHER_P(VectorIsOfSize, n, "") {
return arg.size() == static_cast<size_t>(n);
}
-} // namespace
+} // namespace
class WebIntentPickerMock : public WebIntentPicker {
public:
@@ -196,7 +196,10 @@ class WebIntentPickerControllerTest : public TabContentsWrapperTestHarness {
BrowserThread ui_thread_;
BrowserThread db_thread_;
WebIntentPickerMock picker_;
- WebIntentPickerFactoryMock* picker_factory_; // controller_ takes ownership.
+
+ // |controller_| takes ownership.
+ WebIntentPickerFactoryMock* picker_factory_;
+
scoped_ptr<TestWebIntentPickerController> controller_;
WebIntentPickerDelegate* delegate_;
WebDataService* web_data_service_;
@@ -240,23 +243,6 @@ TEST_F(WebIntentPickerControllerTest, DISABLED_ShowFavicon) {
WaitForDialogToShow();
}
-TEST_F(WebIntentPickerControllerTest, ChooseService) {
- SetPickerExpectations(2, 2);
- AddWebIntentService(kAction1, kServiceURL1);
- AddWebIntentService(kAction1, kServiceURL2);
-
- EXPECT_CALL(*controller_, OnServiceChosen(0))
- .WillOnce(Invoke(controller_.get(),
- &TestWebIntentPickerController::BaseOnServiceChosen));
- EXPECT_CALL(*controller_, OnCancelled())
- .Times(0);
- EXPECT_CALL(*picker_factory_, ClosePicker(_));
-
- controller_->ShowDialog(NULL, kAction1, kType);
- WaitForDialogToShow();
- delegate_->OnServiceChosen(0);
-}
-
TEST_F(WebIntentPickerControllerTest, Cancel) {
SetPickerExpectations(2, 2);
AddWebIntentService(kAction1, kServiceURL1);
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index a3bd85e..b89b478 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2396,6 +2396,7 @@
'browser/ui/find_bar/find_bar_host_browsertest.cc',
'browser/ui/global_error_service_browsertest.cc',
'browser/ui/gtk/view_id_util_browsertest.cc',
+ 'browser/ui/intents/web_intent_picker_controller_browsertest.cc',
'browser/ui/login/login_prompt_browsertest.cc',
'browser/ui/panels/base_panel_browser_test.cc',
'browser/ui/panels/base_panel_browser_test.h',
diff --git a/content/browser/intents/intent_injector.cc b/content/browser/intents/intent_injector.cc
index 600baad..7c416d0 100644
--- a/content/browser/intents/intent_injector.cc
+++ b/content/browser/intents/intent_injector.cc
@@ -28,17 +28,11 @@ void IntentInjector::TabContentsDestroyed(TabContents* tab) {
}
void IntentInjector::SetIntent(int routing_id,
- int intent_id,
- const string16& action,
- const string16& type,
- const string16& data) {
- webkit_glue::WebIntentData* intent_data = new webkit_glue::WebIntentData;
- intent_data->action = action;
- intent_data->type = type;
- intent_data->data = data;
- source_intent_.reset(intent_data);
- intent_id_ = intent_id;
+ const webkit_glue::WebIntentData& intent,
+ int intent_id) {
source_routing_id_ = routing_id;
+ source_intent_.reset(new webkit_glue::WebIntentData(intent));
+ intent_id_ = intent_id;
SendIntent();
}
diff --git a/content/browser/intents/intent_injector.h b/content/browser/intents/intent_injector.h
index 0250060..f658446 100644
--- a/content/browser/intents/intent_injector.h
+++ b/content/browser/intents/intent_injector.h
@@ -43,10 +43,8 @@ class IntentInjector : public TabContentsObserver {
// Sets the intent data to be injected. Call after the user has selected a
// service to pass the intent data to that service.
void SetIntent(int routing_id,
- int intent_id,
- const string16& action,
- const string16& type,
- const string16& data);
+ const webkit_glue::WebIntentData& intent,
+ int intent_id);
private:
// Delivers the intent data to the renderer.