fac7142f9b6634715f747087dccf12d4e70cebc9
[platform/framework/web/chromium-efl.git] / tizen_src / ewk / efl_integration / browser / notification / notification_controller_efl.cc
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.
4
5 #include "browser/notification/notification_controller_efl.h"
6
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"
15
16 using web_contents_utils::WebViewFromWebContents;
17 using namespace blink::mojom;
18
19 namespace content {
20
21 NotificationControllerEfl::NotificationControllerEfl()
22   : notification_show_callback_(nullptr)
23   , notification_cancel_callback_(nullptr)
24   , notification_callback_user_data_(nullptr)
25   , weak_factory_(this)
26 {
27 }
28
29 NotificationControllerEfl::~NotificationControllerEfl() {
30   // notifications_map_.Clear();
31 }
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);
39 }
40
41 bool NotificationControllerEfl::NotificationClosed(uint64_t notification_id,
42     bool by_user) {
43
44   NotificationData* saved_data = notifications_map_.Lookup(notification_id);
45   if (!saved_data)
46     return false;
47
48   saved_data->notification_delegate->NotificationClosed();
49   notifications_map_.Remove(notification_id);
50   return true;
51 }
52 #endif
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_);
57   }
58 }
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);
62   if (!saved_data)
63     return false;
64
65   saved_data->notification_delegate->NotificationClick();
66   notifications_map_.Remove(notification_id);
67   return true;
68 }
69
70 bool NotificationControllerEfl::NotificationDisplayed(uint64_t notification_id) {
71   NotificationData* saved_data = notifications_map_.Lookup(notification_id);
72   if (!saved_data)
73     return false;
74
75   saved_data->notification_delegate->NotificationDisplayed();
76   return true;
77 }
78 #endif
79 blink::mojom::PermissionStatus NotificationControllerEfl::CheckPermissionOnUIThread(
80     BrowserContext* browser_context,
81     const GURL& origin,
82     int render_process_id) {
83   DCHECK_CURRENTLY_ON(BrowserThread::UI);
84   return CheckPermissionForOrigin(origin);
85 }
86
87 blink::mojom::PermissionStatus NotificationControllerEfl::CheckPermissionOnIOThread(
88     ResourceContext* resource_context,
89     const GURL& origin,
90     int render_process_id) {
91   DCHECK_CURRENTLY_ON(BrowserThread::IO);
92   return CheckPermissionForOrigin(origin);
93 }
94
95 void NotificationControllerEfl::DisplayNotification(
96     BrowserContext* browser_context,
97     const std::string& notification_id,
98     const GURL& origin,
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();
105   CHECK(ctx);
106
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();
112     return;
113   }
114
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);
121     else
122       NotificationClosed(replaceUniqueId, false);
123   }
124
125   uint64_t notificationUniqueId = reinterpret_cast<uint64_t>(delegate.get());
126   NotificationAdd(notificationUniqueId, origin,
127                   base::UTF8ToUTF16(notification_data.tag),
128                   std::move(delegate));
129
130   if (cancel_callback)
131     *cancel_callback =
132         base::Bind(&NotificationControllerEfl::NotificationCancelled,
133                    weak_factory_.GetWeakPtr(),
134                    notificationUniqueId);
135
136
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,
144                            origin);
145
146   if (!ctx->NotificationShowCallback(notification))
147     notification_show_callback_(notification, notification_callback_user_data_);
148
149   delete notification;
150 #endif
151 }
152
153 void NotificationControllerEfl::DisplayPersistentNotification(
154     BrowserContext* browser_context,
155     const std::string& notification_id,
156     const GURL& service_worker_origin,
157     const GURL& origin,
158     const PlatformNotificationData& notification_data,
159     const NotificationResources& notification_resources) {
160   NOTIMPLEMENTED();
161 }
162
163 void NotificationControllerEfl::ClosePersistentNotification(
164     BrowserContext* browser_context,
165     const std::string& notification_id) {
166   NOTIMPLEMENTED();
167 }
168
169
170 void NotificationControllerEfl::SetPermissionForNotification(
171     Ewk_Notification_Permission_Request* notification, bool isAllowed) {
172
173   EWebView* wv = EWebView::FromEvasObject(notification->GetWebviewEvasObject());
174   DCHECK(wv);
175   RenderViewHost* render_view_host =
176       wv->web_contents().GetRenderViewHost();
177
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();
184   }
185 }
186
187 void NotificationControllerEfl::AddPermission(const GURL origin,
188                                               bool allowed) {
189   base::AutoLock locker(permissions_mutex_);
190   permissions_map_[origin] = allowed;
191 }
192
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;
200   return it->second ?
201       blink::mojom::PermissionStatus::GRANTED :
202       blink::mojom::PermissionStatus::DENIED;
203 }
204
205 void NotificationControllerEfl::ClearPermissions() {
206   base::AutoLock locker(permissions_mutex_);
207   permissions_map_.clear();
208 }
209
210 void NotificationControllerEfl::RemovePermissions(Eina_List* origins) {
211   Eina_List* list = NULL;
212   void* data = 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());
217   }
218 }
219
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(&notifications_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();
228       return true;
229     }
230   }
231
232   return false;
233 }
234 #endif
235
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);
241   if (!web_view) {
242     LOG(ERROR) << "Dropping PermissionNotification request caused by lack "
243                   "of the WebView";
244     result_callback.Run(PermissionStatus::DENIED);
245     return;
246   }
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));
250
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);
255     return;
256   }
257
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());
268       return;
269     }
270   } else {
271     if (web_notification_permission == blink::mojom::PermissionStatus::GRANTED) {
272       result_callback.Run(PermissionStatus::GRANTED);
273     } else {
274       result_callback.Run(PermissionStatus::DENIED);
275     }
276   }
277 }
278
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;
284 }
285
286 }//namespace