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

Side by Side Diff: chrome/browser/ui/intents/web_intent_picker_controller.cc

Issue 8666013: Add a public content/ interface for intents. Use it. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: For try servers. Created 9 years 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/ui/intents/web_intent_picker_controller.h" 5 #include "chrome/browser/ui/intents/web_intent_picker_controller.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
11 #include "chrome/browser/ui/browser.h" 11 #include "chrome/browser/ui/browser.h"
12 #include "chrome/browser/favicon/favicon_service.h" 12 #include "chrome/browser/favicon/favicon_service.h"
13 #include "chrome/browser/intents/web_intents_registry.h" 13 #include "chrome/browser/intents/web_intents_registry.h"
14 #include "chrome/browser/intents/web_intents_registry_factory.h" 14 #include "chrome/browser/intents/web_intents_registry_factory.h"
15 #include "chrome/browser/profiles/profile.h" 15 #include "chrome/browser/profiles/profile.h"
16 #include "chrome/browser/tabs/tab_strip_model.h" 16 #include "chrome/browser/tabs/tab_strip_model.h"
17 #include "chrome/browser/ui/browser_navigator.h" 17 #include "chrome/browser/ui/browser_navigator.h"
18 #include "chrome/browser/ui/intents/web_intent_picker.h" 18 #include "chrome/browser/ui/intents/web_intent_picker.h"
19 #include "chrome/browser/ui/intents/web_intent_picker_factory.h" 19 #include "chrome/browser/ui/intents/web_intent_picker_factory.h"
20 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h" 20 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
21 #include "chrome/browser/webdata/web_data_service.h" 21 #include "chrome/browser/webdata/web_data_service.h"
22 #include "content/browser/intents/intent_injector.h" 22 #include "content/browser/intents/intent_injector.h"
23 #include "content/browser/tab_contents/tab_contents.h" 23 #include "content/browser/tab_contents/tab_contents.h"
24 #include "content/common/intents_messages.h" 24 #include "content/common/intents_messages.h"
25 #include "content/public/browser/intents_host.h"
25 #include "content/public/browser/notification_source.h" 26 #include "content/public/browser/notification_source.h"
26 #include "ui/gfx/codec/png_codec.h" 27 #include "ui/gfx/codec/png_codec.h"
27 #include "webkit/glue/web_intent_service_data.h" 28 #include "webkit/glue/web_intent_service_data.h"
28 29
29 namespace { 30 namespace {
30 31
31 // Gets the favicon service for the profile in |tab_contents|. 32 // Gets the favicon service for the profile in |tab_contents|.
32 FaviconService* GetFaviconService(TabContentsWrapper* wrapper) { 33 FaviconService* GetFaviconService(TabContentsWrapper* wrapper) {
33 return wrapper->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS); 34 return wrapper->profile()->GetFaviconService(Profile::EXPLICIT_ACCESS);
34 } 35 }
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 WebIntentPickerFactory* factory) 109 WebIntentPickerFactory* factory)
109 : wrapper_(wrapper), 110 : wrapper_(wrapper),
110 picker_factory_(factory), 111 picker_factory_(factory),
111 web_intent_data_fetcher_( 112 web_intent_data_fetcher_(
112 new WebIntentDataFetcher(this, 113 new WebIntentDataFetcher(this,
113 GetWebIntentsRegistry(wrapper))), 114 GetWebIntentsRegistry(wrapper))),
114 favicon_fetcher_( 115 favicon_fetcher_(
115 new FaviconFetcher(this, GetFaviconService(wrapper))), 116 new FaviconFetcher(this, GetFaviconService(wrapper))),
116 picker_(NULL), 117 picker_(NULL),
117 pending_async_count_(0), 118 pending_async_count_(0),
118 routing_id_(0),
119 intent_id_(0),
120 service_tab_(NULL) { 119 service_tab_(NULL) {
121 NavigationController* controller = &wrapper->controller(); 120 NavigationController* controller = &wrapper->controller();
122 registrar_.Add(this, content::NOTIFICATION_LOAD_START, 121 registrar_.Add(this, content::NOTIFICATION_LOAD_START,
123 content::Source<NavigationController>(controller)); 122 content::Source<NavigationController>(controller));
124 registrar_.Add(this, content::NOTIFICATION_TAB_CLOSING, 123 registrar_.Add(this, content::NOTIFICATION_TAB_CLOSING,
125 content::Source<NavigationController>(controller)); 124 content::Source<NavigationController>(controller));
126 } 125 }
127 126
128 WebIntentPickerController::~WebIntentPickerController() { 127 WebIntentPickerController::~WebIntentPickerController() {
129 } 128 }
130 129
131 void WebIntentPickerController::SetIntent( 130 void WebIntentPickerController::SetIntentsHost(
132 int routing_id, 131 content::IntentsHost* intents_host) {
133 const webkit_glue::WebIntentData& intent, 132 intents_host_.reset(intents_host);
134 int intent_id) { 133 intents_host_->RegisterReplyNotification(
135 routing_id_ = routing_id; 134 base::Bind(&WebIntentPickerController::OnSendReturnMessage,
136 intent_ = intent; 135 base::Unretained(this)));
137 intent_id_ = intent_id;
138 } 136 }
139 137
140 void WebIntentPickerController::ShowDialog(Browser* browser, 138 void WebIntentPickerController::ShowDialog(Browser* browser,
141 const string16& action, 139 const string16& action,
142 const string16& type) { 140 const string16& type) {
143 if (picker_ != NULL) 141 if (picker_ != NULL)
144 return; 142 return;
145 143
146 picker_ = picker_factory_->Create(browser, wrapper_, this); 144 picker_ = picker_factory_->Create(browser, wrapper_, this);
147 145
148 // TODO(binji) Remove this check when there are implementations of the picker 146 // TODO(binji) Remove this check when there are implementations of the picker
149 // for windows and mac. 147 // for windows and mac.
150 if (picker_ == NULL) 148 if (picker_ == NULL)
151 return; 149 return;
152 150
153 web_intent_data_fetcher_->Fetch(action, type); 151 web_intent_data_fetcher_->Fetch(action, type);
154 } 152 }
155 153
156 void WebIntentPickerController::Observe( 154 void WebIntentPickerController::Observe(
157 int type, 155 int type,
158 const content::NotificationSource& source, 156 const content::NotificationSource& source,
159 const content::NotificationDetails& details) { 157 const content::NotificationDetails& details) {
160 DCHECK(type == content::NOTIFICATION_LOAD_START || 158 DCHECK(type == content::NOTIFICATION_LOAD_START ||
161 type == content::NOTIFICATION_TAB_CLOSING); 159 type == content::NOTIFICATION_TAB_CLOSING);
162 ClosePicker(); 160 ClosePicker();
163 } 161 }
164 162
165 // Used to forward messages to the source tab from the service context.
166 // Also watches the source tab contents, and if it closes, doesn't forward
167 // messages.
168 class InvokingTabObserver : public TabContentsObserver {
169 public:
170 InvokingTabObserver(TabContentsWrapper* wrapper,
171 IntentInjector* injector,
172 int routing_id)
173 : TabContentsObserver(wrapper->tab_contents()),
174 wrapper_(wrapper),
175 intent_injector_(injector),
176 routing_id_(routing_id) {}
177 virtual ~InvokingTabObserver() {}
178
179 virtual void TabContentsDestroyed(TabContents* tab) OVERRIDE {
180 if (intent_injector_)
181 intent_injector_->SourceTabContentsDestroyed(tab);
182 wrapper_ = NULL;
183 }
184
185 virtual bool Send(IPC::Message* message) OVERRIDE {
186 // The injector can return exactly one message. After that we don't talk
187 // to it again, since it may have deleted itself.
188 intent_injector_ = NULL;
189
190 if (!wrapper_)
191 return false;
192
193 MessageLoopForUI::current()->PostTask(
194 FROM_HERE,
195 base::Bind(&WebIntentPickerController::OnSendReturnMessage,
196 base::Unretained(wrapper_->web_intent_picker_controller())));
197
198 message->set_routing_id(routing_id_);
199 return wrapper_->Send(message);
200 }
201
202 private:
203 // Weak pointer to the source tab invoking the intent.
204 TabContentsWrapper* wrapper_;
205
206 // Weak pointer to the intent injector managing delivering the intent data to
207 // the service tab.
208 IntentInjector* intent_injector_;
209
210 // Renderer-side object invoking the intent.
211 int routing_id_;
212 };
213
214 void WebIntentPickerController::OnServiceChosen(size_t index) { 163 void WebIntentPickerController::OnServiceChosen(size_t index) {
215 DCHECK(index < urls_.size()); 164 DCHECK(index < urls_.size());
216 165
217 bool inline_disposition = service_data_[index].disposition == 166 bool inline_disposition = service_data_[index].disposition ==
218 webkit_glue::WebIntentServiceData::DISPOSITION_INLINE; 167 webkit_glue::WebIntentServiceData::DISPOSITION_INLINE;
219 TabContents* new_tab_contents = NULL; 168 TabContents* new_tab_contents = NULL;
220 if (inline_disposition) 169 if (inline_disposition)
221 new_tab_contents = picker_->SetInlineDisposition(urls_[index]); 170 new_tab_contents = picker_->SetInlineDisposition(urls_[index]);
222 171
223 if (new_tab_contents == NULL) { 172 if (new_tab_contents == NULL) {
224 // TODO(gbillock): This really only handles the 'window' disposition in a 173 // TODO(gbillock): This really only handles the 'window' disposition in a
225 // quite prototype way. We need to flesh out what happens to the picker 174 // quite prototype way. We need to flesh out what happens to the picker
226 // during the lifetime of the service url context, and that may mean we 175 // during the lifetime of the service url context, and that may mean we
227 // need to pass more information into the injector to find the picker again 176 // need to pass more information into the injector to find the picker again
228 // and close it. Also: the above conditional construction is just because 177 // and close it. Also: the above conditional construction is just because
229 // there isn't Mac/Win support yet. When that's there, it'll be an else. 178 // there isn't Mac/Win support yet. When that's there, it'll be an else.
230 browser::NavigateParams params(NULL, urls_[index], 179 browser::NavigateParams params(NULL, urls_[index],
231 content::PAGE_TRANSITION_AUTO_BOOKMARK); 180 content::PAGE_TRANSITION_AUTO_BOOKMARK);
232 params.disposition = NEW_FOREGROUND_TAB; 181 params.disposition = NEW_FOREGROUND_TAB;
233 params.profile = wrapper_->profile(); 182 params.profile = wrapper_->profile();
234 browser::Navigate(&params); 183 browser::Navigate(&params);
235 new_tab_contents = params.target_contents->tab_contents(); 184 new_tab_contents = params.target_contents->tab_contents();
236 service_tab_ = new_tab_contents; 185 service_tab_ = new_tab_contents;
237 186
238 ClosePicker(); 187 ClosePicker();
239 } 188 }
240 189
241 IntentInjector* injector = new IntentInjector(new_tab_contents); 190 intents_host_->DispatchIntent(new_tab_contents);
242 injector->SetIntent(new InvokingTabObserver(wrapper_, injector, routing_id_),
243 intent_,
244 intent_id_);
245 } 191 }
246 192
247 void WebIntentPickerController::OnCancelled() { 193 void WebIntentPickerController::OnCancelled() {
248 InvokingTabObserver forwarder(wrapper_, NULL, routing_id_); 194 if (!intents_host_.get())
195 return;
196
249 if (service_tab_) { 197 if (service_tab_) {
250 forwarder.Send(new IntentsMsg_WebIntentReply( 198 intents_host_->SendReplyMessage(webkit_glue::WEB_INTENT_SERVICE_TAB_CLOSED,
251 0, webkit_glue::WEB_INTENT_SERVICE_TAB_CLOSED, string16(), intent_id_)); 199 string16());
252 } else { 200 } else {
253 forwarder.Send(new IntentsMsg_WebIntentReply( 201 intents_host_->SendReplyMessage(webkit_glue::WEB_INTENT_PICKER_CANCELLED,
254 0, webkit_glue::WEB_INTENT_PICKER_CANCELLED, string16(), intent_id_)); 202 string16());
255 } 203 }
256 204
257 ClosePicker(); 205 ClosePicker();
258 } 206 }
259 207
260 void WebIntentPickerController::OnClosing() { 208 void WebIntentPickerController::OnClosing() {
261 } 209 }
262 210
263 void WebIntentPickerController::OnSendReturnMessage() { 211 void WebIntentPickerController::OnSendReturnMessage() {
264 ClosePicker(); 212 ClosePicker();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
376 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(), 324 if (gfx::PNGCodec::Decode(favicon_data.image_data->front(),
377 favicon_data.image_data->size(), 325 favicon_data.image_data->size(),
378 &icon_bitmap)) { 326 &icon_bitmap)) {
379 controller_->OnFaviconDataAvailable(index, icon_bitmap); 327 controller_->OnFaviconDataAvailable(index, icon_bitmap);
380 return; 328 return;
381 } 329 }
382 } 330 }
383 331
384 controller_->OnFaviconDataUnavailable(index); 332 controller_->OnFaviconDataUnavailable(index);
385 } 333 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698