Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1982)

Side by Side Diff: chrome/browser/services/gcm/push_messaging_service_impl.cc

Issue 404353003: Define PushMessagingApplicationId and replace ad-hoc code. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Address comments from jam and fgorski. Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/browser/services/gcm/push_messaging_service_impl.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/services/gcm/push_messaging_service_impl.h" 5 #include "chrome/browser/services/gcm/push_messaging_service_impl.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/command_line.h" 10 #include "base/command_line.h"
11 #include "base/prefs/pref_service.h" 11 #include "base/prefs/pref_service.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "chrome/browser/content_settings/permission_request_id.h" 13 #include "chrome/browser/content_settings/permission_request_id.h"
14 #include "chrome/browser/profiles/profile.h" 14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/services/gcm/gcm_profile_service.h" 15 #include "chrome/browser/services/gcm/gcm_profile_service.h"
16 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h" 16 #include "chrome/browser/services/gcm/gcm_profile_service_factory.h"
17 #include "chrome/browser/services/gcm/push_messaging_application_id.h"
17 #include "chrome/browser/services/gcm/push_messaging_permission_context.h" 18 #include "chrome/browser/services/gcm/push_messaging_permission_context.h"
18 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory. h" 19 #include "chrome/browser/services/gcm/push_messaging_permission_context_factory. h"
19 #include "chrome/common/chrome_switches.h" 20 #include "chrome/common/chrome_switches.h"
20 #include "chrome/common/pref_names.h" 21 #include "chrome/common/pref_names.h"
21 #include "components/gcm_driver/gcm_driver.h" 22 #include "components/gcm_driver/gcm_driver.h"
22 #include "components/pref_registry/pref_registry_syncable.h" 23 #include "components/pref_registry/pref_registry_syncable.h"
23 #include "content/public/browser/render_frame_host.h" 24 #include "content/public/browser/render_frame_host.h"
24 #include "content/public/browser/web_contents.h" 25 #include "content/public/browser/web_contents.h"
25 26
26 namespace gcm { 27 namespace gcm {
27 28
28 namespace { 29 namespace {
29 const char kAppIdPrefix[] = "push:";
30 const int kMaxRegistrations = 1000000; 30 const int kMaxRegistrations = 1000000;
31 } // namespace 31 } // namespace
32 32
33 // static 33 // static
34 void PushMessagingServiceImpl::RegisterProfilePrefs( 34 void PushMessagingServiceImpl::RegisterProfilePrefs(
35 user_prefs::PrefRegistrySyncable* registry) { 35 user_prefs::PrefRegistrySyncable* registry) {
36 registry->RegisterIntegerPref( 36 registry->RegisterIntegerPref(
37 prefs::kPushMessagingRegistrationCount, 37 prefs::kPushMessagingRegistrationCount,
38 0, 38 0,
39 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF); 39 user_prefs::PrefRegistrySyncable::UNSYNCABLE_PREF);
(...skipping 16 matching lines...) Expand all
56 0) { 56 0) {
57 return; 57 return;
58 } 58 }
59 // Create the GCMProfileService, and hence instantiate this class. 59 // Create the GCMProfileService, and hence instantiate this class.
60 GCMProfileService* gcm_service = 60 GCMProfileService* gcm_service =
61 gcm::GCMProfileServiceFactory::GetForProfile(profile); 61 gcm::GCMProfileServiceFactory::GetForProfile(profile);
62 PushMessagingServiceImpl* push_service = 62 PushMessagingServiceImpl* push_service =
63 static_cast<PushMessagingServiceImpl*>( 63 static_cast<PushMessagingServiceImpl*>(
64 gcm_service->push_messaging_service()); 64 gcm_service->push_messaging_service());
65 // Register ourselves as an app handler. 65 // Register ourselves as an app handler.
66 gcm_service->driver()->AddAppHandler(kAppIdPrefix, push_service); 66 gcm_service->driver()->AddAppHandler(kPushMessagingApplicationIdPrefix,
67 push_service);
67 } 68 }
68 69
69 PushMessagingServiceImpl::PushMessagingServiceImpl( 70 PushMessagingServiceImpl::PushMessagingServiceImpl(
70 GCMProfileService* gcm_profile_service, 71 GCMProfileService* gcm_profile_service,
71 Profile* profile) 72 Profile* profile)
72 : gcm_profile_service_(gcm_profile_service), 73 : gcm_profile_service_(gcm_profile_service),
73 profile_(profile), 74 profile_(profile),
74 weak_factory_(this) { 75 weak_factory_(this) {
75 } 76 }
76 77
77 PushMessagingServiceImpl::~PushMessagingServiceImpl() { 78 PushMessagingServiceImpl::~PushMessagingServiceImpl() {
78 // TODO(johnme): If it's possible for this to be destroyed before GCMDriver, 79 // TODO(johnme): If it's possible for this to be destroyed before GCMDriver,
79 // then we should call RemoveAppHandler. 80 // then we should call RemoveAppHandler.
80 } 81 }
81 82
82 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const { 83 bool PushMessagingServiceImpl::CanHandle(const std::string& app_id) const {
83 // TODO(mvanouwerkerk): Finalize and centralize format of Push API app_id. 84 return PushMessagingApplicationId::Parse(app_id).IsValid();
84 return StartsWithASCII(app_id, kAppIdPrefix, true);
85 } 85 }
86 86
87 void PushMessagingServiceImpl::ShutdownHandler() { 87 void PushMessagingServiceImpl::ShutdownHandler() {
88 // TODO(johnme): Do any necessary cleanup. 88 // TODO(johnme): Do any necessary cleanup.
89 } 89 }
90 90
91 void PushMessagingServiceImpl::OnMessage( 91 void PushMessagingServiceImpl::OnMessage(
92 const std::string& app_id, 92 const std::string& app_id,
93 const GCMClient::IncomingMessage& message) { 93 const GCMClient::IncomingMessage& message) {
94 // The Push API only exposes a single string of data in the push event fired 94 // The Push API only exposes a single string of data in the push event fired
95 // on the Service Worker. When developers send messages using GCM to the Push 95 // on the Service Worker. When developers send messages using GCM to the Push
96 // API, they must pass a single key-value pair, where the key is "data" and 96 // API, they must pass a single key-value pair, where the key is "data" and
97 // the value is the string they want to be passed to their Service Worker. 97 // the value is the string they want to be passed to their Service Worker.
98 // For example, they could send the following JSON using the HTTPS GCM API: 98 // For example, they could send the following JSON using the HTTPS GCM API:
99 // { 99 // {
100 // "registration_ids": ["FOO", "BAR"], 100 // "registration_ids": ["FOO", "BAR"],
101 // "data": { 101 // "data": {
102 // "data": "BAZ", 102 // "data": "BAZ",
103 // }, 103 // },
104 // "delay_while_idle": true, 104 // "delay_while_idle": true,
105 // } 105 // }
106 // TODO(johnme): Make sure this is clearly documented for developers. 106 // TODO(johnme): Make sure this is clearly documented for developers.
107 PushMessagingApplicationId application_id =
108 PushMessagingApplicationId::Parse(app_id);
109 DCHECK(application_id.IsValid());
107 GCMClient::MessageData::const_iterator it = message.data.find("data"); 110 GCMClient::MessageData::const_iterator it = message.data.find("data");
108 if (it != message.data.end()) { 111 if (application_id.IsValid() && it != message.data.end()) {
109 const std::string& data ALLOW_UNUSED = it->second; 112 const std::string& data ALLOW_UNUSED = it->second;
110 // TODO(mvanouwerkerk): Fire push event with data on the Service Worker 113 // TODO(mvanouwerkerk): Fire push event with data on the Service Worker
111 // corresponding to app_id (and remove ALLOW_UNUSED above). 114 // corresponding to app_id (and remove ALLOW_UNUSED above).
112 } else { 115 } else {
113 // Drop the message, as it is invalid. 116 // Drop the message, as it is invalid.
114 // TODO(mvanouwerkerk): Show a warning in the developer console of the 117 // TODO(mvanouwerkerk): Show a warning in the developer console of the
115 // Service Worker corresponding to app_id. 118 // Service Worker corresponding to app_id.
116 // TODO(johnme): Add diagnostic observers (e.g. UMA and an internals page) 119 // TODO(johnme): Add diagnostic observers (e.g. UMA and an internals page)
117 // to know when bad things happen. 120 // to know when bad things happen.
118 } 121 }
119 } 122 }
120 123
121 void PushMessagingServiceImpl::OnMessagesDeleted(const std::string& app_id) { 124 void PushMessagingServiceImpl::OnMessagesDeleted(const std::string& app_id) {
122 // TODO(mvanouwerkerk): Fire push error event on the Service Worker 125 // TODO(mvanouwerkerk): Fire push error event on the Service Worker
123 // corresponding to app_id. 126 // corresponding to app_id.
124 } 127 }
125 128
126 void PushMessagingServiceImpl::OnSendError( 129 void PushMessagingServiceImpl::OnSendError(
127 const std::string& app_id, 130 const std::string& app_id,
128 const GCMClient::SendErrorDetails& send_error_details) { 131 const GCMClient::SendErrorDetails& send_error_details) {
129 NOTREACHED() << "The Push API shouldn't have sent messages upstream"; 132 NOTREACHED() << "The Push API shouldn't have sent messages upstream";
130 } 133 }
131 134
132 void PushMessagingServiceImpl::Register( 135 void PushMessagingServiceImpl::Register(
133 const std::string& app_id, 136 const GURL& origin,
137 int64 service_worker_registration_id,
134 const std::string& sender_id, 138 const std::string& sender_id,
135 int renderer_id, 139 int renderer_id,
136 int render_frame_id, 140 int render_frame_id,
137 bool user_gesture, 141 bool user_gesture,
138 const content::PushMessagingService::RegisterCallback& callback) { 142 const content::PushMessagingService::RegisterCallback& callback) {
139 if (!gcm_profile_service_->driver()) { 143 if (!gcm_profile_service_->driver()) {
140 NOTREACHED() << "There is no GCMDriver. Has GCMProfileService shut down?"; 144 NOTREACHED() << "There is no GCMDriver. Has GCMProfileService shut down?";
141 } 145 }
142 146
147 PushMessagingApplicationId application_id =
148 PushMessagingApplicationId(origin, service_worker_registration_id);
149 DCHECK(application_id.IsValid());
150
143 if (profile_->GetPrefs()->GetInteger( 151 if (profile_->GetPrefs()->GetInteger(
144 prefs::kPushMessagingRegistrationCount) >= kMaxRegistrations) { 152 prefs::kPushMessagingRegistrationCount) >= kMaxRegistrations) {
145 RegisterEnd( 153 RegisterEnd(
146 app_id,
147 callback, 154 callback,
148 std::string(), 155 std::string(),
149 content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_LIMIT_REACHED); 156 content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_LIMIT_REACHED);
150 return; 157 return;
151 } 158 }
152 159
153 // If this is registering for the first time then the driver does not have 160 // If this is registering for the first time then the driver does not have
154 // this as an app handler and registration would fail. 161 // this as an app handler and registration would fail.
155 if (gcm_profile_service_->driver()->GetAppHandler(kAppIdPrefix) != this) 162 if (gcm_profile_service_->driver()->GetAppHandler(
156 gcm_profile_service_->driver()->AddAppHandler(kAppIdPrefix, this); 163 kPushMessagingApplicationIdPrefix) != this)
164 gcm_profile_service_->driver()->AddAppHandler(
165 kPushMessagingApplicationIdPrefix, this);
157 166
158 content::RenderFrameHost* render_frame_host = 167 content::RenderFrameHost* render_frame_host =
159 content::RenderFrameHost::FromID(renderer_id, render_frame_id); 168 content::RenderFrameHost::FromID(renderer_id, render_frame_id);
160 169
161 // The frame doesn't exist any more, or we received a bad frame id. 170 // The frame doesn't exist any more, or we received a bad frame id.
162 if (!render_frame_host) 171 if (!render_frame_host)
163 return; 172 return;
164 173
165 content::WebContents* web_contents = 174 content::WebContents* web_contents =
166 content::WebContents::FromRenderFrameHost(render_frame_host); 175 content::WebContents::FromRenderFrameHost(render_frame_host);
167 176
168 // The page doesn't exist any more or we got a bad render frame host. 177 // The page doesn't exist any more or we got a bad render frame host.
169 if (!web_contents) 178 if (!web_contents)
170 return; 179 return;
171 180
172 // TODO(miguelg) need to send this over IPC when bubble support is 181 // TODO(miguelg) need to send this over IPC when bubble support is
173 // implemented. 182 // implemented.
174 int bridge_id = -1; 183 int bridge_id = -1;
175 184
176 const PermissionRequestID id( 185 const PermissionRequestID id(
177 renderer_id, web_contents->GetRoutingID(), bridge_id, GURL()); 186 renderer_id, web_contents->GetRoutingID(), bridge_id, GURL());
178 187
179 GURL embedder = web_contents->GetLastCommittedURL(); 188 GURL embedder = web_contents->GetLastCommittedURL();
180 gcm::PushMessagingPermissionContext* permission_context = 189 gcm::PushMessagingPermissionContext* permission_context =
181 gcm::PushMessagingPermissionContextFactory::GetForProfile(profile_); 190 gcm::PushMessagingPermissionContextFactory::GetForProfile(profile_);
182 191
183 if (permission_context == NULL) { 192 if (permission_context == NULL) {
184 RegisterEnd( 193 RegisterEnd(
185 app_id,
186 callback, 194 callback,
187 std::string(), 195 std::string(),
188 content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_PERMISSION_DENIED); 196 content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_PERMISSION_DENIED);
189 return; 197 return;
190 } 198 }
191 199
192 permission_context->RequestPermission( 200 permission_context->RequestPermission(
193 web_contents, 201 web_contents,
194 id, 202 id,
195 embedder, 203 embedder,
196 user_gesture, 204 user_gesture,
197 base::Bind(&PushMessagingServiceImpl::DidRequestPermission, 205 base::Bind(&PushMessagingServiceImpl::DidRequestPermission,
198 weak_factory_.GetWeakPtr(), 206 weak_factory_.GetWeakPtr(),
207 application_id,
199 sender_id, 208 sender_id,
200 app_id,
201 callback)); 209 callback));
202 } 210 }
203 211
204 void PushMessagingServiceImpl::RegisterEnd( 212 void PushMessagingServiceImpl::RegisterEnd(
205 const std::string& app_id,
206 const content::PushMessagingService::RegisterCallback& callback, 213 const content::PushMessagingService::RegisterCallback& callback,
207 const std::string& registration_id, 214 const std::string& registration_id,
208 content::PushMessagingStatus status) { 215 content::PushMessagingStatus status) {
209 GURL endpoint = GURL("https://android.googleapis.com/gcm/send"); 216 GURL endpoint = GURL("https://android.googleapis.com/gcm/send");
210 callback.Run(endpoint, registration_id, status); 217 callback.Run(endpoint, registration_id, status);
211 if (status == content::PUSH_MESSAGING_STATUS_OK) { 218 if (status == content::PUSH_MESSAGING_STATUS_OK) {
212 // TODO(johnme): Make sure the pref doesn't get out of sync after crashes. 219 // TODO(johnme): Make sure the pref doesn't get out of sync after crashes.
213 int registration_count = profile_->GetPrefs()->GetInteger( 220 int registration_count = profile_->GetPrefs()->GetInteger(
214 prefs::kPushMessagingRegistrationCount); 221 prefs::kPushMessagingRegistrationCount);
215 profile_->GetPrefs()->SetInteger(prefs::kPushMessagingRegistrationCount, 222 profile_->GetPrefs()->SetInteger(prefs::kPushMessagingRegistrationCount,
216 registration_count + 1); 223 registration_count + 1);
217 } 224 }
218 } 225 }
219 226
220 void PushMessagingServiceImpl::DidRegister( 227 void PushMessagingServiceImpl::DidRegister(
221 const std::string& app_id,
222 const content::PushMessagingService::RegisterCallback& callback, 228 const content::PushMessagingService::RegisterCallback& callback,
223 const std::string& registration_id, 229 const std::string& registration_id,
224 GCMClient::Result result) { 230 GCMClient::Result result) {
225 content::PushMessagingStatus status = 231 content::PushMessagingStatus status =
226 result == GCMClient::SUCCESS 232 result == GCMClient::SUCCESS
227 ? content::PUSH_MESSAGING_STATUS_OK 233 ? content::PUSH_MESSAGING_STATUS_OK
228 : content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_SERVICE_ERROR; 234 : content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_SERVICE_ERROR;
229 RegisterEnd(app_id, callback, registration_id, status); 235 RegisterEnd(callback, registration_id, status);
230 } 236 }
231 237
232 void PushMessagingServiceImpl::DidRequestPermission( 238 void PushMessagingServiceImpl::DidRequestPermission(
239 const PushMessagingApplicationId& application_id,
233 const std::string& sender_id, 240 const std::string& sender_id,
234 const std::string& app_id,
235 const content::PushMessagingService::RegisterCallback& register_callback, 241 const content::PushMessagingService::RegisterCallback& register_callback,
236 bool allow) { 242 bool allow) {
237 if (!allow) { 243 if (!allow) {
238 RegisterEnd( 244 RegisterEnd(
239 app_id,
240 register_callback, 245 register_callback,
241 std::string(), 246 std::string(),
242 content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_PERMISSION_DENIED); 247 content::PUSH_MESSAGING_STATUS_REGISTRATION_FAILED_PERMISSION_DENIED);
243 return; 248 return;
244 } 249 }
245 250
246 // The GCMDriver could be NULL if GCMProfileService has been shut down. 251 // The GCMDriver could be NULL if GCMProfileService has been shut down.
247 if (!gcm_profile_service_->driver()) 252 if (!gcm_profile_service_->driver())
248 return; 253 return;
249 254
250 std::vector<std::string> sender_ids(1, sender_id); 255 std::vector<std::string> sender_ids(1, sender_id);
251 256
252 gcm_profile_service_->driver()->Register( 257 gcm_profile_service_->driver()->Register(
253 app_id, 258 application_id.ToString(),
254 sender_ids, 259 sender_ids,
255 base::Bind(&PushMessagingServiceImpl::DidRegister, 260 base::Bind(&PushMessagingServiceImpl::DidRegister,
256 weak_factory_.GetWeakPtr(), 261 weak_factory_.GetWeakPtr(),
257 app_id,
258 register_callback)); 262 register_callback));
259 } 263 }
260 264
261 // TODO(johnme): Unregister should decrement the pref, and call 265 // TODO(johnme): Unregister should decrement the pref, and call
262 // RemoveAppHandler if the count drops to zero. 266 // RemoveAppHandler if the count drops to zero.
263 267
264 } // namespace gcm 268 } // namespace gcm
OLDNEW
« no previous file with comments | « chrome/browser/services/gcm/push_messaging_service_impl.h ('k') | chrome/chrome_browser.gypi » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698