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/extensions/api/notifications/notifications_api.h" | 5 #include "chrome/browser/extensions/api/notifications/notifications_api.h" |
| 6 | 6 |
| 7 #include "base/callback.h" | 7 #include "base/callback.h" |
| 8 #include "base/strings/string_number_conversions.h" | 8 #include "base/strings/string_number_conversions.h" |
| 9 #include "base/strings/utf_string_conversions.h" | 9 #include "base/strings/utf_string_conversions.h" |
| 10 #include "base/time/time.h" | 10 #include "base/time/time.h" |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 #include "ui/gfx/image/image_skia_rep.h" | 27 #include "ui/gfx/image/image_skia_rep.h" |
| 28 #include "ui/message_center/message_center_style.h" | 28 #include "ui/message_center/message_center_style.h" |
| 29 #include "ui/message_center/message_center_util.h" | 29 #include "ui/message_center/message_center_util.h" |
| 30 #include "url/gurl.h" | 30 #include "url/gurl.h" |
| 31 | 31 |
| 32 namespace extensions { | 32 namespace extensions { |
| 33 | 33 |
| 34 namespace { | 34 namespace { |
| 35 | 35 |
| 36 const char kResultKey[] = "result"; | 36 const char kResultKey[] = "result"; |
| 37 const char kMissingRequiredPropertiesForCreateNotification[] = | |
| 38 "Some of the required properties are missing: type, iconUrl, title and " | |
| 39 "message."; | |
| 37 const char kUnexpectedProgressValueForNonProgressType[] = | 40 const char kUnexpectedProgressValueForNonProgressType[] = |
| 38 "The progress value should not be specified for non-progress notification"; | 41 "The progress value should not be specified for non-progress notification"; |
| 39 const char kInvalidProgressValue[] = | 42 const char kInvalidProgressValue[] = |
| 40 "The progress value should range from 0 to 100"; | 43 "The progress value should range from 0 to 100"; |
| 41 | 44 |
| 42 // Converts an object with width, height, and data in RGBA format into an | 45 // Converts an object with width, height, and data in RGBA format into an |
| 43 // gfx::Image (in ARGB format). | 46 // gfx::Image (in ARGB format). |
| 44 bool NotificationBitmapToGfxImage( | 47 bool NotificationBitmapToGfxImage( |
| 45 api::notifications::NotificationBitmap* notification_bitmap, | 48 api::notifications::NotificationBitmap* notification_bitmap, |
| 46 gfx::Image* return_image) { | 49 gfx::Image* return_image) { |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 223 | 226 |
| 224 NotificationsApiFunction::NotificationsApiFunction() { | 227 NotificationsApiFunction::NotificationsApiFunction() { |
| 225 } | 228 } |
| 226 | 229 |
| 227 NotificationsApiFunction::~NotificationsApiFunction() { | 230 NotificationsApiFunction::~NotificationsApiFunction() { |
| 228 } | 231 } |
| 229 | 232 |
| 230 bool NotificationsApiFunction::CreateNotification( | 233 bool NotificationsApiFunction::CreateNotification( |
| 231 const std::string& id, | 234 const std::string& id, |
| 232 api::notifications::NotificationOptions* options) { | 235 api::notifications::NotificationOptions* options) { |
| 236 // First, make sure the required fields exist: type, title, message, icon. | |
| 237 // These fields are defined as optional in IDL such that they can be used as | |
| 238 // optional for notification updates. But for notification creations, they | |
| 239 // should be present. | |
| 240 if (options->type == api::notifications::TEMPLATE_TYPE_NONE || | |
| 241 !options->icon_url || !options->title || !options->message) { | |
| 242 SetError(kMissingRequiredPropertiesForCreateNotification); | |
| 243 return false; | |
| 244 } | |
| 233 | 245 |
| 234 // First, extract required fields: type, title, message, and icon. | 246 // Extract required fields: type, title, message, and icon. |
| 235 message_center::NotificationType type = | 247 message_center::NotificationType type = |
| 236 MapApiTemplateTypeToType(options->type); | 248 MapApiTemplateTypeToType(options->type); |
| 237 const string16 title(UTF8ToUTF16(options->title)); | 249 const string16 title(UTF8ToUTF16(*options->title)); |
| 238 const string16 message(UTF8ToUTF16(options->message)); | 250 const string16 message(UTF8ToUTF16(*options->message)); |
| 239 gfx::Image icon; | 251 gfx::Image icon; |
| 240 | 252 |
| 241 // TODO(dewittj): Return error if this fails. | 253 // TODO(dewittj): Return error if this fails. |
| 242 NotificationBitmapToGfxImage(options->icon_bitmap.get(), &icon); | 254 NotificationBitmapToGfxImage(options->icon_bitmap.get(), &icon); |
| 243 | 255 |
| 244 // Then, handle any optional data that's been provided. | 256 // Then, handle any optional data that's been provided. |
| 245 message_center::RichNotificationData optional_fields; | 257 message_center::RichNotificationData optional_fields; |
| 246 if (message_center::IsRichNotificationEnabled()) { | 258 if (message_center::IsRichNotificationEnabled()) { |
| 247 if (options->priority.get()) | 259 if (options->priority.get()) |
| 248 optional_fields.priority = *options->priority; | 260 optional_fields.priority = *options->priority; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 318 WebKit::WebTextDirectionDefault, | 330 WebKit::WebTextDirectionDefault, |
| 319 UTF8ToUTF16(extension_->name()), | 331 UTF8ToUTF16(extension_->name()), |
| 320 UTF8ToUTF16(api_delegate->id()), | 332 UTF8ToUTF16(api_delegate->id()), |
| 321 optional_fields, | 333 optional_fields, |
| 322 api_delegate); | 334 api_delegate); |
| 323 | 335 |
| 324 g_browser_process->notification_ui_manager()->Add(notification, profile()); | 336 g_browser_process->notification_ui_manager()->Add(notification, profile()); |
| 325 return true; | 337 return true; |
| 326 } | 338 } |
| 327 | 339 |
| 340 bool NotificationsApiFunction::UpdateNotification( | |
| 341 const std::string& id, | |
| 342 api::notifications::NotificationOptions* options, | |
| 343 Notification* notification) { | |
| 344 // Update optional fields if provided. | |
| 345 if (options->type != api::notifications::TEMPLATE_TYPE_NONE) | |
| 346 notification->set_type(MapApiTemplateTypeToType(options->type)); | |
| 347 if (options->title) | |
| 348 notification->set_title(UTF8ToUTF16(*options->title)); | |
| 349 if (options->message) | |
| 350 notification->set_message(UTF8ToUTF16(*options->message)); | |
| 351 | |
| 352 // TODO(dewittj): Return error if this fails. | |
| 353 if (options->icon_bitmap) { | |
| 354 gfx::Image icon; | |
| 355 NotificationBitmapToGfxImage(options->icon_bitmap.get(), &icon); | |
| 356 notification->set_icon(icon); | |
| 357 } | |
| 358 | |
| 359 message_center::RichNotificationData optional_fields; | |
| 360 if (message_center::IsRichNotificationEnabled()) { | |
| 361 if (options->priority) | |
| 362 notification->set_priority(*options->priority); | |
| 363 | |
| 364 if (options->event_time) | |
| 365 notification->set_timestamp(base::Time::FromJsTime(*options->event_time)); | |
| 366 | |
| 367 if (options->buttons) { | |
| 368 // Currently we allow up to 2 buttons. | |
| 369 size_t number_of_buttons = options->buttons->size(); | |
| 370 number_of_buttons = number_of_buttons > 2 ? 2 : number_of_buttons; | |
| 371 | |
| 372 for (size_t i = 0; i < number_of_buttons; i++) { | |
| 373 message_center::ButtonInfo info( | |
| 374 UTF8ToUTF16((*options->buttons)[i]->title)); | |
| 375 NotificationBitmapToGfxImage((*options->buttons)[i]->icon_bitmap.get(), | |
| 376 &info.icon); | |
| 377 optional_fields.buttons.push_back(info); | |
| 378 } | |
| 379 } | |
| 380 | |
| 381 if (options->expanded_message) { | |
| 382 notification->set_expanded_message( | |
| 383 UTF8ToUTF16(*options->expanded_message)); | |
| 384 } | |
| 385 | |
| 386 gfx::Image image; | |
| 387 if (NotificationBitmapToGfxImage(options->image_bitmap.get(), &image)) { | |
| 388 // We should have an image if and only if the type is an image type. | |
| 389 if (notification->type() != message_center::NOTIFICATION_TYPE_IMAGE) | |
| 390 return false; | |
| 391 notification->set_image(image); | |
| 392 } | |
| 393 | |
| 394 if (options->progress) { | |
| 395 // We should have progress if and only if the type is a progress type. | |
| 396 if (notification->type() != message_center::NOTIFICATION_TYPE_PROGRESS) { | |
| 397 SetError(kUnexpectedProgressValueForNonProgressType); | |
| 398 return false; | |
| 399 } | |
| 400 int progress = *options->progress; | |
| 401 // Progress value should range from 0 to 100. | |
| 402 if (progress < 0 || progress > 100) { | |
| 403 SetError(kInvalidProgressValue); | |
| 404 return false; | |
| 405 } | |
| 406 notification->set_progress(progress); | |
| 407 } | |
| 408 | |
| 409 if (options->items.get() && options->items->size() > 0) { | |
| 410 // We should have list items if and only if the type is a multiple type. | |
| 411 if (notification->type() != message_center::NOTIFICATION_TYPE_MULTIPLE) | |
| 412 return false; | |
| 413 | |
| 414 std::vector< message_center::NotificationItem> items; | |
| 415 using api::notifications::NotificationItem; | |
| 416 std::vector<linked_ptr<NotificationItem> >::iterator i; | |
| 417 for (i = options->items->begin(); i != options->items->end(); ++i) { | |
| 418 message_center::NotificationItem item(UTF8ToUTF16(i->get()->title), | |
| 419 UTF8ToUTF16(i->get()->message)); | |
| 420 items.push_back(item); | |
| 421 } | |
| 422 notification->set_items(items); | |
| 423 } | |
| 424 } | |
| 425 | |
| 426 g_browser_process->notification_ui_manager()->Add(*notification, profile()); | |
| 427 return true; | |
| 428 } | |
| 429 | |
| 328 bool NotificationsApiFunction::IsNotificationsApiEnabled() { | 430 bool NotificationsApiFunction::IsNotificationsApiEnabled() { |
| 329 DesktopNotificationService* service = | 431 DesktopNotificationService* service = |
| 330 DesktopNotificationServiceFactory::GetForProfile(profile()); | 432 DesktopNotificationServiceFactory::GetForProfile(profile()); |
| 331 return service->IsExtensionEnabled(extension_->id()); | 433 return service->IsExtensionEnabled(extension_->id()); |
| 332 } | 434 } |
| 333 | 435 |
| 334 bool NotificationsApiFunction::RunImpl() { | 436 bool NotificationsApiFunction::RunImpl() { |
| 335 if (IsNotificationsApiAvailable() && IsNotificationsApiEnabled()) { | 437 if (IsNotificationsApiAvailable() && IsNotificationsApiEnabled()) { |
| 336 return RunNotificationsApi(); | 438 return RunNotificationsApi(); |
| 337 } else { | 439 } else { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 402 | 504 |
| 403 NotificationsUpdateFunction::~NotificationsUpdateFunction() { | 505 NotificationsUpdateFunction::~NotificationsUpdateFunction() { |
| 404 } | 506 } |
| 405 | 507 |
| 406 bool NotificationsUpdateFunction::RunNotificationsApi() { | 508 bool NotificationsUpdateFunction::RunNotificationsApi() { |
| 407 params_ = api::notifications::Update::Params::Create(*args_); | 509 params_ = api::notifications::Update::Params::Create(*args_); |
| 408 EXTENSION_FUNCTION_VALIDATE(params_.get()); | 510 EXTENSION_FUNCTION_VALIDATE(params_.get()); |
| 409 | 511 |
| 410 // We are in update. If the ID doesn't exist, succeed but call the callback | 512 // We are in update. If the ID doesn't exist, succeed but call the callback |
| 411 // with "false". | 513 // with "false". |
| 514 Notification notification; | |
| 412 if (!g_browser_process->notification_ui_manager()->DoesIdExist( | 515 if (!g_browser_process->notification_ui_manager()->DoesIdExist( |
| 413 CreateScopedIdentifier(extension_->id(), params_->notification_id))) { | 516 CreateScopedIdentifier(extension_->id(), params_->notification_id), |
| 517 ¬ification)) { | |
| 414 SetResult(Value::CreateBooleanValue(false)); | 518 SetResult(Value::CreateBooleanValue(false)); |
| 415 SendResponse(true); | 519 SendResponse(true); |
| 416 return true; | 520 return true; |
| 417 } | 521 } |
| 418 | 522 |
| 419 // If we have trouble creating the notification (could be improper use of API | 523 // If we have trouble creating the notification (could be improper use of API |
| 420 // or some other reason), mark the function as failed, calling the callback | 524 // or some other reason), mark the function as failed, calling the callback |
| 421 // with false. | 525 // with false. |
| 422 // TODO(dewittj): Add more human-readable error strings if this fails. | 526 // TODO(dewittj): Add more human-readable error strings if this fails. |
| 423 bool could_create_notification = | 527 bool could_create_notification = UpdateNotification( |
|
dewittj
2013/07/24 23:09:53
nit: could_update_notification
jianli
2013/07/25 01:02:41
Done.
| |
| 424 CreateNotification(params_->notification_id, ¶ms_->options); | 528 params_->notification_id, ¶ms_->options, ¬ification); |
| 425 SetResult(Value::CreateBooleanValue(could_create_notification)); | 529 SetResult(Value::CreateBooleanValue(could_create_notification)); |
| 426 if (!could_create_notification) | 530 if (!could_create_notification) |
| 427 return false; | 531 return false; |
| 428 | 532 |
| 429 // No trouble, created the notification, send true to the callback and | 533 // No trouble, created the notification, send true to the callback and |
| 430 // succeed. | 534 // succeed. |
| 431 SendResponse(true); | 535 SendResponse(true); |
| 432 return true; | 536 return true; |
| 433 } | 537 } |
| 434 | 538 |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 470 StripScopeFromIdentifier(extension_->id(), *iter), true); | 574 StripScopeFromIdentifier(extension_->id(), *iter), true); |
| 471 } | 575 } |
| 472 | 576 |
| 473 SetResult(result.release()); | 577 SetResult(result.release()); |
| 474 SendResponse(true); | 578 SendResponse(true); |
| 475 | 579 |
| 476 return true; | 580 return true; |
| 477 } | 581 } |
| 478 | 582 |
| 479 } // namespace extensions | 583 } // namespace extensions |
| OLD | NEW |