1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/shell/renderer/test_runner/notification_presenter.h"
6
7#include "base/logging.h"
8#include "content/common/desktop_notification_messages.h"
9#include "content/shell/renderer/test_runner/web_test_delegate.h"
10#include "third_party/WebKit/public/platform/Platform.h"
11#include "third_party/WebKit/public/platform/WebString.h"
12#include "third_party/WebKit/public/platform/WebURL.h"
13#include "third_party/WebKit/public/web/WebKit.h"
14#include "third_party/WebKit/public/web/WebNotificationPermissionCallback.h"
15#include "third_party/WebKit/public/web/WebSecurityOrigin.h"
16#include "url/gurl.h"
17
18using blink::Platform;
19using blink::WebNotification;
20using blink::WebNotificationPermissionCallback;
21using blink::WebNotificationPresenter;
22using blink::WebSecurityOrigin;
23using blink::WebTextDirectionRightToLeft;
24
25namespace content {
26
27namespace {
28
29void DeferredDisplayDispatch(void* context) {
30  WebNotification* notification = static_cast<WebNotification*>(context);
31  notification->dispatchDisplayEvent();
32
33  delete notification;
34}
35
36}  // namespace
37
38NotificationPresenter::NotificationPresenter() : delegate_(0) {}
39
40NotificationPresenter::~NotificationPresenter() {}
41
42bool NotificationPresenter::SimulateClick(const std::string& title) {
43  ActiveNotificationMap::iterator iter = active_notifications_.find(title);
44  if (iter == active_notifications_.end())
45    return false;
46
47  const WebNotification& notification = iter->second;
48
49  WebNotification event_target(notification);
50  event_target.dispatchClickEvent();
51
52  return true;
53}
54
55void NotificationPresenter::Reset() {
56  while (!active_notifications_.empty()) {
57    const WebNotification& notification = active_notifications_.begin()->second;
58    cancel(notification);
59  }
60
61  replacements_.clear();
62}
63
64bool NotificationPresenter::show(const WebNotification& notification) {
65  if (!notification.replaceId().isEmpty()) {
66    std::string replaceId(notification.replaceId().utf8());
67    if (replacements_.find(replaceId) != replacements_.end()) {
68      delegate_->PrintMessage(std::string("REPLACING NOTIFICATION ") +
69                              replacements_.find(replaceId)->second + "\n");
70    }
71    replacements_[replaceId] = notification.title().utf8();
72  }
73
74  delegate_->PrintMessage("DESKTOP NOTIFICATION SHOWN: ");
75  if (!notification.title().isEmpty())
76    delegate_->PrintMessage(notification.title().utf8().data());
77
78  if (notification.direction() == WebTextDirectionRightToLeft)
79    delegate_->PrintMessage(", RTL");
80
81  // TODO(beverloo): WebNotification should expose the "lang" attribute's value.
82
83  if (!notification.body().isEmpty()) {
84    delegate_->PrintMessage(std::string(", body: ") +
85                            notification.body().utf8().data());
86  }
87
88  if (!notification.replaceId().isEmpty()) {
89    delegate_->PrintMessage(std::string(", tag: ") +
90                            notification.replaceId().utf8().data());
91  }
92
93  if (!notification.iconURL().isEmpty()) {
94    delegate_->PrintMessage(std::string(", icon: ") +
95                            notification.iconURL().spec().data());
96  }
97
98  delegate_->PrintMessage("\n");
99
100  std::string title = notification.title().utf8();
101  active_notifications_[title] = notification;
102
103  Platform::current()->callOnMainThread(DeferredDisplayDispatch,
104                                        new WebNotification(notification));
105
106  return true;
107}
108
109void NotificationPresenter::cancel(const WebNotification& notification) {
110  std::string title = notification.title().utf8();
111
112  delegate_->PrintMessage(std::string("DESKTOP NOTIFICATION CLOSED: ") + title +
113                          "\n");
114
115  WebNotification event_target(notification);
116  event_target.dispatchCloseEvent(false);
117
118  active_notifications_.erase(title);
119}
120
121void NotificationPresenter::objectDestroyed(
122    const WebNotification& notification) {
123  std::string title = notification.title().utf8();
124  active_notifications_.erase(title);
125}
126
127WebNotificationPresenter::Permission NotificationPresenter::checkPermission(
128    const WebSecurityOrigin& security_origin) {
129  return delegate_->CheckWebNotificationPermission(
130      GURL(security_origin.toString()));
131}
132
133}  // namespace content
134