Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(4857)

Unified Diff: chrome/browser/ui/intents/web_intent_picker_controller.cc

Issue 7715037: Web Intent Picker UI (implemented as a constrained dialog, linux only) (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: linux_views/chromeos fix Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/ui/intents/web_intent_picker_controller.cc
diff --git a/chrome/browser/ui/intents/web_intent_picker_controller.cc b/chrome/browser/ui/intents/web_intent_picker_controller.cc
new file mode 100644
index 0000000000000000000000000000000000000000..d348e4750e11753a248910e9c3bc1d41572a7532
--- /dev/null
+++ b/chrome/browser/ui/intents/web_intent_picker_controller.cc
@@ -0,0 +1,264 @@
+// 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/ui/intents/web_intent_picker_controller.h"
+
+#include <vector>
+
+#include "chrome/browser/favicon/favicon_service.h"
+#include "chrome/browser/intents/web_intent_data.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/intents/web_intent_picker.h"
+#include "chrome/browser/ui/intents/web_intent_picker_factory.h"
+#include "chrome/browser/webdata/web_data_service.h"
+#include "content/browser/tab_contents/tab_contents.h"
+#include "content/common/notification_source.h"
+#include "ui/gfx/codec/png_codec.h"
+
+namespace {
+
+// Gets the favicon service for the profile in |tab_contents|.
+FaviconService* GetFaviconService(TabContents* tab_contents) {
+ Profile* profile = Profile::FromBrowserContext(
+ tab_contents->browser_context());
+ return profile->GetFaviconService(Profile::EXPLICIT_ACCESS);
+}
+
+// Gets the web intents registry for the profile in |tab_contents|.
+WebIntentsRegistry* GetWebIntentsRegistry(TabContents* tab_contents) {
+ Profile* profile = Profile::FromBrowserContext(
+ tab_contents->browser_context());
+ return WebIntentsRegistryFactory::GetForProfile(profile);
+}
+
+} // namespace
+
+// A class that asynchronously fetches web intent data from the web intents
+// registry.
+class WebIntentPickerController::WebIntentDataFetcher
+ : public WebIntentsRegistry::Consumer {
+ public:
+ WebIntentDataFetcher(WebIntentPickerController* controller,
+ WebIntentsRegistry* web_intents_registry);
+ ~WebIntentDataFetcher();
+
+ // Asynchronously fetches WebIntentData for the given |action| |type| pair.
+ void Fetch(const string16& action, const string16& type);
+
+ // Cancels the WebDataService request.
+ void Cancel();
+
+ private:
+ // WebIntentsRegistry::Consumer implementation.
+ virtual void OnIntentsQueryDone(
+ WebIntentsRegistry::QueryID,
+ const std::vector<WebIntentData>& intents) OVERRIDE;
+
+ // A weak pointer to the picker controller.
+ WebIntentPickerController* controller_;
+
+ // A weak pointer to the web intents registry.
+ WebIntentsRegistry* web_intents_registry_;
+
+ // The ID of the current web intents request. The value will be -1 if
+ // there is no request in flight.
+ WebIntentsRegistry::QueryID query_id_;
+};
+
+// A class that asynchronously fetches favicons for a vector of URLs.
+class WebIntentPickerController::FaviconFetcher {
+ public:
+ FaviconFetcher(WebIntentPickerController* controller,
+ FaviconService *favicon_service);
+ ~FaviconFetcher();
+
+ // Asynchronously fetches favicons for the each URL in |urls|.
+ void Fetch(const std::vector<GURL>& urls);
+
+ // Cancels all favicon requests.
+ void Cancel();
+
+ private:
+ // Callback called when a favicon is received.
+ void OnFaviconDataAvailable(FaviconService::Handle handle,
+ history::FaviconData favicon_data);
+
+ // A weak pointer to the picker controller.
+ WebIntentPickerController* controller_;
+
+ // A weak pointer to the favicon service.
+ FaviconService* favicon_service_;
+
+ // The Consumer to handle asynchronous favicon requests.
+ CancelableRequestConsumerTSimple<size_t> load_consumer_;
+
+ DISALLOW_COPY_AND_ASSIGN(FaviconFetcher);
+};
+
+WebIntentPickerController::WebIntentPickerController(
+ TabContents* tab_contents,
+ WebIntentPickerFactory* factory)
+ : tab_contents_(tab_contents),
+ picker_factory_(factory),
+ web_intent_data_fetcher_(
+ new WebIntentDataFetcher(this,
+ GetWebIntentsRegistry(tab_contents))),
+ favicon_fetcher_(
+ new FaviconFetcher(this, GetFaviconService(tab_contents))),
+ picker_(NULL),
+ pending_async_count_(0) {
+ NavigationController* controller = &tab_contents->controller();
+ registrar_.Add(this, content::NOTIFICATION_LOAD_START,
+ Source<NavigationController>(controller));
+ registrar_.Add(this, content::NOTIFICATION_TAB_CLOSING,
+ Source<NavigationController>(controller));
+}
+
+WebIntentPickerController::~WebIntentPickerController() {
+}
+
+void WebIntentPickerController::ShowDialog(const string16& action,
+ const string16& type) {
+ if (picker_ != NULL)
+ return;
+
+ picker_ = picker_factory_->Create(tab_contents_, this);
+
+ // TODO(binji) Remove this check when there are implementations of the picker
+ // for windows and mac.
+ if (picker_ == NULL)
+ return;
+
+ web_intent_data_fetcher_->Fetch(action, type);
+}
+
+void WebIntentPickerController::Observe(int type,
+ const NotificationSource& source,
+ const NotificationDetails& details) {
+ DCHECK(type == content::NOTIFICATION_LOAD_START ||
+ type == content::NOTIFICATION_TAB_CLOSING);
+ ClosePicker();
+}
+
+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];
+ ClosePicker();
+}
+
+void WebIntentPickerController::OnCancelled() {
+ // TODO(binji) Tell the renderer that the intent was cancelled.
+ ClosePicker();
+}
+
+void WebIntentPickerController::OnWebIntentDataAvailable(
+ const std::vector<WebIntentData>& intent_data) {
+ urls_.clear();
+ for (size_t i = 0; i < intent_data.size(); ++i) {
+ urls_.push_back(intent_data[i].service_url);
+ }
+
+ // Tell the picker to initialize N urls to the default favicon
+ picker_->SetServiceURLs(urls_);
+ favicon_fetcher_->Fetch(urls_);
+ pending_async_count_--;
+}
+
+void WebIntentPickerController::OnFaviconDataAvailable(
+ size_t index,
+ const SkBitmap& icon_bitmap) {
+ picker_->SetServiceIcon(index, icon_bitmap);
+ pending_async_count_--;
+}
+
+void WebIntentPickerController::OnFaviconDataUnavailable(size_t index) {
+ picker_->SetDefaultServiceIcon(index);
+ pending_async_count_--;
+}
+
+void WebIntentPickerController::ClosePicker() {
+ if (picker_) {
+ picker_factory_->ClosePicker(picker_);
+ picker_ = NULL;
+ }
+}
+
+WebIntentPickerController::WebIntentDataFetcher::WebIntentDataFetcher(
+ WebIntentPickerController* controller,
+ WebIntentsRegistry* web_intents_registry)
+ : controller_(controller),
+ web_intents_registry_(web_intents_registry),
+ query_id_(-1) {
+}
+
+WebIntentPickerController::WebIntentDataFetcher::~WebIntentDataFetcher() {
+}
+
+void WebIntentPickerController::WebIntentDataFetcher::Fetch(
+ const string16& action,
+ const string16& type) {
+ DCHECK(query_id_ == -1) << "Fetch already in process.";
+ controller_->pending_async_count_++;
+ query_id_ = web_intents_registry_->GetIntentProviders(action, this);
+}
+
+void WebIntentPickerController::WebIntentDataFetcher::OnIntentsQueryDone(
+ WebIntentsRegistry::QueryID,
+ const std::vector<WebIntentData>& intents) {
+ controller_->OnWebIntentDataAvailable(intents);
+ query_id_ = -1;
+}
+
+WebIntentPickerController::FaviconFetcher::FaviconFetcher(
+ WebIntentPickerController* controller,
+ FaviconService* favicon_service)
+ : controller_(controller),
+ favicon_service_(favicon_service) {
+}
+
+WebIntentPickerController::FaviconFetcher::~FaviconFetcher() {
+}
+
+void WebIntentPickerController::FaviconFetcher::Fetch(
+ const std::vector<GURL>& urls) {
+ if (!favicon_service_)
+ return;
+
+ for (size_t index = 0; index < urls.size(); ++index) {
+ controller_->pending_async_count_++;
+ FaviconService::Handle handle = favicon_service_->GetFaviconForURL(
+ urls[index],
+ history::FAVICON,
+ &load_consumer_,
+ NewCallback(this, &WebIntentPickerController::FaviconFetcher::
+ OnFaviconDataAvailable));
+ load_consumer_.SetClientData(favicon_service_, handle, index);
+ }
+}
+
+void WebIntentPickerController::FaviconFetcher::Cancel() {
+ load_consumer_.CancelAllRequests();
+}
+
+void WebIntentPickerController::FaviconFetcher::OnFaviconDataAvailable(
+ FaviconService::Handle handle,
+ history::FaviconData favicon_data) {
+ size_t index = load_consumer_.GetClientDataForCurrentRequest();
+ if (favicon_data.is_valid()) {
+ SkBitmap icon_bitmap;
+
+ if (gfx::PNGCodec::Decode(favicon_data.image_data->front(),
+ favicon_data.image_data->size(),
+ &icon_bitmap)) {
+ controller_->OnFaviconDataAvailable(index, icon_bitmap);
+ return;
+ }
+ }
+
+ controller_->OnFaviconDataUnavailable(index);
+}

Powered by Google App Engine
This is Rietveld 408576698