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