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 |