// Copyright 2014 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "content/shell/browser/layout_test/layout_test_notification_manager.h" #include "base/guid.h" #include "base/strings/utf_string_conversions.h" #include "content/public/browser/browser_thread.h" #include "content/public/browser/desktop_notification_delegate.h" #include "content/public/browser/notification_event_dispatcher.h" #include "content/public/browser/permission_type.h" #include "content/public/common/persistent_notification_status.h" #include "content/public/common/platform_notification_data.h" #include "content/shell/browser/layout_test/layout_test_browser_context.h" #include "content/shell/browser/layout_test/layout_test_content_browser_client.h" #include "content/shell/browser/layout_test/layout_test_permission_manager.h" namespace content { namespace { // The Web Notification layout tests don't care about the lifetime of the // Service Worker when a notificationclick event has been dispatched. void OnEventDispatchComplete(PersistentNotificationStatus status) {} blink::WebNotificationPermission ToWebNotificationPermission( PermissionStatus status) { switch (status) { case PERMISSION_STATUS_GRANTED: return blink::WebNotificationPermissionAllowed; case PERMISSION_STATUS_DENIED: return blink::WebNotificationPermissionDenied; case PERMISSION_STATUS_ASK: return blink::WebNotificationPermissionDefault; } NOTREACHED(); return blink::WebNotificationPermissionLast; } } // namespace LayoutTestNotificationManager::LayoutTestNotificationManager() : weak_factory_(this) {} LayoutTestNotificationManager::~LayoutTestNotificationManager() {} void LayoutTestNotificationManager::DisplayNotification( BrowserContext* browser_context, const GURL& origin, const SkBitmap& icon, const PlatformNotificationData& notification_data, scoped_ptr delegate, base::Closure* cancel_callback) { DCHECK_CURRENTLY_ON(BrowserThread::UI); std::string title = base::UTF16ToUTF8(notification_data.title); DCHECK(cancel_callback); *cancel_callback = base::Bind(&LayoutTestNotificationManager::Close, weak_factory_.GetWeakPtr(), title); ReplaceNotificationIfNeeded(notification_data); page_notifications_[title] = delegate.release(); page_notifications_[title]->NotificationDisplayed(); } void LayoutTestNotificationManager::DisplayPersistentNotification( BrowserContext* browser_context, int64_t persistent_notification_id, const GURL& origin, const SkBitmap& icon, const PlatformNotificationData& notification_data) { DCHECK_CURRENTLY_ON(BrowserThread::UI); std::string title = base::UTF16ToUTF8(notification_data.title); ReplaceNotificationIfNeeded(notification_data); PersistentNotification notification; notification.browser_context = browser_context; notification.origin = origin; notification.persistent_id = persistent_notification_id; persistent_notifications_[title] = notification; } void LayoutTestNotificationManager::ClosePersistentNotification( BrowserContext* browser_context, int64_t persistent_notification_id) { for (const auto& iter : persistent_notifications_) { if (iter.second.persistent_id != persistent_notification_id) continue; persistent_notifications_.erase(iter.first); return; } } void LayoutTestNotificationManager::SimulateClick(const std::string& title) { DCHECK_CURRENTLY_ON(BrowserThread::UI); // First check for page-notifications with the given title. const auto& page_iterator = page_notifications_.find(title); if (page_iterator != page_notifications_.end()) { page_iterator->second->NotificationClick(); return; } // Then check for persistent notifications with the given title. const auto& persistent_iterator = persistent_notifications_.find(title); if (persistent_iterator == persistent_notifications_.end()) return; const PersistentNotification& notification = persistent_iterator->second; content::NotificationEventDispatcher::GetInstance() ->DispatchNotificationClickEvent( notification.browser_context, notification.persistent_id, notification.origin, base::Bind(&OnEventDispatchComplete)); } blink::WebNotificationPermission LayoutTestNotificationManager::CheckPermissionOnUIThread( BrowserContext* browser_context, const GURL& origin, int render_process_id) { DCHECK_CURRENTLY_ON(BrowserThread::UI); return CheckPermission(origin); } blink::WebNotificationPermission LayoutTestNotificationManager::CheckPermissionOnIOThread( ResourceContext* resource_context, const GURL& origin, int render_process_id) { DCHECK_CURRENTLY_ON(BrowserThread::IO); return CheckPermission(origin); } void LayoutTestNotificationManager::Close(const std::string& title) { DCHECK_CURRENTLY_ON(BrowserThread::UI); auto iterator = page_notifications_.find(title); if (iterator == page_notifications_.end()) return; iterator->second->NotificationClosed(); } void LayoutTestNotificationManager::ReplaceNotificationIfNeeded( const PlatformNotificationData& notification_data) { if (!notification_data.tag.length()) return; std::string tag = notification_data.tag; const auto& replace_iter = replacements_.find(tag); if (replace_iter != replacements_.end()) { const std::string& previous_title = replace_iter->second; const auto& page_notification_iter = page_notifications_.find(previous_title); if (page_notification_iter != page_notifications_.end()) { DesktopNotificationDelegate* previous_delegate = page_notification_iter->second; previous_delegate->NotificationClosed(); page_notifications_.erase(page_notification_iter); delete previous_delegate; } const auto& persistent_notification_iter = persistent_notifications_.find(previous_title); if (persistent_notification_iter != persistent_notifications_.end()) persistent_notifications_.erase(persistent_notification_iter); } replacements_[tag] = base::UTF16ToUTF8(notification_data.title); } blink::WebNotificationPermission LayoutTestNotificationManager::CheckPermission(const GURL& origin) { return ToWebNotificationPermission(LayoutTestContentBrowserClient::Get() ->GetLayoutTestBrowserContext() ->GetLayoutTestPermissionManager() ->GetPermissionStatus(PermissionType::NOTIFICATIONS, origin, origin)); } } // namespace content