| 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 <stddef.h> | 7 #include <stddef.h> |
| 8 | 8 |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/callback.h" | 11 #include "base/callback.h" |
| 12 #include "base/feature_list.h" | 12 #include "base/feature_list.h" |
| 13 #include "base/guid.h" | 13 #include "base/guid.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/memory/ptr_util.h" | 15 #include "base/memory/ptr_util.h" |
| 16 #include "base/metrics/histogram_macros.h" | 16 #include "base/metrics/histogram_macros.h" |
| 17 #include "base/rand_util.h" | 17 #include "base/rand_util.h" |
| 18 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 19 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 21 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 22 #include "chrome/browser/extensions/api/notifications/extension_notification_dis
play_helper.h" | 22 #include "chrome/browser/extensions/api/notifications/extension_notification_dis
play_helper.h" |
| 23 #include "chrome/browser/extensions/api/notifications/extension_notification_dis
play_helper_factory.h" | 23 #include "chrome/browser/extensions/api/notifications/extension_notification_dis
play_helper_factory.h" |
| 24 #include "chrome/browser/notifications/notification.h" | 24 #include "chrome/browser/notifications/notification.h" |
| 25 #include "chrome/browser/notifications/notifier_state_tracker.h" | 25 #include "chrome/browser/notifications/notifier_state_tracker.h" |
| 26 #include "chrome/browser/notifications/notifier_state_tracker_factory.h" | 26 #include "chrome/browser/notifications/notifier_state_tracker_factory.h" |
| 27 #include "chrome/browser/profiles/profile.h" | 27 #include "chrome/browser/profiles/profile.h" |
| 28 #include "chrome/common/chrome_features.h" |
| 28 #include "chrome/common/extensions/api/notifications/notification_style.h" | 29 #include "chrome/common/extensions/api/notifications/notification_style.h" |
| 30 #include "chrome/common/features.h" |
| 29 #include "components/keyed_service/content/browser_context_keyed_service_shutdow
n_notifier_factory.h" | 31 #include "components/keyed_service/content/browser_context_keyed_service_shutdow
n_notifier_factory.h" |
| 30 #include "components/keyed_service/core/keyed_service_shutdown_notifier.h" | 32 #include "components/keyed_service/core/keyed_service_shutdown_notifier.h" |
| 31 #include "content/public/browser/render_process_host.h" | 33 #include "content/public/browser/render_process_host.h" |
| 32 #include "content/public/browser/render_view_host.h" | 34 #include "content/public/browser/render_view_host.h" |
| 33 #include "content/public/browser/web_contents.h" | 35 #include "content/public/browser/web_contents.h" |
| 34 #include "extensions/browser/app_window/app_window.h" | 36 #include "extensions/browser/app_window/app_window.h" |
| 35 #include "extensions/browser/app_window/app_window_registry.h" | 37 #include "extensions/browser/app_window/app_window_registry.h" |
| 36 #include "extensions/browser/app_window/native_app_window.h" | 38 #include "extensions/browser/app_window/native_app_window.h" |
| 37 #include "extensions/browser/event_router.h" | 39 #include "extensions/browser/event_router.h" |
| 38 #include "extensions/browser/extension_system_provider.h" | 40 #include "extensions/browser/extension_system_provider.h" |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 197 ShutdownNotifierFactory() | 199 ShutdownNotifierFactory() |
| 198 : BrowserContextKeyedServiceShutdownNotifierFactory( | 200 : BrowserContextKeyedServiceShutdownNotifierFactory( |
| 199 "NotificationsApiDelegate") { | 201 "NotificationsApiDelegate") { |
| 200 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); | 202 DependsOn(ExtensionsBrowserClient::Get()->GetExtensionSystemFactory()); |
| 201 } | 203 } |
| 202 ~ShutdownNotifierFactory() override {} | 204 ~ShutdownNotifierFactory() override {} |
| 203 | 205 |
| 204 DISALLOW_COPY_AND_ASSIGN(ShutdownNotifierFactory); | 206 DISALLOW_COPY_AND_ASSIGN(ShutdownNotifierFactory); |
| 205 }; | 207 }; |
| 206 | 208 |
| 207 class NotificationsApiDelegate : public NotificationDelegate { | 209 // Temporary native notification api delagate, it is only used |
| 210 // to extract the delegate id. |
| 211 // This is an interim state until the work in |
| 212 // https://bugs.chromium.org/p/chromium/issues/detail?id=720345 |
| 213 // is completed. We need a small delegate shim since the |
| 214 // Notification object has a non virtual method (delegate_id) that is |
| 215 // used all over the place whose implementation returns delegate->id() |
| 216 #if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) |
| 217 class NativeNotificationApiDelegate : public NotificationDelegate { |
| 208 public: | 218 public: |
| 209 NotificationsApiDelegate(ChromeAsyncExtensionFunction* api_function, | 219 NativeNotificationApiDelegate(const std::string& extension_id, |
| 210 Profile* profile, | 220 const std::string& notification_id) |
| 211 const std::string& extension_id, | 221 : scoped_notification_id_( |
| 212 const std::string& id) | 222 CreateScopedIdentifier(extension_id, notification_id)) {} |
| 223 |
| 224 std::string id() const override { return scoped_notification_id_; } |
| 225 |
| 226 private: |
| 227 ~NativeNotificationApiDelegate() override = default; |
| 228 const std::string scoped_notification_id_; |
| 229 |
| 230 DISALLOW_COPY_AND_ASSIGN(NativeNotificationApiDelegate); |
| 231 }; |
| 232 #endif // BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) |
| 233 |
| 234 // Message center based notification delegate with all the functionality. |
| 235 class NotificationApiDelegate : public NotificationDelegate { |
| 236 public: |
| 237 NotificationApiDelegate(ChromeAsyncExtensionFunction* api_function, |
| 238 Profile* profile, |
| 239 const std::string& extension_id, |
| 240 const std::string& id) |
| 213 : api_function_(api_function), | 241 : api_function_(api_function), |
| 214 event_router_(EventRouter::Get(profile)), | 242 event_router_(EventRouter::Get(profile)), |
| 215 display_helper_( | 243 display_helper_( |
| 216 ExtensionNotificationDisplayHelperFactory::GetForProfile(profile)), | 244 ExtensionNotificationDisplayHelperFactory::GetForProfile(profile)), |
| 217 extension_id_(extension_id), | 245 extension_id_(extension_id), |
| 218 id_(id), | 246 id_(id), |
| 219 scoped_id_(CreateScopedIdentifier(extension_id, id)) { | 247 scoped_id_(CreateScopedIdentifier(extension_id, id)) { |
| 220 DCHECK(api_function_); | 248 DCHECK(api_function_); |
| 221 DCHECK(display_helper_); | 249 DCHECK(display_helper_); |
| 222 | 250 |
| 223 shutdown_notifier_subscription_ = | 251 shutdown_notifier_subscription_ = |
| 224 ShutdownNotifierFactory::GetInstance()->Get(profile)->Subscribe( | 252 ShutdownNotifierFactory::GetInstance()->Get(profile)->Subscribe( |
| 225 base::Bind(&NotificationsApiDelegate::Shutdown, | 253 base::Bind(&NotificationApiDelegate::Shutdown, |
| 226 base::Unretained(this))); | 254 base::Unretained(this))); |
| 227 } | 255 } |
| 228 | 256 |
| 229 void Close(bool by_user) override { | 257 void Close(bool by_user) override { |
| 230 EventRouter::UserGestureState gesture = | 258 EventRouter::UserGestureState gesture = |
| 231 by_user ? EventRouter::USER_GESTURE_ENABLED | 259 by_user ? EventRouter::USER_GESTURE_ENABLED |
| 232 : EventRouter::USER_GESTURE_NOT_ENABLED; | 260 : EventRouter::USER_GESTURE_NOT_ENABLED; |
| 233 std::unique_ptr<base::ListValue> args(CreateBaseEventArgs()); | 261 std::unique_ptr<base::ListValue> args(CreateBaseEventArgs()); |
| 234 args->AppendBoolean(by_user); | 262 args->AppendBoolean(by_user); |
| 235 SendEvent(events::NOTIFICATIONS_ON_CLOSED, | 263 SendEvent(events::NOTIFICATIONS_ON_CLOSED, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 286 | 314 |
| 287 } | 315 } |
| 288 return enabled; | 316 return enabled; |
| 289 } | 317 } |
| 290 } | 318 } |
| 291 | 319 |
| 292 return false; | 320 return false; |
| 293 } | 321 } |
| 294 | 322 |
| 295 private: | 323 private: |
| 296 ~NotificationsApiDelegate() override {} | 324 ~NotificationApiDelegate() override {} |
| 297 | 325 |
| 298 void SendEvent(events::HistogramValue histogram_value, | 326 void SendEvent(events::HistogramValue histogram_value, |
| 299 const std::string& name, | 327 const std::string& name, |
| 300 EventRouter::UserGestureState user_gesture, | 328 EventRouter::UserGestureState user_gesture, |
| 301 std::unique_ptr<base::ListValue> args) { | 329 std::unique_ptr<base::ListValue> args) { |
| 302 if (!event_router_) | 330 if (!event_router_) |
| 303 return; | 331 return; |
| 304 | 332 |
| 305 std::unique_ptr<Event> event( | 333 std::unique_ptr<Event> event( |
| 306 new Event(histogram_value, name, std::move(args))); | 334 new Event(histogram_value, name, std::move(args))); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 328 EventRouter* event_router_; | 356 EventRouter* event_router_; |
| 329 ExtensionNotificationDisplayHelper* display_helper_; | 357 ExtensionNotificationDisplayHelper* display_helper_; |
| 330 | 358 |
| 331 const std::string extension_id_; | 359 const std::string extension_id_; |
| 332 const std::string id_; | 360 const std::string id_; |
| 333 const std::string scoped_id_; | 361 const std::string scoped_id_; |
| 334 | 362 |
| 335 std::unique_ptr<KeyedServiceShutdownNotifier::Subscription> | 363 std::unique_ptr<KeyedServiceShutdownNotifier::Subscription> |
| 336 shutdown_notifier_subscription_; | 364 shutdown_notifier_subscription_; |
| 337 | 365 |
| 338 DISALLOW_COPY_AND_ASSIGN(NotificationsApiDelegate); | 366 DISALLOW_COPY_AND_ASSIGN(NotificationApiDelegate); |
| 339 }; | 367 }; |
| 340 | 368 |
| 341 } // namespace | 369 } // namespace |
| 342 | 370 |
| 343 bool NotificationsApiFunction::IsNotificationsApiAvailable() { | 371 bool NotificationsApiFunction::IsNotificationsApiAvailable() { |
| 344 // We need to check this explicitly rather than letting | 372 // We need to check this explicitly rather than letting |
| 345 // _permission_features.json enforce it, because we're sharing the | 373 // _permission_features.json enforce it, because we're sharing the |
| 346 // chrome.notifications permissions namespace with WebKit notifications. | 374 // chrome.notifications permissions namespace with WebKit notifications. |
| 347 return extension()->is_platform_app() || extension()->is_extension(); | 375 return extension()->is_platform_app() || extension()->is_extension(); |
| 348 } | 376 } |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 484 for (const NotificationItem& api_item : *options->items) { | 512 for (const NotificationItem& api_item : *options->items) { |
| 485 optional_fields.items.push_back(message_center::NotificationItem( | 513 optional_fields.items.push_back(message_center::NotificationItem( |
| 486 base::UTF8ToUTF16(api_item.title), | 514 base::UTF8ToUTF16(api_item.title), |
| 487 base::UTF8ToUTF16(api_item.message))); | 515 base::UTF8ToUTF16(api_item.message))); |
| 488 } | 516 } |
| 489 } | 517 } |
| 490 | 518 |
| 491 if (options->is_clickable.get()) | 519 if (options->is_clickable.get()) |
| 492 optional_fields.clickable = *options->is_clickable; | 520 optional_fields.clickable = *options->is_clickable; |
| 493 | 521 |
| 494 NotificationsApiDelegate* api_delegate(new NotificationsApiDelegate( | 522 // Create the notification api delegate. Ownership passed to the notification. |
| 495 this, GetProfile(), extension_->id(), id)); // ownership is passed to | 523 NotificationDelegate* api_delegate; |
| 496 // Notification | 524 #if BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) |
| 525 if (base::FeatureList::IsEnabled(features::kNativeNotifications)) { |
| 526 api_delegate = new NativeNotificationApiDelegate(extension_->id(), id); |
| 527 } else { |
| 528 api_delegate = |
| 529 new NotificationApiDelegate(this, GetProfile(), extension_->id(), id); |
| 530 } |
| 531 #else |
| 532 api_delegate = |
| 533 new NotificationApiDelegate(this, GetProfile(), extension_->id(), id); |
| 534 #endif // BUILDFLAG(ENABLE_NATIVE_NOTIFICATIONS) |
| 535 |
| 497 Notification notification( | 536 Notification notification( |
| 498 type, title, message, icon, | 537 type, title, message, icon, |
| 499 message_center::NotifierId(message_center::NotifierId::APPLICATION, | 538 message_center::NotifierId(message_center::NotifierId::APPLICATION, |
| 500 extension_->id()), | 539 extension_->id()), |
| 501 base::UTF8ToUTF16(extension_->name()), extension_->url(), | 540 base::UTF8ToUTF16(extension_->name()), extension_->url(), |
| 502 api_delegate->id(), optional_fields, api_delegate); | 541 api_delegate->id(), optional_fields, api_delegate); |
| 503 | 542 |
| 504 // Apply the "requireInteraction" flag. The value defaults to false. | 543 // Apply the "requireInteraction" flag. The value defaults to false. |
| 505 notification.set_never_timeout(options->require_interaction && | 544 notification.set_never_timeout(options->require_interaction && |
| 506 *options->require_interaction); | 545 *options->require_interaction); |
| (...skipping 323 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 : api::notifications::PERMISSION_LEVEL_DENIED; | 869 : api::notifications::PERMISSION_LEVEL_DENIED; |
| 831 | 870 |
| 832 SetResult( | 871 SetResult( |
| 833 base::MakeUnique<base::Value>(api::notifications::ToString(result))); | 872 base::MakeUnique<base::Value>(api::notifications::ToString(result))); |
| 834 SendResponse(true); | 873 SendResponse(true); |
| 835 | 874 |
| 836 return true; | 875 return true; |
| 837 } | 876 } |
| 838 | 877 |
| 839 } // namespace extensions | 878 } // namespace extensions |
| OLD | NEW |