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_message_filter.h"
6
7 #include <string>
8
9 #include "base/bind.h"
10 #include "base/strings/string_number_conversions.h"
11 #include "content/browser/renderer_host/render_process_host_impl.h"
12 #include "content/browser/service_worker/service_worker_context_wrapper.h"
13 #include "content/common/push_messaging_messages.h"
14 #include "content/public/browser/browser_context.h"
15 #include "content/public/browser/browser_thread.h"
16 #include "content/public/browser/push_messaging_service.h"
17
18 namespace content {
19
PushMessagingMessageFilter(int render_process_id,ServiceWorkerContextWrapper * service_worker_context)20 PushMessagingMessageFilter::PushMessagingMessageFilter(
21 int render_process_id,
22 ServiceWorkerContextWrapper* service_worker_context)
23 : BrowserMessageFilter(PushMessagingMsgStart),
24 render_process_id_(render_process_id),
25 service_worker_context_(service_worker_context),
26 service_(NULL),
27 weak_factory_(this) {
28 }
29
~PushMessagingMessageFilter()30 PushMessagingMessageFilter::~PushMessagingMessageFilter() {}
31
OnMessageReceived(const IPC::Message & message)32 bool PushMessagingMessageFilter::OnMessageReceived(
33 const IPC::Message& message) {
34 bool handled = true;
35 IPC_BEGIN_MESSAGE_MAP(PushMessagingMessageFilter, message)
36 IPC_MESSAGE_HANDLER(PushMessagingHostMsg_Register, OnRegister)
37 IPC_MESSAGE_UNHANDLED(handled = false)
38 IPC_END_MESSAGE_MAP()
39 return handled;
40 }
41
OnRegister(int render_frame_id,int callbacks_id,const std::string & sender_id,bool user_gesture,int service_worker_provider_id)42 void PushMessagingMessageFilter::OnRegister(int render_frame_id,
43 int callbacks_id,
44 const std::string& sender_id,
45 bool user_gesture,
46 int service_worker_provider_id) {
47 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
48 // TODO(mvanouwerkerk): Validate arguments?
49 ServiceWorkerProviderHost* service_worker_host =
50 service_worker_context_->context()->GetProviderHost(
51 render_process_id_, service_worker_provider_id);
52 if (!service_worker_host || !service_worker_host->active_version()) {
53 Send(new PushMessagingMsg_RegisterError(
54 render_frame_id,
55 callbacks_id,
56 PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_NO_SERVICE_WORKER));
57 return;
58 }
59 BrowserThread::PostTask(
60 BrowserThread::UI,
61 FROM_HERE,
62 base::Bind(&PushMessagingMessageFilter::DoRegister,
63 weak_factory_.GetWeakPtr(),
64 render_frame_id,
65 callbacks_id,
66 sender_id,
67 user_gesture,
68 service_worker_host->active_version()->scope().GetOrigin(),
69 service_worker_host->active_version()->registration_id()));
70 }
71
DoRegister(int render_frame_id,int callbacks_id,const std::string & sender_id,bool user_gesture,const GURL & origin,int64 service_worker_registration_id)72 void PushMessagingMessageFilter::DoRegister(
73 int render_frame_id,
74 int callbacks_id,
75 const std::string& sender_id,
76 bool user_gesture,
77 const GURL& origin,
78 int64 service_worker_registration_id) {
79 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
80 if (!service()) {
81 Send(new PushMessagingMsg_RegisterError(
82 render_frame_id,
83 callbacks_id,
84 PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_SERVICE_NOT_AVAILABLE));
85 return;
86 }
87 service()->Register(origin,
88 service_worker_registration_id,
89 sender_id,
90 render_process_id_,
91 render_frame_id,
92 user_gesture,
93 base::Bind(&PushMessagingMessageFilter::DidRegister,
94 weak_factory_.GetWeakPtr(),
95 render_frame_id,
96 callbacks_id));
97 }
98
DidRegister(int render_frame_id,int callbacks_id,const GURL & push_endpoint,const std::string & push_registration_id,PushMessagingStatus status)99 void PushMessagingMessageFilter::DidRegister(
100 int render_frame_id,
101 int callbacks_id,
102 const GURL& push_endpoint,
103 const std::string& push_registration_id,
104 PushMessagingStatus status) {
105 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
106 if (status == PUSH_MESSAGING_STATUS_OK) {
107 Send(new PushMessagingMsg_RegisterSuccess(
108 render_frame_id, callbacks_id, push_endpoint, push_registration_id));
109 } else {
110 Send(new PushMessagingMsg_RegisterError(
111 render_frame_id, callbacks_id, status));
112 }
113 }
114
service()115 PushMessagingService* PushMessagingMessageFilter::service() {
116 if (!service_) {
117 RenderProcessHost* process_host =
118 RenderProcessHost::FromID(render_process_id_);
119 if (!process_host)
120 return NULL;
121 service_ = process_host->GetBrowserContext()->GetPushMessagingService();
122 }
123 return service_;
124 }
125
126 } // namespace content
127