| Index: chrome/browser/extensions/api/notifications/notifications_api.cc
|
| diff --git a/chrome/browser/extensions/api/notifications/notifications_api.cc b/chrome/browser/extensions/api/notifications/notifications_api.cc
|
| index 8dd419765b5e2aee079583e30ae42cba78062ba3..ad3e46f6c82e35b9a7924ba94ff31e9acaec40a0 100644
|
| --- a/chrome/browser/extensions/api/notifications/notifications_api.cc
|
| +++ b/chrome/browser/extensions/api/notifications/notifications_api.cc
|
| @@ -34,6 +34,9 @@ namespace extensions {
|
| namespace {
|
|
|
| const char kResultKey[] = "result";
|
| +const char kMissingRequiredPropertiesForCreateNotification[] =
|
| + "Some of the required properties are missing: type, iconUrl, title and "
|
| + "message.";
|
| const char kUnexpectedProgressValueForNonProgressType[] =
|
| "The progress value should not be specified for non-progress notification";
|
| const char kInvalidProgressValue[] =
|
| @@ -230,12 +233,21 @@ NotificationsApiFunction::~NotificationsApiFunction() {
|
| bool NotificationsApiFunction::CreateNotification(
|
| const std::string& id,
|
| api::notifications::NotificationOptions* options) {
|
| + // First, make sure the required fields exist: type, title, message, icon.
|
| + // These fields are defined as optional in IDL such that they can be used as
|
| + // optional for notification updates. But for notification creations, they
|
| + // should be present.
|
| + if (options->type == api::notifications::TEMPLATE_TYPE_NONE ||
|
| + !options->icon_url || !options->title || !options->message) {
|
| + SetError(kMissingRequiredPropertiesForCreateNotification);
|
| + return false;
|
| + }
|
|
|
| - // First, extract required fields: type, title, message, and icon.
|
| + // Extract required fields: type, title, message, and icon.
|
| message_center::NotificationType type =
|
| MapApiTemplateTypeToType(options->type);
|
| - const string16 title(UTF8ToUTF16(options->title));
|
| - const string16 message(UTF8ToUTF16(options->message));
|
| + const string16 title(UTF8ToUTF16(*options->title));
|
| + const string16 message(UTF8ToUTF16(*options->message));
|
| gfx::Image icon;
|
|
|
| // TODO(dewittj): Return error if this fails.
|
| @@ -325,6 +337,96 @@ bool NotificationsApiFunction::CreateNotification(
|
| return true;
|
| }
|
|
|
| +bool NotificationsApiFunction::UpdateNotification(
|
| + const std::string& id,
|
| + api::notifications::NotificationOptions* options,
|
| + Notification* notification) {
|
| + // Update optional fields if provided.
|
| + if (options->type != api::notifications::TEMPLATE_TYPE_NONE)
|
| + notification->set_type(MapApiTemplateTypeToType(options->type));
|
| + if (options->title)
|
| + notification->set_title(UTF8ToUTF16(*options->title));
|
| + if (options->message)
|
| + notification->set_message(UTF8ToUTF16(*options->message));
|
| +
|
| + // TODO(dewittj): Return error if this fails.
|
| + if (options->icon_bitmap) {
|
| + gfx::Image icon;
|
| + NotificationBitmapToGfxImage(options->icon_bitmap.get(), &icon);
|
| + notification->set_icon(icon);
|
| + }
|
| +
|
| + message_center::RichNotificationData optional_fields;
|
| + if (message_center::IsRichNotificationEnabled()) {
|
| + if (options->priority)
|
| + notification->set_priority(*options->priority);
|
| +
|
| + if (options->event_time)
|
| + notification->set_timestamp(base::Time::FromJsTime(*options->event_time));
|
| +
|
| + if (options->buttons) {
|
| + // Currently we allow up to 2 buttons.
|
| + size_t number_of_buttons = options->buttons->size();
|
| + number_of_buttons = number_of_buttons > 2 ? 2 : number_of_buttons;
|
| +
|
| + for (size_t i = 0; i < number_of_buttons; i++) {
|
| + message_center::ButtonInfo info(
|
| + UTF8ToUTF16((*options->buttons)[i]->title));
|
| + NotificationBitmapToGfxImage((*options->buttons)[i]->icon_bitmap.get(),
|
| + &info.icon);
|
| + optional_fields.buttons.push_back(info);
|
| + }
|
| + }
|
| +
|
| + if (options->expanded_message) {
|
| + notification->set_expanded_message(
|
| + UTF8ToUTF16(*options->expanded_message));
|
| + }
|
| +
|
| + gfx::Image image;
|
| + if (NotificationBitmapToGfxImage(options->image_bitmap.get(), &image)) {
|
| + // We should have an image if and only if the type is an image type.
|
| + if (notification->type() != message_center::NOTIFICATION_TYPE_IMAGE)
|
| + return false;
|
| + notification->set_image(image);
|
| + }
|
| +
|
| + if (options->progress) {
|
| + // We should have progress if and only if the type is a progress type.
|
| + if (notification->type() != message_center::NOTIFICATION_TYPE_PROGRESS) {
|
| + SetError(kUnexpectedProgressValueForNonProgressType);
|
| + return false;
|
| + }
|
| + int progress = *options->progress;
|
| + // Progress value should range from 0 to 100.
|
| + if (progress < 0 || progress > 100) {
|
| + SetError(kInvalidProgressValue);
|
| + return false;
|
| + }
|
| + notification->set_progress(progress);
|
| + }
|
| +
|
| + if (options->items.get() && options->items->size() > 0) {
|
| + // We should have list items if and only if the type is a multiple type.
|
| + if (notification->type() != message_center::NOTIFICATION_TYPE_MULTIPLE)
|
| + return false;
|
| +
|
| + std::vector< message_center::NotificationItem> items;
|
| + using api::notifications::NotificationItem;
|
| + std::vector<linked_ptr<NotificationItem> >::iterator i;
|
| + for (i = options->items->begin(); i != options->items->end(); ++i) {
|
| + message_center::NotificationItem item(UTF8ToUTF16(i->get()->title),
|
| + UTF8ToUTF16(i->get()->message));
|
| + items.push_back(item);
|
| + }
|
| + notification->set_items(items);
|
| + }
|
| + }
|
| +
|
| + g_browser_process->notification_ui_manager()->Add(*notification, profile());
|
| + return true;
|
| +}
|
| +
|
| bool NotificationsApiFunction::IsNotificationsApiEnabled() {
|
| DesktopNotificationService* service =
|
| DesktopNotificationServiceFactory::GetForProfile(profile());
|
| @@ -409,21 +511,24 @@ bool NotificationsUpdateFunction::RunNotificationsApi() {
|
|
|
| // We are in update. If the ID doesn't exist, succeed but call the callback
|
| // with "false".
|
| - if (!g_browser_process->notification_ui_manager()->DoesIdExist(
|
| - CreateScopedIdentifier(extension_->id(), params_->notification_id))) {
|
| + const Notification* matched_notification =
|
| + g_browser_process->notification_ui_manager()->FindById(
|
| + CreateScopedIdentifier(extension_->id(), params_->notification_id));
|
| + if (!matched_notification) {
|
| SetResult(Value::CreateBooleanValue(false));
|
| SendResponse(true);
|
| return true;
|
| }
|
|
|
| - // If we have trouble creating the notification (could be improper use of API
|
| + // If we have trouble updating the notification (could be improper use of API
|
| // or some other reason), mark the function as failed, calling the callback
|
| // with false.
|
| // TODO(dewittj): Add more human-readable error strings if this fails.
|
| - bool could_create_notification =
|
| - CreateNotification(params_->notification_id, ¶ms_->options);
|
| - SetResult(Value::CreateBooleanValue(could_create_notification));
|
| - if (!could_create_notification)
|
| + Notification notification = *matched_notification;
|
| + bool could_update_notification = UpdateNotification(
|
| + params_->notification_id, ¶ms_->options, ¬ification);
|
| + SetResult(Value::CreateBooleanValue(could_update_notification));
|
| + if (!could_update_notification)
|
| return false;
|
|
|
| // No trouble, created the notification, send true to the callback and
|
|
|