Chromium Code Reviews| OLD | NEW |
|---|---|
| 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/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "base/time/time.h" | 9 #include "base/time/time.h" |
| 10 #include "base/values.h" | 10 #include "base/values.h" |
| 11 #include "chrome/browser/browser_process.h" | 11 #include "chrome/browser/browser_process.h" |
| 12 #include "chrome/browser/notifications/notification.h" | 12 #include "chrome/browser/notifications/notification.h" |
| 13 #include "chrome/browser/notifications/notification_ui_manager.h" | 13 #include "chrome/browser/notifications/notification_ui_manager.h" |
| 14 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h" | 14 #include "chrome/browser/notifications/sync_notifier/chrome_notifier_delegate.h" |
| 15 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 16 #include "sync/protocol/sync.pb.h" | 16 #include "sync/protocol/sync.pb.h" |
| 17 #include "sync/protocol/synced_notification_specifics.pb.h" | 17 #include "sync/protocol/synced_notification_specifics.pb.h" |
| 18 #include "ui/gfx/image/image.h" | 18 #include "ui/gfx/image/image.h" |
| 19 #include "ui/message_center/message_center_util.h" | 19 #include "ui/message_center/message_center_util.h" |
| 20 #include "ui/message_center/notification_types.h" | 20 #include "ui/message_center/notification_types.h" |
| 21 | 21 |
| 22 namespace { | 22 namespace { |
| 23 const char kExtensionScheme[] = "chrome-extension://"; | 23 const char kExtensionScheme[] = "chrome-extension://"; |
| 24 const char kDefaultSyncedNotificationScheme[] = "https:"; | |
| 24 | 25 |
| 25 // Today rich notifications only supports two buttons, make sure we don't | 26 // Today rich notifications only supports two buttons, make sure we don't |
| 26 // try to supply them with more than this number of buttons. | 27 // try to supply them with more than this number of buttons. |
| 27 const unsigned int kMaxNotificationButtonIndex = 2; | 28 const unsigned int kMaxNotificationButtonIndex = 2; |
| 28 | 29 |
| 29 bool UseRichNotifications() { | 30 bool UseRichNotifications() { |
| 30 return message_center::IsRichNotificationEnabled(); | 31 return message_center::IsRichNotificationEnabled(); |
| 31 } | 32 } |
| 32 | 33 |
| 34 // Schema-less specs default badly in windows. If we find one, add the schema | |
| 35 // we expect instead of allowing windows specific GURL code to make it default | |
| 36 // to "file:". | |
| 37 std::string AddDefaultSchemaIfNeeded(std::string& url_spec) { | |
|
dewittj
2013/07/19 22:37:19
This function makes me sad. Is there anything else
Pete Williamson
2013/07/19 22:49:07
Yes, I share your sadness for this function. My f
| |
| 38 #ifdef OS_WIN | |
| 39 if (url_spec.length() > 1 && url_spec[0] == '/' && url_spec[1] == '/') | |
| 40 return std::string(kDefaultSyncedNotificationScheme) + url_spec; | |
| 41 #endif // OS_WINDOWS | |
| 42 | |
| 43 return url_spec; | |
| 44 } | |
| 45 | |
| 33 } // namespace | 46 } // namespace |
| 34 | 47 |
| 35 namespace notifier { | 48 namespace notifier { |
| 36 | 49 |
| 37 COMPILE_ASSERT(static_cast<sync_pb::CoalescedSyncedNotification_ReadState>( | 50 COMPILE_ASSERT(static_cast<sync_pb::CoalescedSyncedNotification_ReadState>( |
| 38 SyncedNotification::kUnread) == | 51 SyncedNotification::kUnread) == |
| 39 sync_pb::CoalescedSyncedNotification_ReadState_UNREAD, | 52 sync_pb::CoalescedSyncedNotification_ReadState_UNREAD, |
| 40 local_enum_must_match_protobuf_enum); | 53 local_enum_must_match_protobuf_enum); |
| 41 COMPILE_ASSERT(static_cast<sync_pb::CoalescedSyncedNotification_ReadState>( | 54 COMPILE_ASSERT(static_cast<sync_pb::CoalescedSyncedNotification_ReadState>( |
| 42 SyncedNotification::kRead) == | 55 SyncedNotification::kRead) == |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 69 } | 82 } |
| 70 | 83 |
| 71 void SyncedNotification::OnFetchComplete(const GURL url, | 84 void SyncedNotification::OnFetchComplete(const GURL url, |
| 72 const SkBitmap* bitmap) { | 85 const SkBitmap* bitmap) { |
| 73 // TODO(petewil): Add timeout mechanism in case bitmaps take too long. Do we | 86 // TODO(petewil): Add timeout mechanism in case bitmaps take too long. Do we |
| 74 // already have one built into URLFetcher? | 87 // already have one built into URLFetcher? |
| 75 // Make sure we are on the thread we expect. | 88 // Make sure we are on the thread we expect. |
| 76 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | 89 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); |
| 77 | 90 |
| 78 // Match the incoming bitmaps to URLs. In case this is a dup, make sure to | 91 // Match the incoming bitmaps to URLs. In case this is a dup, make sure to |
| 79 // Try all potentially matching urls. | 92 // try all potentially matching urls. |
| 80 if (GetAppIconUrl() == url && bitmap != NULL) { | 93 if (GetAppIconUrl() == url && bitmap != NULL) { |
| 81 app_icon_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap); | 94 app_icon_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap); |
| 82 } | 95 } |
| 83 if (GetImageUrl() == url && bitmap != NULL) { | 96 if (GetImageUrl() == url && bitmap != NULL) { |
| 84 image_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap); | 97 image_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap); |
| 85 } | 98 } |
| 99 if (GetProfilePictureUrl(0) == url && bitmap != NULL) { | |
| 100 sender_bitmap_ = gfx::Image::CreateFrom1xBitmap(*bitmap); | |
| 101 } | |
| 86 | 102 |
| 87 // If this URL matches one or more button bitmaps, save them off. | 103 // If this URL matches one or more button bitmaps, save them off. |
| 88 for (unsigned int i = 0; i < GetButtonCount(); ++i) { | 104 for (unsigned int i = 0; i < GetButtonCount(); ++i) { |
| 89 if (GetButtonIconUrl(i) == url && bitmap != NULL) | 105 if (GetButtonIconUrl(i) == url && bitmap != NULL) |
| 90 button_bitmaps_[i] = gfx::Image::CreateFrom1xBitmap(*bitmap); | 106 button_bitmaps_[i] = gfx::Image::CreateFrom1xBitmap(*bitmap); |
| 91 } | 107 } |
| 92 | 108 |
| 93 // Count off the bitmaps as they arrive. | 109 // Count off the bitmaps as they arrive. |
| 94 --active_fetcher_count_; | 110 --active_fetcher_count_; |
| 95 DCHECK_GE(active_fetcher_count_, 0); | 111 DCHECK_GE(active_fetcher_count_, 0); |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 116 profile_ = profile; | 132 profile_ = profile; |
| 117 DCHECK_EQ(active_fetcher_count_, 0); | 133 DCHECK_EQ(active_fetcher_count_, 0); |
| 118 | 134 |
| 119 // Ensure our bitmap vector has as many entries as there are buttons, | 135 // Ensure our bitmap vector has as many entries as there are buttons, |
| 120 // so that when the bitmaps arrive the vector has a slot for them. | 136 // so that when the bitmaps arrive the vector has a slot for them. |
| 121 for (unsigned int i = 0; i < GetButtonCount(); ++i) { | 137 for (unsigned int i = 0; i < GetButtonCount(); ++i) { |
| 122 button_bitmaps_.push_back(gfx::Image()); | 138 button_bitmaps_.push_back(gfx::Image()); |
| 123 AddBitmapToFetchQueue(GetButtonIconUrl(i)); | 139 AddBitmapToFetchQueue(GetButtonIconUrl(i)); |
| 124 } | 140 } |
| 125 | 141 |
| 142 // If there is a profile image bitmap, fetch it | |
| 143 if (GetProfilePictureCount() > 0) { | |
| 144 // TODO(petewil): When we have the capacity to display more than one bitmap, | |
| 145 // modify this code to fetch as many as we can display | |
| 146 AddBitmapToFetchQueue(GetProfilePictureUrl(0)); | |
| 147 } | |
| 148 | |
| 126 // If the URL is non-empty, add it to our queue of URLs to fetch. | 149 // If the URL is non-empty, add it to our queue of URLs to fetch. |
| 127 AddBitmapToFetchQueue(GetAppIconUrl()); | 150 AddBitmapToFetchQueue(GetAppIconUrl()); |
| 128 AddBitmapToFetchQueue(GetImageUrl()); | 151 AddBitmapToFetchQueue(GetImageUrl()); |
| 129 | 152 |
| 130 // If there are no bitmaps, call show now. | 153 // If there are no bitmaps, call show now. |
| 131 if (active_fetcher_count_ == 0) { | 154 if (active_fetcher_count_ == 0) { |
| 132 Show(notification_manager, notifier_service, profile); | 155 Show(notification_manager, notifier_service, profile); |
| 133 } | 156 } |
| 134 } | 157 } |
| 135 | 158 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 164 notification_manager->CancelById(GetKey()); | 187 notification_manager->CancelById(GetKey()); |
| 165 DVLOG(2) << "Dismissed notification arrived" | 188 DVLOG(2) << "Dismissed notification arrived" |
| 166 << GetHeading() << " " << GetText(); | 189 << GetHeading() << " " << GetText(); |
| 167 return; | 190 return; |
| 168 } | 191 } |
| 169 | 192 |
| 170 // Set up the fields we need to send and create a Notification object. | 193 // Set up the fields we need to send and create a Notification object. |
| 171 GURL image_url = GetImageUrl(); | 194 GURL image_url = GetImageUrl(); |
| 172 string16 text = UTF8ToUTF16(GetText()); | 195 string16 text = UTF8ToUTF16(GetText()); |
| 173 string16 heading = UTF8ToUTF16(GetHeading()); | 196 string16 heading = UTF8ToUTF16(GetHeading()); |
| 197 string16 description = UTF8ToUTF16(GetDescription()); | |
| 198 string16 annotation = UTF8ToUTF16(GetAnnotation()); | |
| 174 // TODO(petewil): Eventually put the display name of the sending service here. | 199 // TODO(petewil): Eventually put the display name of the sending service here. |
| 175 string16 display_source = UTF8ToUTF16(GetOriginUrl().spec()); | 200 string16 display_source = UTF8ToUTF16(GetOriginUrl().spec()); |
| 176 string16 replace_key = UTF8ToUTF16(GetKey()); | 201 string16 replace_key = UTF8ToUTF16(GetKey()); |
| 202 string16 notification_heading = heading; | |
| 203 string16 notification_text = text; | |
| 177 | 204 |
| 178 // The delegate will eventually catch calls that the notification | 205 // The delegate will eventually catch calls that the notification |
| 179 // was read or deleted, and send the changes back to the server. | 206 // was read or deleted, and send the changes back to the server. |
| 180 scoped_refptr<NotificationDelegate> delegate = | 207 scoped_refptr<NotificationDelegate> delegate = |
| 181 new ChromeNotifierDelegate(GetKey(), notifier_service); | 208 new ChromeNotifierDelegate(GetKey(), notifier_service); |
| 182 | 209 |
| 183 // Some inputs and fields are only used if there is a notification center. | 210 // Some inputs and fields are only used if there is a notification center. |
| 184 if (UseRichNotifications()) { | 211 if (UseRichNotifications()) { |
| 185 base::Time creation_time = | 212 base::Time creation_time = |
| 186 base::Time::FromDoubleT(static_cast<double>(GetCreationTime())); | 213 base::Time::FromDoubleT(static_cast<double>(GetCreationTime())); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 202 // Fill the optional fields with the information we need to make a | 229 // Fill the optional fields with the information we need to make a |
| 203 // notification. | 230 // notification. |
| 204 message_center::RichNotificationData rich_notification_data; | 231 message_center::RichNotificationData rich_notification_data; |
| 205 rich_notification_data.timestamp = creation_time; | 232 rich_notification_data.timestamp = creation_time; |
| 206 if (priority != SyncedNotification::kUndefinedPriority) | 233 if (priority != SyncedNotification::kUndefinedPriority) |
| 207 rich_notification_data.priority = priority; | 234 rich_notification_data.priority = priority; |
| 208 | 235 |
| 209 // Fill in the button data. | 236 // Fill in the button data. |
| 210 // TODO(petewil): Today Rich notifiations are limited to two buttons. | 237 // TODO(petewil): Today Rich notifiations are limited to two buttons. |
| 211 // When rich notifications supports more, remove the | 238 // When rich notifications supports more, remove the |
| 212 // "&& i < kMaxNotificationButtonIndex" below. | 239 // "&& i < kMaxNotificationButtonIndex" clause below. |
| 213 for (unsigned int i = 0; | 240 for (unsigned int i = 0; |
| 214 i < button_count | 241 i < button_count |
| 215 && i < button_bitmaps_.size() | 242 && i < button_bitmaps_.size() |
| 216 && i < kMaxNotificationButtonIndex; | 243 && i < kMaxNotificationButtonIndex; |
| 217 ++i) { | 244 ++i) { |
| 218 // Stop at the first button with no title | 245 // Stop at the first button with no title |
| 219 std::string title = GetButtonTitle(i); | 246 std::string title = GetButtonTitle(i); |
| 220 if (title.empty()) | 247 if (title.empty()) |
| 221 break; | 248 break; |
| 222 message_center::ButtonInfo button_info(UTF8ToUTF16(title)); | 249 message_center::ButtonInfo button_info(UTF8ToUTF16(title)); |
| 223 if (!button_bitmaps_[i].IsEmpty()) | 250 if (!button_bitmaps_[i].IsEmpty()) |
| 224 button_info.icon = button_bitmaps_[i]; | 251 button_info.icon = button_bitmaps_[i]; |
| 225 rich_notification_data.buttons.push_back(button_info); | 252 rich_notification_data.buttons.push_back(button_info); |
| 226 } | 253 } |
| 227 | 254 |
| 228 // Fill in the bitmap images. | 255 // Fill in the bitmap images. |
| 229 if (!image_bitmap_.IsEmpty()) | 256 if (!image_bitmap_.IsEmpty()) |
| 230 rich_notification_data.image = image_bitmap_; | 257 rich_notification_data.image = image_bitmap_; |
| 231 | 258 |
| 232 // Fill the individual notification fields for a multiple notification. | 259 // Fill the individual notification fields for a multiple notification. |
| 233 if (notification_count > 1) { | 260 if (notification_count > 1) { |
| 234 for (int ii = 0; ii < notification_count; ++ii) { | 261 for (int ii = 0; ii < notification_count; ++ii) { |
| 235 message_center::NotificationItem item( | 262 message_center::NotificationItem item( |
| 236 UTF8ToUTF16(GetContainedNotificationTitle(ii)), | 263 UTF8ToUTF16(GetContainedNotificationTitle(ii)), |
| 237 UTF8ToUTF16(GetContainedNotificationMessage(ii))); | 264 UTF8ToUTF16(GetContainedNotificationMessage(ii))); |
| 238 rich_notification_data.items.push_back(item); | 265 rich_notification_data.items.push_back(item); |
| 239 } | 266 } |
| 240 } | 267 } |
| 241 | 268 |
| 269 // Set the heading and text appropriately for the message type. | |
| 270 notification_text = annotation; | |
| 271 if (notification_type == message_center::NOTIFICATION_TYPE_IMAGE) { | |
| 272 // For an image, fill in the description field. | |
| 273 notification_text = description; | |
| 274 } else if (notification_count == 1) { | |
| 275 // For a single collapsed info entry, use the contained message if any. | |
| 276 std::string comment_body = GetContainedNotificationMessage(0); | |
| 277 std::string comment_header = GetContainedNotificationTitle(0); | |
| 278 if (!comment_header.empty() && !comment_body.empty()) | |
| 279 notification_text = UTF8ToUTF16(comment_header) + UTF8ToUTF16(" ") + | |
| 280 UTF8ToUTF16(comment_body); | |
| 281 } | |
| 282 | |
| 283 // If there is a single person sending, use their picture instead of the app | |
| 284 // icon. | |
| 285 // TODO(petewil): Someday combine multiple profile photos here. | |
| 286 gfx::Image icon_bitmap = app_icon_bitmap_; | |
| 287 if (GetProfilePictureCount() == 1) { | |
| 288 icon_bitmap = sender_bitmap_; | |
| 289 } | |
| 290 | |
| 242 Notification ui_notification(notification_type, | 291 Notification ui_notification(notification_type, |
| 243 GetOriginUrl(), | 292 GetOriginUrl(), |
| 244 heading, | 293 notification_heading, |
| 245 text, | 294 notification_text, |
| 246 app_icon_bitmap_, | 295 icon_bitmap, |
| 247 WebKit::WebTextDirectionDefault, | 296 WebKit::WebTextDirectionDefault, |
| 248 display_source, | 297 display_source, |
| 249 replace_key, | 298 replace_key, |
| 250 rich_notification_data, | 299 rich_notification_data, |
| 251 delegate.get()); | 300 delegate.get()); |
| 252 notification_manager->Add(ui_notification, profile); | 301 notification_manager->Add(ui_notification, profile); |
| 253 } else { | 302 } else { |
| 254 | 303 // In this case we have a Webkit Notification, not a Rich Notification. |
| 255 Notification ui_notification(GetOriginUrl(), | 304 Notification ui_notification(GetOriginUrl(), |
| 256 GetAppIconUrl(), | 305 GetAppIconUrl(), |
| 257 heading, | 306 notification_heading, |
| 258 text, | 307 notification_text, |
| 259 WebKit::WebTextDirectionDefault, | 308 WebKit::WebTextDirectionDefault, |
| 260 display_source, | 309 display_source, |
| 261 replace_key, | 310 replace_key, |
| 262 delegate.get()); | 311 delegate.get()); |
| 263 | 312 |
| 264 notification_manager->Add(ui_notification, profile); | 313 notification_manager->Add(ui_notification, profile); |
| 265 } | 314 } |
| 266 | 315 |
| 267 DVLOG(1) << "Showing Synced Notification! " << heading << " " << text | 316 DVLOG(1) << "Showing Synced Notification! " << heading << " " << text |
| 268 << " " << GetAppIconUrl() << " " << replace_key << " " | 317 << " " << GetAppIconUrl() << " " << replace_key << " " |
| 269 << GetReadState(); | 318 << GetReadState(); |
| 270 | 319 |
| 271 return; | 320 return; |
| 272 } | 321 } |
| 273 | 322 |
| 274 // This should detect even small changes in case the server updated the | 323 // This should detect even small changes in case the server updated the |
| 275 // notification. | 324 // notification. We ignore the timestamp if other fields match. |
| 276 // TODO(petewil): Should I also ignore the timestamp if other fields match? | |
| 277 bool SyncedNotification::EqualsIgnoringReadState( | 325 bool SyncedNotification::EqualsIgnoringReadState( |
| 278 const SyncedNotification& other) const { | 326 const SyncedNotification& other) const { |
| 279 if (GetTitle() == other.GetTitle() && | 327 if (GetTitle() == other.GetTitle() && |
| 280 GetHeading() == other.GetHeading() && | 328 GetHeading() == other.GetHeading() && |
| 281 GetDescription() == other.GetDescription() && | 329 GetDescription() == other.GetDescription() && |
| 330 GetAnnotation() == other.GetAnnotation() && | |
| 282 GetAppId() == other.GetAppId() && | 331 GetAppId() == other.GetAppId() && |
| 283 GetKey() == other.GetKey() && | 332 GetKey() == other.GetKey() && |
| 284 GetOriginUrl() == other.GetOriginUrl() && | 333 GetOriginUrl() == other.GetOriginUrl() && |
| 285 GetAppIconUrl() == other.GetAppIconUrl() && | 334 GetAppIconUrl() == other.GetAppIconUrl() && |
| 286 GetImageUrl() == other.GetImageUrl() && | 335 GetImageUrl() == other.GetImageUrl() && |
| 287 GetText() == other.GetText() && | 336 GetText() == other.GetText() && |
| 288 // We intentionally skip read state | 337 // We intentionally skip read state |
| 289 GetCreationTime() == other.GetCreationTime() && | 338 GetCreationTime() == other.GetCreationTime() && |
| 290 GetPriority() == other.GetPriority() && | 339 GetPriority() == other.GetPriority() && |
| 291 GetDefaultDestinationTitle() == other.GetDefaultDestinationTitle() && | 340 GetDefaultDestinationTitle() == other.GetDefaultDestinationTitle() && |
| 292 GetDefaultDestinationIconUrl() == other.GetDefaultDestinationIconUrl() && | 341 GetDefaultDestinationIconUrl() == other.GetDefaultDestinationIconUrl() && |
| 293 GetNotificationCount() == other.GetNotificationCount() && | 342 GetNotificationCount() == other.GetNotificationCount() && |
| 294 GetButtonCount() == other.GetButtonCount()) { | 343 GetButtonCount() == other.GetButtonCount() && |
| 344 GetProfilePictureCount() == other.GetProfilePictureCount()) { | |
| 295 | 345 |
| 296 // If all the surface data matched, check, to see if contained data also | 346 // If all the surface data matched, check, to see if contained data also |
| 297 // matches, titles and messages. | 347 // matches, titles and messages. |
| 298 size_t count = GetNotificationCount(); | 348 size_t count = GetNotificationCount(); |
| 299 for (size_t ii = 0; ii < count; ++ii) { | 349 for (size_t ii = 0; ii < count; ++ii) { |
| 300 if (GetContainedNotificationTitle(ii) != | 350 if (GetContainedNotificationTitle(ii) != |
| 301 other.GetContainedNotificationTitle(ii)) | 351 other.GetContainedNotificationTitle(ii)) |
| 302 return false; | 352 return false; |
| 303 if (GetContainedNotificationMessage(ii) != | 353 if (GetContainedNotificationMessage(ii) != |
| 304 other.GetContainedNotificationMessage(ii)) | 354 other.GetContainedNotificationMessage(ii)) |
| 305 return false; | 355 return false; |
| 306 } | 356 } |
| 307 | 357 |
| 308 // Make sure buttons match. | 358 // Make sure buttons match. |
| 309 count = GetButtonCount(); | 359 count = GetButtonCount(); |
| 310 for (size_t jj = 0; jj < count; ++jj) { | 360 for (size_t jj = 0; jj < count; ++jj) { |
| 311 if (GetButtonTitle(jj) != other.GetButtonTitle(jj)) | 361 if (GetButtonTitle(jj) != other.GetButtonTitle(jj)) |
| 312 return false; | 362 return false; |
| 313 if (GetButtonIconUrl(jj) != other.GetButtonIconUrl(jj)) | 363 if (GetButtonIconUrl(jj) != other.GetButtonIconUrl(jj)) |
| 314 return false; | 364 return false; |
| 315 } | 365 } |
| 316 | 366 |
| 367 // Make sure profile icons match | |
| 368 count = GetButtonCount(); | |
| 369 for (size_t kk = 0; kk < count; ++kk) { | |
| 370 if (GetProfilePictureUrl(kk) != other.GetProfilePictureUrl(kk)) | |
| 371 return false; | |
| 372 } | |
| 373 | |
| 317 // If buttons and notifications matched, they are equivalent. | 374 // If buttons and notifications matched, they are equivalent. |
| 318 return true; | 375 return true; |
| 319 } | 376 } |
| 320 | 377 |
| 321 return false; | 378 return false; |
| 322 } | 379 } |
| 323 | 380 |
| 324 // Set the read state on the notification, returns true for success. | 381 // Set the read state on the notification, returns true for success. |
| 325 void SyncedNotification::SetReadState(const ReadState& read_state) { | 382 void SyncedNotification::SetReadState(const ReadState& read_state) { |
| 326 | 383 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 362 | 419 |
| 363 std::string SyncedNotification::GetDescription() const { | 420 std::string SyncedNotification::GetDescription() const { |
| 364 if (!specifics_.coalesced_notification().render_info().collapsed_info(). | 421 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 365 simple_collapsed_layout().has_description()) | 422 simple_collapsed_layout().has_description()) |
| 366 return std::string(); | 423 return std::string(); |
| 367 | 424 |
| 368 return specifics_.coalesced_notification().render_info().collapsed_info(). | 425 return specifics_.coalesced_notification().render_info().collapsed_info(). |
| 369 simple_collapsed_layout().description(); | 426 simple_collapsed_layout().description(); |
| 370 } | 427 } |
| 371 | 428 |
| 429 std::string SyncedNotification::GetAnnotation() const { | |
| 430 if (!specifics_.coalesced_notification().render_info().collapsed_info(). | |
| 431 simple_collapsed_layout().has_annotation()) | |
| 432 return std::string(); | |
| 433 | |
| 434 return specifics_.coalesced_notification().render_info().collapsed_info(). | |
| 435 simple_collapsed_layout().annotation(); | |
| 436 } | |
| 437 | |
| 372 std::string SyncedNotification::GetAppId() const { | 438 std::string SyncedNotification::GetAppId() const { |
| 373 if (!specifics_.coalesced_notification().has_app_id()) | 439 if (!specifics_.coalesced_notification().has_app_id()) |
| 374 return std::string(); | 440 return std::string(); |
| 375 return specifics_.coalesced_notification().app_id(); | 441 return specifics_.coalesced_notification().app_id(); |
| 376 } | 442 } |
| 377 | 443 |
| 378 std::string SyncedNotification::GetKey() const { | 444 std::string SyncedNotification::GetKey() const { |
| 379 if (!specifics_.coalesced_notification().has_key()) | 445 if (!specifics_.coalesced_notification().has_key()) |
| 380 return std::string(); | 446 return std::string(); |
| 381 return specifics_.coalesced_notification().key(); | 447 return specifics_.coalesced_notification().key(); |
| 382 } | 448 } |
| 383 | 449 |
| 384 GURL SyncedNotification::GetOriginUrl() const { | 450 GURL SyncedNotification::GetOriginUrl() const { |
| 385 std::string origin_url(kExtensionScheme); | 451 std::string origin_url(kExtensionScheme); |
| 386 origin_url += GetAppId(); | 452 origin_url += GetAppId(); |
| 387 return GURL(origin_url); | 453 return GURL(origin_url); |
| 388 } | 454 } |
| 389 | 455 |
| 390 // TODO(petewil): This only returns the first icon. Make all the icons | |
| 391 // available. | |
| 392 GURL SyncedNotification::GetAppIconUrl() const { | 456 GURL SyncedNotification::GetAppIconUrl() const { |
| 393 if (specifics_.coalesced_notification().render_info().expanded_info(). | 457 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 394 collapsed_info_size() == 0) | 458 simple_collapsed_layout().has_app_icon()) |
| 395 return GURL(); | 459 return GURL(); |
| 396 | 460 |
| 397 if (!specifics_.coalesced_notification().render_info().expanded_info(). | 461 std::string url_spec = specifics_.coalesced_notification().render_info(). |
| 398 collapsed_info(0).simple_collapsed_layout().has_app_icon()) | 462 collapsed_info().simple_collapsed_layout().app_icon().url(); |
| 463 | |
| 464 url_spec = AddDefaultSchemaIfNeeded(url_spec); | |
| 465 | |
| 466 return GURL(url_spec); | |
| 467 } | |
| 468 | |
| 469 // TODO(petewil): This ignores all but the first image. If Rich Notifications | |
| 470 // supports more images someday, then fetch all images. | |
| 471 GURL SyncedNotification::GetImageUrl() const { | |
| 472 if (specifics_.coalesced_notification().render_info().collapsed_info(). | |
| 473 simple_collapsed_layout().media_size() == 0) | |
| 399 return GURL(); | 474 return GURL(); |
| 400 | 475 |
| 401 return GURL(specifics_.coalesced_notification().render_info(). | 476 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 402 expanded_info().collapsed_info(0).simple_collapsed_layout(). | 477 simple_collapsed_layout().media(0).image().has_url()) |
| 403 app_icon().url()); | |
| 404 } | |
| 405 | |
| 406 // TODO(petewil): This currenly only handles the first image from the first | |
| 407 // collapsed item, someday return all images. | |
| 408 GURL SyncedNotification::GetImageUrl() const { | |
| 409 if (specifics_.coalesced_notification().render_info().expanded_info(). | |
| 410 simple_expanded_layout().media_size() == 0) | |
| 411 return GURL(); | 478 return GURL(); |
| 412 | 479 |
| 413 if (!specifics_.coalesced_notification().render_info().expanded_info(). | 480 std::string url_spec = specifics_.coalesced_notification().render_info(). |
| 414 simple_expanded_layout().media(0).image().has_url()) | 481 collapsed_info().simple_collapsed_layout().media(0).image().url(); |
| 415 return GURL(); | |
| 416 | 482 |
| 417 return GURL(specifics_.coalesced_notification().render_info(). | 483 url_spec = AddDefaultSchemaIfNeeded(url_spec); |
| 418 expanded_info().simple_expanded_layout().media(0).image().url()); | 484 |
| 485 return GURL(url_spec); | |
| 419 } | 486 } |
| 420 | 487 |
| 421 std::string SyncedNotification::GetText() const { | 488 std::string SyncedNotification::GetText() const { |
| 422 if (!specifics_.coalesced_notification().render_info().expanded_info(). | 489 if (!specifics_.coalesced_notification().render_info().expanded_info(). |
| 423 simple_expanded_layout().has_text()) | 490 simple_expanded_layout().has_text()) |
| 424 return std::string(); | 491 return std::string(); |
| 425 | 492 |
| 426 return specifics_.coalesced_notification().render_info().expanded_info(). | 493 return specifics_.coalesced_notification().render_info().expanded_info(). |
| 427 simple_expanded_layout().text(); | 494 simple_expanded_layout().text(); |
| 428 } | 495 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 484 size_t SyncedNotification::GetNotificationCount() const { | 551 size_t SyncedNotification::GetNotificationCount() const { |
| 485 return specifics_.coalesced_notification().render_info(). | 552 return specifics_.coalesced_notification().render_info(). |
| 486 expanded_info().collapsed_info_size(); | 553 expanded_info().collapsed_info_size(); |
| 487 } | 554 } |
| 488 | 555 |
| 489 size_t SyncedNotification::GetButtonCount() const { | 556 size_t SyncedNotification::GetButtonCount() const { |
| 490 return specifics_.coalesced_notification().render_info().collapsed_info(). | 557 return specifics_.coalesced_notification().render_info().collapsed_info(). |
| 491 target_size(); | 558 target_size(); |
| 492 } | 559 } |
| 493 | 560 |
| 561 size_t SyncedNotification::GetProfilePictureCount() const { | |
| 562 return specifics_.coalesced_notification().render_info().collapsed_info(). | |
| 563 simple_collapsed_layout().profile_image_size(); | |
| 564 } | |
| 565 | |
| 566 GURL SyncedNotification::GetProfilePictureUrl(unsigned int which_url) const { | |
| 567 if (GetProfilePictureCount() <= which_url) | |
| 568 return GURL(); | |
| 569 | |
| 570 std::string url_spec = specifics_.coalesced_notification().render_info(). | |
| 571 collapsed_info().simple_collapsed_layout().profile_image(which_url). | |
| 572 image_url(); | |
| 573 | |
| 574 url_spec = AddDefaultSchemaIfNeeded(url_spec); | |
| 575 | |
| 576 return GURL(url_spec); | |
| 577 } | |
| 578 | |
| 579 | |
| 494 std::string SyncedNotification::GetDefaultDestinationTitle() const { | 580 std::string SyncedNotification::GetDefaultDestinationTitle() const { |
| 495 if (!specifics_.coalesced_notification().render_info().collapsed_info(). | 581 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 496 default_destination().icon().has_alt_text()) { | 582 default_destination().icon().has_alt_text()) { |
| 497 return std::string(); | 583 return std::string(); |
| 498 } | 584 } |
| 499 return specifics_.coalesced_notification().render_info().collapsed_info(). | 585 return specifics_.coalesced_notification().render_info().collapsed_info(). |
| 500 default_destination().icon().alt_text(); | 586 default_destination().icon().alt_text(); |
| 501 } | 587 } |
| 502 | 588 |
| 503 GURL SyncedNotification::GetDefaultDestinationIconUrl() const { | 589 GURL SyncedNotification::GetDefaultDestinationIconUrl() const { |
| 504 if (!specifics_.coalesced_notification().render_info().collapsed_info(). | 590 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 505 default_destination().icon().has_url()) { | 591 default_destination().icon().has_url()) { |
| 506 return GURL(); | 592 return GURL(); |
| 507 } | 593 } |
| 508 return GURL(specifics_.coalesced_notification().render_info(). | 594 std::string url_spec = specifics_.coalesced_notification().render_info(). |
| 509 collapsed_info().default_destination().icon().url()); | 595 collapsed_info().default_destination().icon().url(); |
| 596 | |
| 597 url_spec = AddDefaultSchemaIfNeeded(url_spec); | |
| 598 | |
| 599 return GURL(url_spec); | |
| 510 } | 600 } |
| 511 | 601 |
| 512 GURL SyncedNotification::GetDefaultDestinationUrl() const { | 602 GURL SyncedNotification::GetDefaultDestinationUrl() const { |
| 513 if (!specifics_.coalesced_notification().render_info().collapsed_info(). | 603 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 514 default_destination().has_url()) { | 604 default_destination().has_url()) { |
| 515 return GURL(); | 605 return GURL(); |
| 516 } | 606 } |
| 517 return GURL(specifics_.coalesced_notification().render_info(). | 607 std::string url_spec = specifics_.coalesced_notification().render_info(). |
| 518 collapsed_info().default_destination().url()); | 608 collapsed_info().default_destination().url(); |
| 609 | |
| 610 url_spec = AddDefaultSchemaIfNeeded(url_spec); | |
| 611 | |
| 612 return GURL(url_spec); | |
| 519 } | 613 } |
| 520 | 614 |
| 521 std::string SyncedNotification::GetButtonTitle( | 615 std::string SyncedNotification::GetButtonTitle( |
| 522 unsigned int which_button) const { | 616 unsigned int which_button) const { |
| 523 // Must ensure that we have a target before trying to access it. | 617 // Must ensure that we have a target before trying to access it. |
| 524 if (GetButtonCount() <= which_button) | 618 if (GetButtonCount() <= which_button) |
| 525 return std::string(); | 619 return std::string(); |
| 526 if (!specifics_.coalesced_notification().render_info().collapsed_info(). | 620 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 527 target(which_button).action().icon().has_alt_text()) { | 621 target(which_button).action().icon().has_alt_text()) { |
| 528 return std::string(); | 622 return std::string(); |
| 529 } | 623 } |
| 530 return specifics_.coalesced_notification().render_info().collapsed_info(). | 624 return specifics_.coalesced_notification().render_info().collapsed_info(). |
| 531 target(which_button).action().icon().alt_text(); | 625 target(which_button).action().icon().alt_text(); |
| 532 } | 626 } |
| 533 | 627 |
| 534 GURL SyncedNotification::GetButtonIconUrl(unsigned int which_button) const { | 628 GURL SyncedNotification::GetButtonIconUrl(unsigned int which_button) const { |
| 535 // Must ensure that we have a target before trying to access it. | 629 // Must ensure that we have a target before trying to access it. |
| 536 if (GetButtonCount() <= which_button) | 630 if (GetButtonCount() <= which_button) |
| 537 return GURL(); | 631 return GURL(); |
| 538 if (!specifics_.coalesced_notification().render_info().collapsed_info(). | 632 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 539 target(which_button).action().icon().has_url()) { | 633 target(which_button).action().icon().has_url()) { |
| 540 return GURL(); | 634 return GURL(); |
| 541 } | 635 } |
| 542 return GURL(specifics_.coalesced_notification().render_info(). | 636 std::string url_spec = specifics_.coalesced_notification().render_info(). |
| 543 collapsed_info().target(which_button).action().icon().url()); | 637 collapsed_info().target(which_button).action().icon().url(); |
| 638 | |
| 639 url_spec = AddDefaultSchemaIfNeeded(url_spec); | |
| 640 | |
| 641 return GURL(url_spec); | |
| 544 } | 642 } |
| 545 | 643 |
| 546 GURL SyncedNotification::GetButtonUrl(unsigned int which_button) const { | 644 GURL SyncedNotification::GetButtonUrl(unsigned int which_button) const { |
| 547 // Must ensure that we have a target before trying to access it. | 645 // Must ensure that we have a target before trying to access it. |
| 548 if (GetButtonCount() <= which_button) | 646 if (GetButtonCount() <= which_button) |
| 549 return GURL(); | 647 return GURL(); |
| 550 if (!specifics_.coalesced_notification().render_info().collapsed_info(). | 648 if (!specifics_.coalesced_notification().render_info().collapsed_info(). |
| 551 target(which_button).action().has_url()) { | 649 target(which_button).action().has_url()) { |
| 552 return GURL(); | 650 return GURL(); |
| 553 } | 651 } |
| 554 return GURL(specifics_.coalesced_notification().render_info(). | 652 std::string url_spec = specifics_.coalesced_notification().render_info(). |
| 555 collapsed_info().target(which_button).action().url()); | 653 collapsed_info().target(which_button).action().url(); |
| 654 | |
| 655 url_spec = AddDefaultSchemaIfNeeded(url_spec); | |
| 656 | |
| 657 return GURL(url_spec); | |
| 556 } | 658 } |
| 557 | 659 |
| 558 std::string SyncedNotification::GetContainedNotificationTitle( | 660 std::string SyncedNotification::GetContainedNotificationTitle( |
| 559 int index) const { | 661 int index) const { |
| 560 if (specifics_.coalesced_notification().render_info().expanded_info(). | 662 if (specifics_.coalesced_notification().render_info().expanded_info(). |
| 561 collapsed_info_size() < index + 1) | 663 collapsed_info_size() < index + 1) |
| 562 return std::string(); | 664 return std::string(); |
| 563 | 665 |
| 564 return specifics_.coalesced_notification().render_info().expanded_info(). | 666 return specifics_.coalesced_notification().render_info().expanded_info(). |
| 565 collapsed_info(index).simple_collapsed_layout().heading(); | 667 collapsed_info(index).simple_collapsed_layout().heading(); |
| 566 } | 668 } |
| 567 | 669 |
| 568 std::string SyncedNotification::GetContainedNotificationMessage( | 670 std::string SyncedNotification::GetContainedNotificationMessage( |
| 569 int index) const { | 671 int index) const { |
| 570 if (specifics_.coalesced_notification().render_info().expanded_info(). | 672 if (specifics_.coalesced_notification().render_info().expanded_info(). |
| 571 collapsed_info_size() < index + 1) | 673 collapsed_info_size() < index + 1) |
| 572 return std::string(); | 674 return std::string(); |
| 573 | 675 |
| 574 return specifics_.coalesced_notification().render_info().expanded_info(). | 676 return specifics_.coalesced_notification().render_info().expanded_info(). |
| 575 collapsed_info(index).simple_collapsed_layout().description(); | 677 collapsed_info(index).simple_collapsed_layout().description(); |
| 576 } | 678 } |
| 577 | 679 |
| 578 } // namespace notifier | 680 } // namespace notifier |
| OLD | NEW |