1 // Copyright 2013 Samsung Electronics. 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.
5 #include "browser/notification/notification_controller_efl.h"
7 #include "base/strings/utf_string_conversions.h"
8 #include "common/web_contents_utils.h"
9 #include "content/public/browser/browser_thread.h"
10 #include "content/public/common/notification_resources.h"
11 #include "content/public/common/platform_notification_data.h"
12 #include "eweb_view.h"
13 #include "private/ewk_notification_private.h"
14 #include "public/ewk_notification.h"
16 using web_contents_utils::WebViewFromWebContents;
17 using namespace blink::mojom;
21 NotificationControllerEfl::NotificationControllerEfl()
22 : notification_show_callback_(nullptr)
23 , notification_cancel_callback_(nullptr)
24 , notification_callback_user_data_(nullptr)
29 NotificationControllerEfl::~NotificationControllerEfl() {
30 // notifications_map_.Clear();
32 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
33 void NotificationControllerEfl::NotificationAdd(uint64_t notification_id,
34 const GURL& origin, const base::string16& replace_id,
35 std::unique_ptr<DesktopNotificationDelegate> delegate) {
36 NotificationData* new_notification(
37 new NotificationData(origin, replace_id, std::move(delegate)));
38 notifications_map_.AddWithID(new_notification, notification_id);
41 bool NotificationControllerEfl::NotificationClosed(uint64_t notification_id,
44 NotificationData* saved_data = notifications_map_.Lookup(notification_id);
48 saved_data->notification_delegate->NotificationClosed();
49 notifications_map_.Remove(notification_id);
53 void NotificationControllerEfl::NotificationCancelled(uint64_t notification_id) {
54 // NotificationClosed(notification_id, false);
55 if (notification_cancel_callback_) {
56 notification_cancel_callback_(notification_id, notification_callback_user_data_);
59 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
60 bool NotificationControllerEfl::NotificationClicked(uint64_t notification_id) {
61 NotificationData* saved_data = notifications_map_.Lookup(notification_id);
65 saved_data->notification_delegate->NotificationClick();
66 notifications_map_.Remove(notification_id);
70 bool NotificationControllerEfl::NotificationDisplayed(uint64_t notification_id) {
71 NotificationData* saved_data = notifications_map_.Lookup(notification_id);
75 saved_data->notification_delegate->NotificationDisplayed();
79 blink::mojom::PermissionStatus NotificationControllerEfl::CheckPermissionOnUIThread(
80 BrowserContext* browser_context,
82 int render_process_id) {
83 DCHECK_CURRENTLY_ON(BrowserThread::UI);
84 return CheckPermissionForOrigin(origin);
87 blink::mojom::PermissionStatus NotificationControllerEfl::CheckPermissionOnIOThread(
88 ResourceContext* resource_context,
90 int render_process_id) {
91 DCHECK_CURRENTLY_ON(BrowserThread::IO);
92 return CheckPermissionForOrigin(origin);
95 void NotificationControllerEfl::DisplayNotification(
96 BrowserContext* browser_context,
97 const std::string& notification_id,
99 const PlatformNotificationData& notification_data,
100 const NotificationResources& notification_resources) {
101 BrowserContextEfl* browser_context_efl =
102 static_cast<BrowserContextEfl*>(browser_context);
103 CHECK(browser_context_efl);
104 EWebContext* ctx = browser_context_efl->WebContext();
107 bool has_callbacks = ctx->HasNotificationCallbacks()
108 || (notification_show_callback_ && notification_cancel_callback_);
109 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
110 if (!has_callbacks) {
111 delegate->NotificationClosed();
115 uint64_t replaceUniqueId = 0;
116 if (!notification_data.tag.empty() &&
117 IsNotificationPresent(origin,
118 base::UTF8ToUTF16(notification_data.tag), replaceUniqueId)) {
119 if (!ctx->NotificationCancelCallback(replaceUniqueId))
120 NotificationCancelled(replaceUniqueId);
122 NotificationClosed(replaceUniqueId, false);
125 uint64_t notificationUniqueId = reinterpret_cast<uint64_t>(delegate.get());
126 NotificationAdd(notificationUniqueId, origin,
127 base::UTF8ToUTF16(notification_data.tag),
128 std::move(delegate));
132 base::Bind(&NotificationControllerEfl::NotificationCancelled,
133 weak_factory_.GetWeakPtr(),
134 notificationUniqueId);
137 Ewk_Notification* notification =
138 new Ewk_Notification(base::UTF16ToUTF8(notification_data.body),
139 notification_data.tag,
140 base::UTF16ToUTF8(notification_data.title),
141 notification_resources.notification_icon,
142 notification_data.silent,
143 notificationUniqueId,
146 if (!ctx->NotificationShowCallback(notification))
147 notification_show_callback_(notification, notification_callback_user_data_);
153 void NotificationControllerEfl::DisplayPersistentNotification(
154 BrowserContext* browser_context,
155 const std::string& notification_id,
156 const GURL& service_worker_origin,
158 const PlatformNotificationData& notification_data,
159 const NotificationResources& notification_resources) {
163 void NotificationControllerEfl::ClosePersistentNotification(
164 BrowserContext* browser_context,
165 const std::string& notification_id) {
170 void NotificationControllerEfl::SetPermissionForNotification(
171 Ewk_Notification_Permission_Request* notification, bool isAllowed) {
173 EWebView* wv = EWebView::FromEvasObject(notification->GetWebviewEvasObject());
175 RenderViewHost* render_view_host =
176 wv->web_contents().GetRenderViewHost();
178 if (render_view_host) {
179 GURL origin = notification->GetSecurityOrigin()->GetURL();
180 // save decision in permissions map
181 permissions_mutex_.Acquire();
182 permissions_map_[origin] = isAllowed;
183 permissions_mutex_.Release();
187 void NotificationControllerEfl::AddPermission(const GURL origin,
189 base::AutoLock locker(permissions_mutex_);
190 permissions_map_[origin] = allowed;
193 blink::mojom::PermissionStatus
194 NotificationControllerEfl::CheckPermissionForOrigin(
195 const GURL &origin) const {
196 base::AutoLock locker(permissions_mutex_);
197 std::map<GURL, bool>::const_iterator it = permissions_map_.find(origin);
198 if (it == permissions_map_.end())
199 return blink::mojom::PermissionStatus::ASK;
201 blink::mojom::PermissionStatus::GRANTED :
202 blink::mojom::PermissionStatus::DENIED;
205 void NotificationControllerEfl::ClearPermissions() {
206 base::AutoLock locker(permissions_mutex_);
207 permissions_map_.clear();
210 void NotificationControllerEfl::RemovePermissions(Eina_List* origins) {
211 Eina_List* list = NULL;
213 base::AutoLock locker(permissions_mutex_);
214 EINA_LIST_FOREACH(origins, list, data) {
215 _Ewk_Security_Origin* origin = static_cast<_Ewk_Security_Origin*>(data);
216 permissions_map_.erase(origin->GetURL());
220 #if !defined(EWK_BRINGUP) // FIXME: m67 bringup
221 bool NotificationControllerEfl::IsNotificationPresent(const GURL& origin,
222 const base::string16& replaceid, uint64_t& notification_id) {
223 IDMap<NotificationData, IDMapOwnPointer>::const_iterator it(¬ifications_map_);
224 for (; !it.IsAtEnd(); it.Advance()) {
225 if (replaceid == it.GetCurrentValue()->replace_id &&
226 origin.spec() == it.GetCurrentValue()->origin_url) {
227 notification_id = it.GetCurrentKey();
236 void NotificationControllerEfl::RequestPermission(
237 WebContents* web_contents,
238 const GURL& requesting_frame,
239 const base::Callback<void(PermissionStatus)>& result_callback) {
240 EWebView* web_view = WebViewFromWebContents(web_contents);
242 LOG(ERROR) << "Dropping PermissionNotification request caused by lack "
244 result_callback.Run(PermissionStatus::DENIED);
247 std::unique_ptr<Ewk_Notification_Permission_Request> notification_permission(
248 new Ewk_Notification_Permission_Request(web_view->evas_object(),
249 result_callback, requesting_frame));
251 if (!web_view->IsNotificationPermissionCallbackSet()) {
252 LOG(ERROR) << "Dropping PermissionNotification request caused by lack "
253 "of the Notification Permission Callback";
254 result_callback.Run(PermissionStatus::DENIED);
258 blink::mojom::PermissionStatus web_notification_permission =
259 CheckPermissionForOrigin(requesting_frame);
260 if (web_notification_permission ==
261 blink::mojom::PermissionStatus::LAST) {
262 web_view->InvokeNotificationPermissionCallback(
263 notification_permission.get());
264 // if policy is suspended, the API takes over the policy object lifetime
265 // and policy will be deleted after decision is made
266 if (notification_permission->IsSuspended()) {
267 ignore_result(notification_permission.release());
271 if (web_notification_permission == blink::mojom::PermissionStatus::GRANTED) {
272 result_callback.Run(PermissionStatus::GRANTED);
274 result_callback.Run(PermissionStatus::DENIED);
279 void NotificationControllerEfl::SetNotificationCallbacks(Ewk_Notification_Show_Callback show_callback, Ewk_Notification_Cancel_Callback cancel_callback, void* user_data) {
280 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
281 notification_show_callback_ = show_callback;
282 notification_cancel_callback_ = cancel_callback;
283 notification_callback_user_data_ = user_data;