Upstream version 11.40.271.0
[platform/framework/web/crosswalk.git] / src / content / browser / push_messaging / push_messaging_message_filter.cc
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/browser/push_messaging/push_messaging_message_filter.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/metrics/histogram.h"
11 #include "base/strings/string_number_conversions.h"
12 #include "content/browser/renderer_host/render_process_host_impl.h"
13 #include "content/browser/service_worker/service_worker_context_wrapper.h"
14 #include "content/common/push_messaging_messages.h"
15 #include "content/public/browser/browser_context.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/browser/push_messaging_service.h"
18 #include "third_party/WebKit/public/platform/WebPushPermissionStatus.h"
19
20 namespace content {
21 namespace {
22
23 void RecordRegistrationStatus(PushRegistrationStatus status) {
24   UMA_HISTOGRAM_ENUMERATION("PushMessaging.RegistrationStatus",
25                             status,
26                             PUSH_REGISTRATION_STATUS_LAST + 1);
27 }
28
29 }  // namespace
30
31 PushMessagingMessageFilter::PushMessagingMessageFilter(
32     int render_process_id,
33     ServiceWorkerContextWrapper* service_worker_context)
34     : BrowserMessageFilter(PushMessagingMsgStart),
35       render_process_id_(render_process_id),
36       service_worker_context_(service_worker_context),
37       service_(NULL),
38       weak_factory_(this) {
39 }
40
41 PushMessagingMessageFilter::~PushMessagingMessageFilter() {}
42
43 bool PushMessagingMessageFilter::OnMessageReceived(
44     const IPC::Message& message) {
45   bool handled = true;
46   IPC_BEGIN_MESSAGE_MAP(PushMessagingMessageFilter, message)
47     IPC_MESSAGE_HANDLER(PushMessagingHostMsg_Register, OnRegister)
48     IPC_MESSAGE_HANDLER(PushMessagingHostMsg_PermissionStatus,
49                         OnPermissionStatusRequest)
50     IPC_MESSAGE_UNHANDLED(handled = false)
51   IPC_END_MESSAGE_MAP()
52   return handled;
53 }
54
55 void PushMessagingMessageFilter::OnRegister(int render_frame_id,
56                                             int callbacks_id,
57                                             const std::string& sender_id,
58                                             bool user_gesture,
59                                             int service_worker_provider_id) {
60   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
61   // TODO(mvanouwerkerk): Validate arguments?
62   ServiceWorkerProviderHost* service_worker_host =
63       service_worker_context_->context()->GetProviderHost(
64           render_process_id_, service_worker_provider_id);
65   if (!service_worker_host || !service_worker_host->active_version()) {
66     PushRegistrationStatus status =
67         PUSH_REGISTRATION_STATUS_NO_SERVICE_WORKER;
68     Send(new PushMessagingMsg_RegisterError(
69         render_frame_id,
70         callbacks_id,
71         status));
72     RecordRegistrationStatus(status);
73     return;
74   }
75   BrowserThread::PostTask(
76       BrowserThread::UI,
77       FROM_HERE,
78       base::Bind(&PushMessagingMessageFilter::DoRegister,
79                  weak_factory_.GetWeakPtr(),
80                  render_frame_id,
81                  callbacks_id,
82                  sender_id,
83                  user_gesture,
84                  service_worker_host->active_version()->scope().GetOrigin(),
85                  service_worker_host->active_version()->registration_id()));
86 }
87
88 void PushMessagingMessageFilter::OnPermissionStatusRequest(
89     int render_frame_id,
90     int service_worker_provider_id,
91     int permission_callback_id) {
92   DCHECK_CURRENTLY_ON(BrowserThread::IO);
93   ServiceWorkerProviderHost* service_worker_host =
94       service_worker_context_->context()->GetProviderHost(
95           render_process_id_, service_worker_provider_id);
96
97   if (service_worker_host && service_worker_host->active_version()) {
98     BrowserThread::PostTask(
99         BrowserThread::UI,
100         FROM_HERE,
101         base::Bind(&PushMessagingMessageFilter::DoPermissionStatusRequest,
102                    weak_factory_.GetWeakPtr(),
103                    service_worker_host->active_version()->scope().GetOrigin(),
104                    render_frame_id,
105                    permission_callback_id));
106   } else {
107     Send(new PushMessagingMsg_PermissionStatusFailure(
108           render_frame_id, permission_callback_id));
109   }
110 }
111
112 void PushMessagingMessageFilter::DoRegister(
113     int render_frame_id,
114     int callbacks_id,
115     const std::string& sender_id,
116     bool user_gesture,
117     const GURL& origin,
118     int64 service_worker_registration_id) {
119   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
120   if (!service()) {
121     PushRegistrationStatus status =
122         PUSH_REGISTRATION_STATUS_SERVICE_NOT_AVAILABLE;
123     Send(new PushMessagingMsg_RegisterError(
124         render_frame_id,
125         callbacks_id,
126         status));
127     RecordRegistrationStatus(status);
128     return;
129   }
130   service()->Register(origin,
131                       service_worker_registration_id,
132                       sender_id,
133                       render_process_id_,
134                       render_frame_id,
135                       user_gesture,
136                       base::Bind(&PushMessagingMessageFilter::DidRegister,
137                                  weak_factory_.GetWeakPtr(),
138                                  render_frame_id,
139                                  callbacks_id));
140 }
141
142 void PushMessagingMessageFilter::DoPermissionStatusRequest(
143     const GURL& requesting_origin,
144     int render_frame_id,
145     int callback_id) {
146   DCHECK_CURRENTLY_ON(BrowserThread::UI);
147   blink::WebPushPermissionStatus permission_value =
148       service()->GetPermissionStatus(
149           requesting_origin, render_process_id_, render_frame_id);
150
151   Send(new PushMessagingMsg_PermissionStatusResult(
152       render_frame_id, callback_id, permission_value));
153 }
154
155 void PushMessagingMessageFilter::DidRegister(
156     int render_frame_id,
157     int callbacks_id,
158     const GURL& push_endpoint,
159     const std::string& push_registration_id,
160     PushRegistrationStatus status) {
161   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
162   if (status == PUSH_REGISTRATION_STATUS_SUCCESS) {
163     Send(new PushMessagingMsg_RegisterSuccess(
164         render_frame_id, callbacks_id, push_endpoint, push_registration_id));
165   } else {
166     Send(new PushMessagingMsg_RegisterError(
167         render_frame_id, callbacks_id, status));
168   }
169   RecordRegistrationStatus(status);
170 }
171
172 PushMessagingService* PushMessagingMessageFilter::service() {
173   if (!service_) {
174     RenderProcessHost* process_host =
175         RenderProcessHost::FromID(render_process_id_);
176     if (!process_host)
177       return NULL;
178     service_ = process_host->GetBrowserContext()->GetPushMessagingService();
179   }
180   return service_;
181 }
182
183 }  // namespace content