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

Side by Side Diff: chrome/browser/notifications/sync_notifier/synced_notification.cc

Issue 193773003: Turn on and use the AppInfo data. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Turn on app info: LGTM nits Created 6 years, 8 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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/notifications/sync_notifier/synced_notification.h" 5 #include "chrome/browser/notifications/sync_notifier/synced_notification.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/strings/string_util.h" 8 #include "base/strings/string_util.h"
9 #include "base/strings/stringprintf.h" 9 #include "base/strings/stringprintf.h"
10 #include "base/strings/utf_string_conversions.h" 10 #include "base/strings/utf_string_conversions.h"
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
61 local_enum_must_match_protobuf_enum); 61 local_enum_must_match_protobuf_enum);
62 COMPILE_ASSERT(static_cast<sync_pb::CoalescedSyncedNotification_ReadState>( 62 COMPILE_ASSERT(static_cast<sync_pb::CoalescedSyncedNotification_ReadState>(
63 SyncedNotification::kRead) == 63 SyncedNotification::kRead) ==
64 sync_pb::CoalescedSyncedNotification_ReadState_READ, 64 sync_pb::CoalescedSyncedNotification_ReadState_READ,
65 local_enum_must_match_protobuf_enum); 65 local_enum_must_match_protobuf_enum);
66 COMPILE_ASSERT(static_cast<sync_pb::CoalescedSyncedNotification_ReadState>( 66 COMPILE_ASSERT(static_cast<sync_pb::CoalescedSyncedNotification_ReadState>(
67 SyncedNotification::kDismissed) == 67 SyncedNotification::kDismissed) ==
68 sync_pb::CoalescedSyncedNotification_ReadState_DISMISSED, 68 sync_pb::CoalescedSyncedNotification_ReadState_DISMISSED,
69 local_enum_must_match_protobuf_enum); 69 local_enum_must_match_protobuf_enum);
70 70
71 SyncedNotification::SyncedNotification(const syncer::SyncData& sync_data) 71 SyncedNotification::SyncedNotification(
72 : notification_manager_(NULL), 72 const syncer::SyncData& sync_data,
73 notifier_service_(NULL), 73 ChromeNotifierService* notifier_service,
74 NotificationUIManager* notification_manager)
75 : notification_manager_(notification_manager),
76 notifier_service_(notifier_service),
74 profile_(NULL), 77 profile_(NULL),
75 toast_state_(true), 78 toast_state_(true),
76 app_icon_bitmap_fetch_pending_(true), 79 app_icon_bitmap_fetch_pending_(true),
77 sender_bitmap_fetch_pending_(true), 80 sender_bitmap_fetch_pending_(true),
78 image_bitmap_fetch_pending_(true) { 81 image_bitmap_fetch_pending_(true) {
79 Update(sync_data); 82 Update(sync_data);
80 } 83 }
81 84
82 SyncedNotification::~SyncedNotification() {} 85 SyncedNotification::~SyncedNotification() {}
83 86
84 void SyncedNotification::Update(const syncer::SyncData& sync_data) { 87 void SyncedNotification::Update(const syncer::SyncData& sync_data) {
85 // TODO(petewil): Add checking that the notification looks valid. 88 // TODO(petewil): Add checking that the notification looks valid.
86 specifics_.CopyFrom(sync_data.GetSpecifics().synced_notification()); 89 specifics_.CopyFrom(sync_data.GetSpecifics().synced_notification());
87 } 90 }
88 91
89 sync_pb::EntitySpecifics SyncedNotification::GetEntitySpecifics() const { 92 void SyncedNotification::Show(Profile* profile) {
90 sync_pb::EntitySpecifics entity_specifics;
91 entity_specifics.mutable_synced_notification()->CopyFrom(specifics_);
92 return entity_specifics;
93 }
94
95 // Check that we have either fetched or gotten an error on all the bitmaps we
96 // asked for.
97 bool SyncedNotification::AreAllBitmapsFetched() {
98 bool app_icon_ready = GetAppIconUrl().is_empty() ||
99 !app_icon_bitmap_.IsEmpty() || !app_icon_bitmap_fetch_pending_;
100 bool images_ready = GetImageUrl().is_empty() || !image_bitmap_.IsEmpty() ||
101 !image_bitmap_fetch_pending_;
102 bool sender_picture_ready = GetProfilePictureUrl(0).is_empty() ||
103 !sender_bitmap_.IsEmpty() || !sender_bitmap_fetch_pending_;
104 bool button_bitmaps_ready = true;
105 for (unsigned int j = 0; j < GetButtonCount(); ++j) {
106 if (!GetButtonIconUrl(j).is_empty()
107 && button_bitmaps_[j].IsEmpty()
108 && button_bitmaps_fetch_pending_[j]) {
109 button_bitmaps_ready = false;
110 break;
111 }
112 }
113
114 return app_icon_ready && images_ready && sender_picture_ready &&
115 button_bitmaps_ready;
116 }
117
118 // TODO(petewil): The fetch mechanism appears to be returning two bitmaps on the
119 // mac - perhaps one is regular, one is high dpi? If so, ensure we use the high
120 // dpi bitmap when appropriate.
121 void SyncedNotification::OnFetchComplete(const GURL url,
122 const SkBitmap* bitmap) {
123 // TODO(petewil): Add timeout mechanism in case bitmaps take too long. Do we
124 // already have one built into URLFetcher?
125 // Make sure we are on the thread we expect.
126 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
127
128 gfx::Image downloaded_image;
129 if (bitmap != NULL)
130 downloaded_image = gfx::Image::CreateFrom1xBitmap(*bitmap);
131
132 // Match the incoming bitmaps to URLs. In case this is a dup, make sure to
133 // try all potentially matching urls.
134 if (GetAppIconUrl() == url) {
135 app_icon_bitmap_ = downloaded_image;
136 if (app_icon_bitmap_.IsEmpty())
137 app_icon_bitmap_fetch_pending_ = false;
138 }
139 if (GetImageUrl() == url) {
140 image_bitmap_ = downloaded_image;
141 if (image_bitmap_.IsEmpty())
142 image_bitmap_fetch_pending_ = false;
143 }
144 if (GetProfilePictureUrl(0) == url) {
145 sender_bitmap_ = downloaded_image;
146 if (sender_bitmap_.IsEmpty())
147 sender_bitmap_fetch_pending_ = false;
148 }
149
150 // If this URL matches one or more button bitmaps, save them off.
151 for (unsigned int i = 0; i < GetButtonCount(); ++i) {
152 if (GetButtonIconUrl(i) == url) {
153 if (bitmap != NULL) {
154 button_bitmaps_[i] = gfx::Image::CreateFrom1xBitmap(*bitmap);
155 }
156 button_bitmaps_fetch_pending_[i] = false;
157 }
158 }
159
160 DVLOG(2) << __FUNCTION__ << " popping bitmap " << url;
161
162 // See if all bitmaps are already accounted for, if so call Show.
163 if (AreAllBitmapsFetched()) {
164 Show(notification_manager_, notifier_service_, profile_);
165 }
166 }
167
168 void SyncedNotification::QueueBitmapFetchJobs(
169 NotificationUIManager* notification_manager,
170 ChromeNotifierService* notifier_service,
171 Profile* profile) {
172 // If we are not using the MessageCenter, call show now, and the existing
173 // code will handle the bitmap fetch for us.
174 if (!UseRichNotifications()) {
175 Show(notification_manager, notifier_service, profile);
176 return;
177 }
178
179 // Save off the arguments for the call to Show.
180 notification_manager_ = notification_manager;
181 notifier_service_ = notifier_service;
182 profile_ = profile;
183
184 // Ensure our bitmap vector has as many entries as there are buttons,
185 // so that when the bitmaps arrive the vector has a slot for them.
186 for (unsigned int i = 0; i < GetButtonCount(); ++i) {
187 button_bitmaps_.push_back(gfx::Image());
188 button_bitmaps_fetch_pending_.push_back(true);
189 AddBitmapToFetchQueue(GetButtonIconUrl(i));
190 }
191
192 // If there is a profile image bitmap, fetch it
193 if (GetProfilePictureCount() > 0) {
194 // TODO(petewil): When we have the capacity to display more than one bitmap,
195 // modify this code to fetch as many as we can display
196 AddBitmapToFetchQueue(GetProfilePictureUrl(0));
197 }
198
199 // If the URL is non-empty, add it to our queue of URLs to fetch.
200 AddBitmapToFetchQueue(GetAppIconUrl());
201 AddBitmapToFetchQueue(GetImageUrl());
202
203 // Check to see if we don't need to fetch images, either because we already
204 // did, or because the URLs are empty. If so, we can display the notification.
205
206 // See if all bitmaps are accounted for, if so call Show().
207 if (AreAllBitmapsFetched()) {
208 Show(notification_manager_, notifier_service_, profile_);
209 }
210 }
211
212 void SyncedNotification::StartBitmapFetch() {
213 // Now that we have queued and counted them all, start the fetching.
214 ScopedVector<chrome::BitmapFetcher>::iterator iter;
215 for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
216 (*iter)->Start(profile_);
217 }
218 }
219
220 void SyncedNotification::AddBitmapToFetchQueue(const GURL& url) {
221 // Check for dups, ignore any request for a dup.
222 ScopedVector<chrome::BitmapFetcher>::iterator iter;
223 for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
224 if ((*iter)->url() == url)
225 return;
226 }
227
228 if (url.is_valid()) {
229 fetchers_.push_back(new chrome::BitmapFetcher(url, this));
230 DVLOG(2) << __FUNCTION__ << "Pushing bitmap " << url;
231 }
232 }
233
234 void SyncedNotification::Show(NotificationUIManager* notification_manager,
235 ChromeNotifierService* notifier_service,
236 Profile* profile) {
237 // Let NotificationUIManager know that the notification has been dismissed. 93 // Let NotificationUIManager know that the notification has been dismissed.
238 if (SyncedNotification::kRead == GetReadState() || 94 if (SyncedNotification::kRead == GetReadState() ||
239 SyncedNotification::kDismissed == GetReadState() ) { 95 SyncedNotification::kDismissed == GetReadState() ) {
240 notification_manager->CancelById(GetKey()); 96 notification_manager_->CancelById(GetKey());
241 DVLOG(2) << "Dismissed or read notification arrived" 97 DVLOG(2) << "Dismissed or read notification arrived"
242 << GetHeading() << " " << GetText(); 98 << GetHeading() << " " << GetText();
243 return; 99 return;
244 } 100 }
245 101
246 // |notifier_service| can be NULL in tests. 102 // |notifier_service| can be NULL in tests.
247 if (UseRichNotifications() && notifier_service) { 103 if (UseRichNotifications() && notifier_service_) {
248 notifier_service->ShowWelcomeToastIfNecessary(this, notification_manager); 104 notifier_service_->ShowWelcomeToastIfNecessary(this, notification_manager_);
249 } 105 }
250 106
251 // Set up the fields we need to send and create a Notification object. 107 // Set up the fields we need to send and create a Notification object.
252 GURL image_url = GetImageUrl(); 108 GURL image_url = GetImageUrl();
253 base::string16 text = base::UTF8ToUTF16(GetText()); 109 base::string16 text = base::UTF8ToUTF16(GetText());
254 base::string16 heading = base::UTF8ToUTF16(GetHeading()); 110 base::string16 heading = base::UTF8ToUTF16(GetHeading());
255 base::string16 description = base::UTF8ToUTF16(GetDescription()); 111 base::string16 description = base::UTF8ToUTF16(GetDescription());
256 base::string16 annotation = base::UTF8ToUTF16(GetAnnotation()); 112 base::string16 annotation = base::UTF8ToUTF16(GetAnnotation());
257 // TODO(petewil): Eventually put the display name of the sending service here. 113 // TODO(petewil): Eventually put the display name of the sending service here.
258 base::string16 display_source = base::UTF8ToUTF16(GetAppId()); 114 base::string16 display_source = base::UTF8ToUTF16(GetAppId());
259 base::string16 replace_key = base::UTF8ToUTF16(GetKey()); 115 base::string16 replace_key = base::UTF8ToUTF16(GetKey());
260 base::string16 notification_heading = heading; 116 base::string16 notification_heading = heading;
261 base::string16 notification_text = description; 117 base::string16 notification_text = description;
262 base::string16 newline = base::UTF8ToUTF16("\n"); 118 base::string16 newline = base::UTF8ToUTF16("\n");
263 119
264 // The delegate will eventually catch calls that the notification 120 // The delegate will eventually catch calls that the notification
265 // was read or deleted, and send the changes back to the server. 121 // was read or deleted, and send the changes back to the server.
266 scoped_refptr<NotificationDelegate> delegate = 122 scoped_refptr<NotificationDelegate> delegate =
267 new ChromeNotifierDelegate(GetKey(), notifier_service); 123 new ChromeNotifierDelegate(GetKey(), notifier_service_);
268 124
269 // Some inputs and fields are only used if there is a notification center. 125 // Some inputs and fields are only used if there is a notification center.
270 if (UseRichNotifications()) { 126 if (UseRichNotifications()) {
271 base::Time creation_time = 127 base::Time creation_time =
272 base::Time::FromDoubleT(static_cast<double>(GetCreationTime())); 128 base::Time::FromDoubleT(static_cast<double>(GetCreationTime()));
273 int priority = GetPriority(); 129 int priority = GetPriority();
274 unsigned int button_count = GetButtonCount(); 130 unsigned int button_count = GetButtonCount();
275 131
276 // Deduce which notification template to use from the data. 132 // Deduce which notification template to use from the data.
277 message_center::NotificationType notification_type = 133 message_center::NotificationType notification_type =
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
357 blink::WebTextDirectionDefault, 213 blink::WebTextDirectionDefault,
358 message_center::NotifierId(GetOriginUrl()), 214 message_center::NotifierId(GetOriginUrl()),
359 display_source, 215 display_source,
360 replace_key, 216 replace_key,
361 rich_notification_data, 217 rich_notification_data,
362 delegate.get()); 218 delegate.get());
363 // In case the notification is not supposed to be toasted, pretend that it 219 // In case the notification is not supposed to be toasted, pretend that it
364 // has already been shown. 220 // has already been shown.
365 ui_notification.set_shown_as_popup(!toast_state_); 221 ui_notification.set_shown_as_popup(!toast_state_);
366 222
367 notification_manager->Add(ui_notification, profile); 223 notification_manager_->Add(ui_notification, profile);
368 } else { 224 } else {
369 // In this case we have a Webkit Notification, not a Rich Notification. 225 // In this case we have a Webkit Notification, not a Rich Notification.
370 Notification ui_notification(GetOriginUrl(), 226 Notification ui_notification(GetOriginUrl(),
371 GetAppIconUrl(), 227 GetAppIconUrl(),
372 notification_heading, 228 notification_heading,
373 notification_text, 229 notification_text,
374 blink::WebTextDirectionDefault, 230 blink::WebTextDirectionDefault,
375 display_source, 231 display_source,
376 replace_key, 232 replace_key,
377 delegate.get()); 233 delegate.get());
378 234
379 notification_manager->Add(ui_notification, profile); 235 notification_manager_->Add(ui_notification, profile);
380 } 236 }
381 237
382 DVLOG(1) << "Showing Synced Notification! " << heading << " " << text 238 DVLOG(1) << "Showing Synced Notification! " << heading << " " << text
383 << " " << GetAppIconUrl() << " " << replace_key << " " 239 << " " << GetAppIconUrl() << " " << replace_key << " "
384 << GetProfilePictureUrl(0) << " " << GetReadState(); 240 << GetProfilePictureUrl(0) << " " << GetReadState();
385 241
386 return; 242 return;
387 } 243 }
388 244
245 sync_pb::EntitySpecifics SyncedNotification::GetEntitySpecifics() const {
246 sync_pb::EntitySpecifics entity_specifics;
247 entity_specifics.mutable_synced_notification()->CopyFrom(specifics_);
248 return entity_specifics;
249 }
250
251 // Display the notification if it has the specified app_id_name.
252 void SyncedNotification::ShowAllForAppId(Profile* profile,
253 std::string app_id_name) {
254 if (app_id_name == GetAppId())
255 Show(profile);
256 }
257
258 // Remove the notification if it has the specified app_id_name.
259 void SyncedNotification::HideAllForAppId(std::string app_id_name) {
260 if (app_id_name == GetAppId()) {
261 notification_manager_->CancelById(GetKey());
262 }
263 }
264
265 void SyncedNotification::QueueBitmapFetchJobs(
266 ChromeNotifierService* notifier_service,
267 Profile* profile) {
268 // If we are not using the MessageCenter, call show now, and the existing
269 // code will handle the bitmap fetch for us.
270 if (!UseRichNotifications()) {
271 Show(profile);
272 return;
273 }
274
275 // Save off the arguments for the call to Show.
276 notifier_service_ = notifier_service;
277 profile_ = profile;
278
279 // Ensure our bitmap vector has as many entries as there are buttons,
280 // so that when the bitmaps arrive the vector has a slot for them.
281 for (unsigned int i = 0; i < GetButtonCount(); ++i) {
282 button_bitmaps_.push_back(gfx::Image());
283 button_bitmaps_fetch_pending_.push_back(true);
284 CreateBitmapFetcher(GetButtonIconUrl(i));
285 }
286
287 // If there is a profile image bitmap, fetch it
288 if (GetProfilePictureCount() > 0) {
289 // TODO(petewil): When we have the capacity to display more than one bitmap,
290 // modify this code to fetch as many as we can display
291 CreateBitmapFetcher(GetProfilePictureUrl(0));
292 }
293
294 // If the URL is non-empty, add it to our queue of URLs to fetch.
295 CreateBitmapFetcher(GetAppIconUrl());
296 CreateBitmapFetcher(GetImageUrl());
297
298 // Check to see if we don't need to fetch images, either because we already
299 // did, or because the URLs are empty. If so, we can display the notification.
300
301 // See if all bitmaps are accounted for, if so call Show().
302 if (AreAllBitmapsFetched()) {
303 Show(profile_);
304 }
305 }
306
307 void SyncedNotification::StartBitmapFetch() {
308 // Now that we have queued and counted them all, start the fetching.
309 ScopedVector<chrome::BitmapFetcher>::iterator iter;
310 for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
311 (*iter)->Start(profile_);
312 }
313 }
314
389 // This should detect even small changes in case the server updated the 315 // This should detect even small changes in case the server updated the
390 // notification. We ignore the timestamp if other fields match. 316 // notification. We ignore the timestamp if other fields match.
391 bool SyncedNotification::EqualsIgnoringReadState( 317 bool SyncedNotification::EqualsIgnoringReadState(
392 const SyncedNotification& other) const { 318 const SyncedNotification& other) const {
393 if (GetTitle() == other.GetTitle() && 319 if (GetTitle() == other.GetTitle() &&
394 GetHeading() == other.GetHeading() && 320 GetHeading() == other.GetHeading() &&
395 GetDescription() == other.GetDescription() && 321 GetDescription() == other.GetDescription() &&
396 GetAnnotation() == other.GetAnnotation() && 322 GetAnnotation() == other.GetAnnotation() &&
397 GetAppId() == other.GetAppId() && 323 GetAppId() == other.GetAppId() &&
398 GetKey() == other.GetKey() && 324 GetKey() == other.GetKey() &&
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 return false; 363 return false;
438 } 364 }
439 365
440 // If buttons and notifications matched, they are equivalent. 366 // If buttons and notifications matched, they are equivalent.
441 return true; 367 return true;
442 } 368 }
443 369
444 return false; 370 return false;
445 } 371 }
446 372
447 void SyncedNotification::LogNotification() {
448 std::string readStateString("Unread");
449 if (SyncedNotification::kRead == GetReadState())
450 readStateString = "Read";
451 else if (SyncedNotification::kDismissed == GetReadState())
452 readStateString = "Dismissed";
453
454 DVLOG(2) << " Notification: Heading is " << GetHeading()
455 << " description is " << GetDescription()
456 << " key is " << GetKey()
457 << " read state is " << readStateString;
458 }
459
460 // Set the read state on the notification, returns true for success.
461 void SyncedNotification::SetReadState(const ReadState& read_state) {
462
463 // Convert the read state to the protobuf type for read state.
464 if (kDismissed == read_state)
465 specifics_.mutable_coalesced_notification()->set_read_state(
466 sync_pb::CoalescedSyncedNotification_ReadState_DISMISSED);
467 else if (kUnread == read_state)
468 specifics_.mutable_coalesced_notification()->set_read_state(
469 sync_pb::CoalescedSyncedNotification_ReadState_UNREAD);
470 else if (kRead == read_state)
471 specifics_.mutable_coalesced_notification()->set_read_state(
472 sync_pb::CoalescedSyncedNotification_ReadState_READ);
473 else
474 NOTREACHED();
475 }
476
477 void SyncedNotification::NotificationHasBeenRead() { 373 void SyncedNotification::NotificationHasBeenRead() {
478 SetReadState(kRead); 374 SetReadState(kRead);
479 } 375 }
480 376
481 void SyncedNotification::NotificationHasBeenDismissed() { 377 void SyncedNotification::NotificationHasBeenDismissed() {
482 SetReadState(kDismissed); 378 SetReadState(kDismissed);
483 } 379 }
484 380
485 std::string SyncedNotification::GetTitle() const { 381 std::string SyncedNotification::GetTitle() const {
486 if (!specifics_.coalesced_notification().render_info().expanded_info(). 382 if (!specifics_.coalesced_notification().render_info().expanded_info().
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
620 } else { 516 } else {
621 // Complain if this is a new priority we have not seen before. 517 // Complain if this is a new priority we have not seen before.
622 DCHECK(protobuf_priority < 518 DCHECK(protobuf_priority <
623 sync_pb::CoalescedSyncedNotification_Priority_LOW || 519 sync_pb::CoalescedSyncedNotification_Priority_LOW ||
624 sync_pb::CoalescedSyncedNotification_Priority_HIGH < 520 sync_pb::CoalescedSyncedNotification_Priority_HIGH <
625 protobuf_priority); 521 protobuf_priority);
626 return kUndefinedPriority; 522 return kUndefinedPriority;
627 } 523 }
628 } 524 }
629 525
630 size_t SyncedNotification::GetNotificationCount() const {
631 return specifics_.coalesced_notification().render_info().
632 expanded_info().collapsed_info_size();
633 }
634
635 size_t SyncedNotification::GetButtonCount() const {
636 return specifics_.coalesced_notification().render_info().collapsed_info().
637 target_size();
638 }
639
640 size_t SyncedNotification::GetProfilePictureCount() const {
641 return specifics_.coalesced_notification().render_info().collapsed_info().
642 simple_collapsed_layout().profile_image_size();
643 }
644
645 GURL SyncedNotification::GetProfilePictureUrl(unsigned int which_url) const {
646 if (GetProfilePictureCount() <= which_url)
647 return GURL();
648
649 std::string url_spec = specifics_.coalesced_notification().render_info().
650 collapsed_info().simple_collapsed_layout().profile_image(which_url).
651 image_url();
652
653 return AddDefaultSchemaIfNeeded(url_spec);
654 }
655
656
657 std::string SyncedNotification::GetDefaultDestinationTitle() const { 526 std::string SyncedNotification::GetDefaultDestinationTitle() const {
658 if (!specifics_.coalesced_notification().render_info().collapsed_info(). 527 if (!specifics_.coalesced_notification().render_info().collapsed_info().
659 default_destination().icon().has_alt_text()) { 528 default_destination().icon().has_alt_text()) {
660 return std::string(); 529 return std::string();
661 } 530 }
662 return specifics_.coalesced_notification().render_info().collapsed_info(). 531 return specifics_.coalesced_notification().render_info().collapsed_info().
663 default_destination().icon().alt_text(); 532 default_destination().icon().alt_text();
664 } 533 }
665 534
666 GURL SyncedNotification::GetDefaultDestinationIconUrl() const { 535 GURL SyncedNotification::GetDefaultDestinationIconUrl() const {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
719 if (!specifics_.coalesced_notification().render_info().collapsed_info(). 588 if (!specifics_.coalesced_notification().render_info().collapsed_info().
720 target(which_button).action().has_url()) { 589 target(which_button).action().has_url()) {
721 return GURL(); 590 return GURL();
722 } 591 }
723 std::string url_spec = specifics_.coalesced_notification().render_info(). 592 std::string url_spec = specifics_.coalesced_notification().render_info().
724 collapsed_info().target(which_button).action().url(); 593 collapsed_info().target(which_button).action().url();
725 594
726 return AddDefaultSchemaIfNeeded(url_spec); 595 return AddDefaultSchemaIfNeeded(url_spec);
727 } 596 }
728 597
598 GURL SyncedNotification::GetProfilePictureUrl(unsigned int which_url) const {
599 if (GetProfilePictureCount() <= which_url)
600 return GURL();
601
602 std::string url_spec = specifics_.coalesced_notification().render_info().
603 collapsed_info().simple_collapsed_layout().profile_image(which_url).
604 image_url();
605
606 return AddDefaultSchemaIfNeeded(url_spec);
607 }
608
609 size_t SyncedNotification::GetProfilePictureCount() const {
610 return specifics_.coalesced_notification().render_info().collapsed_info().
611 simple_collapsed_layout().profile_image_size();
612 }
613
614 size_t SyncedNotification::GetNotificationCount() const {
615 return specifics_.coalesced_notification().render_info().
616 expanded_info().collapsed_info_size();
617 }
618
619 size_t SyncedNotification::GetButtonCount() const {
620 return specifics_.coalesced_notification().render_info().collapsed_info().
621 target_size();
622 }
729 std::string SyncedNotification::GetContainedNotificationTitle( 623 std::string SyncedNotification::GetContainedNotificationTitle(
730 int index) const { 624 int index) const {
731 if (specifics_.coalesced_notification().render_info().expanded_info(). 625 if (specifics_.coalesced_notification().render_info().expanded_info().
732 collapsed_info_size() < index + 1) 626 collapsed_info_size() < index + 1)
733 return std::string(); 627 return std::string();
734 628
735 return specifics_.coalesced_notification().render_info().expanded_info(). 629 return specifics_.coalesced_notification().render_info().expanded_info().
736 collapsed_info(index).simple_collapsed_layout().heading(); 630 collapsed_info(index).simple_collapsed_layout().heading();
737 } 631 }
738 632
739 std::string SyncedNotification::GetContainedNotificationMessage( 633 std::string SyncedNotification::GetContainedNotificationMessage(
740 int index) const { 634 int index) const {
741 if (specifics_.coalesced_notification().render_info().expanded_info(). 635 if (specifics_.coalesced_notification().render_info().expanded_info().
742 collapsed_info_size() < index + 1) 636 collapsed_info_size() < index + 1)
743 return std::string(); 637 return std::string();
744 638
745 return specifics_.coalesced_notification().render_info().expanded_info(). 639 return specifics_.coalesced_notification().render_info().expanded_info().
746 collapsed_info(index).simple_collapsed_layout().description(); 640 collapsed_info(index).simple_collapsed_layout().description();
747 } 641 }
748 642
749 std::string SyncedNotification::GetSendingServiceId() const {
750 // TODO(petewil): We are building a new protocol (a new sync datatype) to send
751 // the service name and icon from the server. For now this method is
752 // hardcoded to the name of our first service using synced notifications.
753 // Once the new protocol is built, remove this hardcoding.
754 return kFirstSyncedNotificationServiceId;
755 }
756
757 const gfx::Image& SyncedNotification::GetAppIcon() const { 643 const gfx::Image& SyncedNotification::GetAppIcon() const {
758 return app_icon_bitmap_; 644 return app_icon_bitmap_;
759 } 645 }
760 646
761 void SyncedNotification::SetToastState(bool toast_state) { 647 void SyncedNotification::set_toast_state(bool toast_state) {
762 toast_state_ = toast_state; 648 toast_state_ = toast_state;
763 } 649 }
764 650
651 void SyncedNotification::LogNotification() {
652 std::string readStateString("Unread");
653 if (SyncedNotification::kRead == GetReadState())
654 readStateString = "Read";
655 else if (SyncedNotification::kDismissed == GetReadState())
656 readStateString = "Dismissed";
657
658 DVLOG(2) << " Notification: Heading is " << GetHeading()
659 << " description is " << GetDescription()
660 << " key is " << GetKey()
661 << " read state is " << readStateString;
662 }
663
664 // TODO(petewil): The fetch mechanism appears to be returning two bitmaps on the
665 // mac - perhaps one is regular, one is high dpi? If so, ensure we use the high
666 // dpi bitmap when appropriate.
667 void SyncedNotification::OnFetchComplete(const GURL url,
668 const SkBitmap* bitmap) {
669 // Make sure we are on the thread we expect.
670 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
671
672 gfx::Image downloaded_image;
673 if (bitmap != NULL)
674 downloaded_image = gfx::Image::CreateFrom1xBitmap(*bitmap);
675
676 // Match the incoming bitmaps to URLs. In case this is a dup, make sure to
677 // try all potentially matching urls.
678 if (GetAppIconUrl() == url) {
679 app_icon_bitmap_ = downloaded_image;
680 if (app_icon_bitmap_.IsEmpty())
681 app_icon_bitmap_fetch_pending_ = false;
682 }
683 if (GetImageUrl() == url) {
684 image_bitmap_ = downloaded_image;
685 if (image_bitmap_.IsEmpty())
686 image_bitmap_fetch_pending_ = false;
687 }
688 if (GetProfilePictureUrl(0) == url) {
689 sender_bitmap_ = downloaded_image;
690 if (sender_bitmap_.IsEmpty())
691 sender_bitmap_fetch_pending_ = false;
692 }
693
694 // If this URL matches one or more button bitmaps, save them off.
695 for (unsigned int i = 0; i < GetButtonCount(); ++i) {
696 if (GetButtonIconUrl(i) == url) {
697 if (bitmap != NULL) {
698 button_bitmaps_[i] = gfx::Image::CreateFrom1xBitmap(*bitmap);
699 }
700 button_bitmaps_fetch_pending_[i] = false;
701 }
702 }
703
704 DVLOG(2) << __FUNCTION__ << " popping bitmap " << url;
705
706 // See if all bitmaps are already accounted for, if so call Show.
707 if (AreAllBitmapsFetched()) {
708 Show(profile_);
709 }
710 }
711
712 void SyncedNotification::CreateBitmapFetcher(const GURL& url) {
713 // Check for dups, ignore any request for a dup.
714 ScopedVector<chrome::BitmapFetcher>::iterator iter;
715 for (iter = fetchers_.begin(); iter != fetchers_.end(); ++iter) {
716 if ((*iter)->url() == url)
717 return;
718 }
719
720 if (url.is_valid()) {
721 fetchers_.push_back(new chrome::BitmapFetcher(url, this));
722 DVLOG(2) << __FUNCTION__ << "Pushing bitmap " << url;
723 }
724 }
725
726 // Check that we have either fetched or gotten an error on all the bitmaps we
727 // asked for.
728 bool SyncedNotification::AreAllBitmapsFetched() {
729 bool app_icon_ready = GetAppIconUrl().is_empty() ||
730 !app_icon_bitmap_.IsEmpty() || !app_icon_bitmap_fetch_pending_;
731 bool images_ready = GetImageUrl().is_empty() || !image_bitmap_.IsEmpty() ||
732 !image_bitmap_fetch_pending_;
733 bool sender_picture_ready = GetProfilePictureUrl(0).is_empty() ||
734 !sender_bitmap_.IsEmpty() || !sender_bitmap_fetch_pending_;
735 bool button_bitmaps_ready = true;
736 for (unsigned int j = 0; j < GetButtonCount(); ++j) {
737 if (!GetButtonIconUrl(j).is_empty()
738 && button_bitmaps_[j].IsEmpty()
739 && button_bitmaps_fetch_pending_[j]) {
740 button_bitmaps_ready = false;
741 break;
742 }
743 }
744
745 return app_icon_ready && images_ready && sender_picture_ready &&
746 button_bitmaps_ready;
747 }
748
749 // Set the read state on the notification, returns true for success.
750 void SyncedNotification::SetReadState(const ReadState& read_state) {
751
752 // Convert the read state to the protobuf type for read state.
753 if (kDismissed == read_state)
754 specifics_.mutable_coalesced_notification()->set_read_state(
755 sync_pb::CoalescedSyncedNotification_ReadState_DISMISSED);
756 else if (kUnread == read_state)
757 specifics_.mutable_coalesced_notification()->set_read_state(
758 sync_pb::CoalescedSyncedNotification_ReadState_UNREAD);
759 else if (kRead == read_state)
760 specifics_.mutable_coalesced_notification()->set_read_state(
761 sync_pb::CoalescedSyncedNotification_ReadState_READ);
762 else
763 NOTREACHED();
764 }
765
765 } // namespace notifier 766 } // namespace notifier
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698