push_messaging_message_filter.cc revision 116680a4aac90f2aa7413d9095a592090648e557
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
18namespace content {
19
20PushMessagingMessageFilter::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
30PushMessagingMessageFilter::~PushMessagingMessageFilter() {}
31
32bool 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
42void 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
72void 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  // TODO(mvanouwerkerk): Is this the app_id format we want to use?
88  std::string app_id =
89      origin.spec() + " " + base::Int64ToString(service_worker_registration_id);
90  service()->Register(app_id,
91                      sender_id,
92                      render_process_id_,
93                      render_frame_id,
94                      user_gesture,
95                      base::Bind(&PushMessagingMessageFilter::DidRegister,
96                                 weak_factory_.GetWeakPtr(),
97                                 render_frame_id,
98                                 callbacks_id));
99}
100
101void PushMessagingMessageFilter::DidRegister(
102    int render_frame_id,
103    int callbacks_id,
104    const GURL& push_endpoint,
105    const std::string& push_registration_id,
106    PushMessagingStatus status) {
107  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
108  if (status == PUSH_MESSAGING_STATUS_OK) {
109    Send(new PushMessagingMsg_RegisterSuccess(
110        render_frame_id, callbacks_id, push_endpoint, push_registration_id));
111  } else {
112    Send(new PushMessagingMsg_RegisterError(
113        render_frame_id, callbacks_id, status));
114  }
115}
116
117PushMessagingService* PushMessagingMessageFilter::service() {
118  if (!service_) {
119    RenderProcessHost* process_host =
120        RenderProcessHost::FromID(render_process_id_);
121    if (!process_host)
122      return NULL;
123    service_ = process_host->GetBrowserContext()->GetPushMessagingService();
124  }
125  return service_;
126}
127
128}  // namespace content
129