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

Side by Side Diff: chrome/browser/extensions/api/notifications/notifications_api.cc

Issue 20136004: Allow partial update for notification update API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add more tests per feedback Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/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
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
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
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
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".
412 if (!g_browser_process->notification_ui_manager()->DoesIdExist( 514 const Notification* matched_notification =
413 CreateScopedIdentifier(extension_->id(), params_->notification_id))) { 515 g_browser_process->notification_ui_manager()->FindById(
516 CreateScopedIdentifier(extension_->id(), params_->notification_id));
517 if (!matched_notification) {
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 updating 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 Notification notification = *matched_notification;
424 CreateNotification(params_->notification_id, &params_->options); 528 bool could_update_notification = UpdateNotification(
425 SetResult(Value::CreateBooleanValue(could_create_notification)); 529 params_->notification_id, &params_->options, &notification);
426 if (!could_create_notification) 530 SetResult(Value::CreateBooleanValue(could_update_notification));
531 if (!could_update_notification)
427 return false; 532 return false;
428 533
429 // No trouble, created the notification, send true to the callback and 534 // No trouble, created the notification, send true to the callback and
430 // succeed. 535 // succeed.
431 SendResponse(true); 536 SendResponse(true);
432 return true; 537 return true;
433 } 538 }
434 539
435 NotificationsClearFunction::NotificationsClearFunction() { 540 NotificationsClearFunction::NotificationsClearFunction() {
436 } 541 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
470 StripScopeFromIdentifier(extension_->id(), *iter), true); 575 StripScopeFromIdentifier(extension_->id(), *iter), true);
471 } 576 }
472 577
473 SetResult(result.release()); 578 SetResult(result.release());
474 SendResponse(true); 579 SendResponse(true);
475 580
476 return true; 581 return true;
477 } 582 }
478 583
479 } // namespace extensions 584 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698